auto-added

This commit is contained in:
2026-08-30 18:34:41 +03:00
parent c5e0213c74
commit e2022c2dae
4 changed files with 545 additions and 31 deletions
+111
View File
@@ -0,0 +1,111 @@
import pytest
import allure
from playwright.sync_api import Page, expect
@pytest.mark.login_page
class TestLoginPageAccessibility:
"""Anonymized accessibility checks from an enterprise Playwright project."""
def _check_accessibility(self, login_page_devices, accessibility_checker):
login_page_devices.wait_for_load_state("networkidle")
accessibility_checker.check(login_page_devices)
@pytest.mark.axe
def test_accessibility_login_page(
self,
login_page_devices: Page,
accessibility_checker,
):
with allure.step("Check login page accessibility"):
self._check_accessibility(login_page_devices, accessibility_checker)
@pytest.mark.axe
def test_accessibility_password_recovery(
self,
login_page_devices: Page,
login_page_object,
accessibility_checker,
):
with allure.step("Open password recovery form"):
login_page_object.forgot_password_link.click()
with allure.step("Check password recovery accessibility"):
self._check_accessibility(login_page_devices, accessibility_checker)
@pytest.mark.axe
def test_accessibility_security_questions(
self,
login_page_devices: Page,
login_page_object,
security_questions_user,
accessibility_checker,
):
with allure.step("Open password recovery form"):
login_page_object.forgot_password_link.click()
with allure.step("Fill login and email"):
login_page_object.login_field.fill(security_questions_user.login)
login_page_object.email_field.fill(security_questions_user.email)
with allure.step("Submit password recovery request"):
login_page_object.next_btn.click()
with allure.step("Check security questions accessibility"):
self._check_accessibility(login_page_devices, accessibility_checker)
@pytest.mark.axe
@pytest.mark.parametrize(
"username,password,expected_error",
[
pytest.param(
"valid_user",
"invalid_password",
"Unable to logon with specified login and password",
id="invalid-password",
),
pytest.param(
"",
"valid_password",
"Form validation failed",
id="empty-username",
),
],
)
def test_accessibility_login_error_state(
self,
login_page_devices: Page,
login_page_object,
accessibility_checker,
username: str,
password: str,
expected_error: str,
):
with allure.step("Fill login and password"):
login_page_object.login_field.fill(username)
login_page_object.password_field.fill(password)
with allure.step("Submit login form"):
login_page_object.logon_btn.click()
with allure.step("Check error message"):
expect(login_page_devices.get_by_text(expected_error)).to_contain_text(
expected_error
)
with allure.step("Check error state accessibility"):
self._check_accessibility(login_page_devices, accessibility_checker)
@pytest.mark.axe
def test_accessibility_dark_theme(
self,
login_page_devices: Page,
accessibility_checker,
):
with allure.step("Switch to dark theme"):
login_page_devices.locator("html").evaluate(
"element => element.className = 'dark'"
)
with allure.step("Check dark theme accessibility"):
self._check_accessibility(login_page_devices, accessibility_checker)
+310
View File
@@ -0,0 +1,310 @@
import re
import allure
import pytest
from playwright.sync_api import Page, expect
@pytest.mark.login_page
class TestLoginPage:
"""Anonymized E2E examples from an enterprise Playwright project."""
@pytest.mark.e2e
@pytest.mark.parametrize(
"username,password,expected_error",
[
pytest.param(
"valid_user",
"invalid_password",
"Unable to logon with specified login and password",
id="invalid-password",
),
pytest.param(
"unknown_user",
"valid_password",
"Unable to logon with specified login and password",
id="unknown-user",
),
pytest.param(
"",
"valid_password",
"Form validation failed",
id="empty-username",
),
pytest.param(
"valid_user",
"",
"Form validation failed",
id="empty-password",
),
pytest.param(
r"!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:\"|~ZXCVBNM<>?±§ ",
r"!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:\"|~ZXCVBNM<>?±§ ",
"Unable to logon with specified login and password",
id="special-characters",
),
pytest.param(
"qwertyuiopasdfghjklzxcvbnm" * 2,
"qwertyuiopasdfghjklzxcvbnm" * 2,
"Form validation failed",
id="overlong-input",
),
pytest.param(
"non_latin_user",
"non_latin_password",
"Form validation failed",
id="non-latin-input",
),
],
)
def test_login_negative(
self,
login_page: Page,
login_page_object,
username: str,
password: str,
expected_error: str,
):
with allure.step("Fill login and password"):
login_page_object.login_field.fill(username)
login_page_object.password_field.fill(password)
with allure.step("Click Logon button"):
login_page_object.logon_btn.click()
with allure.step("Check error message"):
expect(login_page.get_by_text(expected_error)).to_contain_text(expected_error)
@pytest.mark.e2e
def test_login_positive(self, login_page: Page, login_page_object, test_user):
with allure.step("Fill valid credentials"):
login_page_object.login_field.fill(test_user.login)
login_page_object.password_field.fill(test_user.password)
with allure.step("Click Logon button"):
login_page_object.logon_btn.click()
with allure.step("Check successful login"):
expect(login_page).not_to_have_url(login_page.url)
@pytest.mark.e2e
def test_password_reset_positive(
self,
login_page: Page,
login_page_object,
password_reset_user,
mail_checker,
):
with allure.step("Open password reset form"):
login_page_object.forgot_password_link.click()
with allure.step("Close password reset form"):
login_page_object.close_btn.click()
expect(login_page_object.reset_pass_txt).to_be_hidden()
with allure.step("Reopen password reset form"):
login_page_object.forgot_password_link.click()
with allure.step("Fill login and email"):
login_page_object.login_field.fill(password_reset_user.login)
login_page_object.email_field.fill(password_reset_user.email)
with allure.step("Submit password reset request"):
login_page_object.next_btn.click()
with allure.step("Check reset email"):
mail = mail_checker.wait_for_email(positive=True, timeout=60)
print("Received email:", mail["subject"])
with allure.step("Check confirmation message"):
expect(login_page).to_contain_text(
"Password reset confirmation message"
)
@pytest.mark.e2e
@pytest.mark.parametrize(
"login,email,expected_result",
[
pytest.param("test_user", " ", "Form validation failed", id="empty-email"),
pytest.param("test_user", "@", "Form validation failed", id="invalid-email-1"),
pytest.param("test_user", "test@", "Form validation failed", id="invalid-email-2"),
pytest.param(
"test_user",
"test@test.",
"Form validation failed",
id="invalid-email-3",
),
pytest.param(
"test_user",
".test@test.com",
"Form validation failed",
id="invalid-email-4",
),
pytest.param(
"test_user",
"te..st@test.com",
"Form validation failed",
id="invalid-email-5",
),
pytest.param(
"test_user",
"non_latin@test.com",
"Form validation failed",
id="non-latin-email",
),
pytest.param(
"test_user",
"test@test.com",
"Reset password request was accepted",
id="unknown-email-for-valid-user",
),
pytest.param(
"unknown_user",
"test@test.com",
"Reset password request was accepted",
id="unknown-user",
),
pytest.param(
"",
"test@test.com",
"Form validation failed",
id="empty-login",
),
pytest.param(
"test_user",
"test@test",
"Reset password request was accepted",
id="email-without-tld",
),
pytest.param(
"test_user",
"!@test",
"Reset password request was accepted",
id="non-standard-email-format",
),
],
)
def test_password_reset_negative(
self,
login_page: Page,
login_page_object,
mail_checker,
login: str,
email: str,
expected_result: str,
):
with allure.step("Open password reset form"):
login_page_object.forgot_password_link.click()
with allure.step("Fill login and email"):
login_page_object.login_field.fill(login)
login_page_object.email_field.fill(email)
if expected_result == "Form validation failed":
with allure.step("Verify submit button is disabled"):
expect(login_page_object.next_btn).to_be_disabled()
else:
with allure.step("Submit password reset request"):
login_page_object.next_btn.click()
with allure.step("Check application response"):
expect(login_page).to_contain_text(expected_result)
with allure.step("Check that no reset email is sent"):
mail_checker.wait_for_email(positive=False, timeout=20)
@pytest.mark.e2e
def test_password_reset_security_questions_positive(
self,
login_page: Page,
login_page_object,
security_questions_user,
mail_checker,
):
with allure.step("Open password reset form"):
login_page_object.forgot_password_link.click()
with allure.step("Fill login and email"):
login_page_object.login_field.fill(security_questions_user.login)
login_page_object.email_field.fill(security_questions_user.email)
with allure.step("Submit password reset request"):
login_page_object.next_btn.click()
answers = []
expected_questions = {
"question_type_a": "answer_a",
"question_type_b": "answer_b",
"question_type_c": "answer_c",
"question_type_d": "answer_d",
}
with allure.step("Answer security questions"):
for index in range(1, 5):
question_text = login_page.get_by_text(
re.compile(fr"Question {index}")
).inner_text()
current_answer = None
question_lower = question_text.lower()
for question_type, answer in expected_questions.items():
if question_type in question_lower:
current_answer = answer
break
assert current_answer is not None, (
f"Unknown security question: {question_text}"
)
answers.append(current_answer)
assert len(answers) == len(set(answers)), (
f"Duplicate security question detected: {question_text}"
)
login_page_object.answer_field.fill(current_answer)
login_page_object.next_btn.nth(1).click()
with allure.step("Check password reset email"):
mail = mail_checker.wait_for_email(positive=True, timeout=60)
print("Received email:", mail["subject"])
with allure.step("Check successful password reset"):
expect(login_page).to_contain_text("Password reset completed")
@pytest.mark.e2e
def test_password_reset_security_questions_negative(
self,
login_page: Page,
login_page_object,
security_questions_user,
):
with allure.step("Open password reset form"):
login_page_object.forgot_password_link.click()
with allure.step("Fill login and email"):
login_page_object.login_field.fill(security_questions_user.login)
login_page_object.email_field.fill(security_questions_user.email)
with allure.step("Submit password reset request"):
login_page_object.next_btn.click()
with allure.step("Submit invalid answers"):
for _ in range(3):
login_page_object.answer_field.fill("invalid_answer")
login_page_object.next_btn.nth(1).click()
expect(login_page).to_contain_text(
"Incorrect answer. Try again"
)
login_page_object.ok_btn.click()
with allure.step("Check cooldown timer"):
expect(login_page_object.sixty_btn).to_be_disabled()
expect(login_page_object.sixty_btn).to_contain_text(re.compile(r"\d+"))
with allure.step("Wait for cooldown to finish"):
expect(login_page_object.next_btn.nth(1)).to_be_enabled(timeout=61_000)
expect(login_page_object.next_btn.nth(1)).not_to_contain_text(
re.compile(r"\d+")
)
+71
View File
@@ -0,0 +1,71 @@
Playwright E2E Testing — Anonymized Case Study
This is an anonymized excerpt from an enterprise E2E automation project.
The original project is proprietary and cannot be published.
The code has been sanitized to remove company-specific data, credentials, URLs and internal implementation details.
Stack
* Python
* pytest
* Playwright
* Allure
* Axe / axe-core
Covered scenarios
Authentication
* valid credentials
* invalid username
* invalid password
* empty fields
* invalid characters
* boundary/long input
* error state validation
Password recovery
* valid login/email
* invalid email
* unknown user
* form validation
* email notification
* security questions
* cooldown/retry behavior
Accessibility Testing
Accessibility checks were automated using Axe / axe-core as part of the E2E test suite.
Covered UI states include:
* login page
* password recovery form
* security questions
* validation/error states
* dark theme
The accessibility checks are executed against different application states rather than only the initial page, helping detect accessibility regressions introduced by dynamic UI changes.
Security questions
* unique questions validation
* valid answers
* invalid answers
* duplicate question detection
* retry/cooldown timer
Testing approach
* Page Object Model
* parametrized tests
* positive/negative testing
* UI validation
* accessibility testing with Axe
* asynchronous email verification
* business-rule validation
* explicit assertions
* dynamic UI state validation
* E2E validation across multiple application components