from pathlib import Path import pytest from django.urls import reverse from playwright.sync_api import expect from apps.accounts.models import TicketMagicLink, User from apps.customers.models import CustomerProfile from apps.tickets.models import TicketCategory from apps.tickets.services import create_ticket from tests.e2e.pages.auth import AuthenticationPage from tests.e2e.pages.magic_link import MagicLinkConfirmationPage from tests.e2e.pages.tickets import TicketConversationPage pytestmark = [pytest.mark.e2e, pytest.mark.django_db(transaction=True)] PASSWORD = "Magic-link-test-password-2026" MESSAGE = "شما با حساب دیگری وارد سامانه شده‌اید. برای مشاهده تیکت مرتبط با این لینک، از حساب فعلی خارج شوید. پس از خروج، تیکت به‌صورت خودکار باز می‌شود و نیازی به ورود مجدد ندارید." @pytest.fixture def browser_magic_case(): category = TicketCategory.objects.create(title="پشتیبانی لینک", slug="browser-magic") owner = User.objects.create_user(username="browser-link-owner", mobile="09123000101", account_type="CUSTOMER") other = User.objects.create_user(username="browser-link-other", mobile="09123000102", account_type="CUSTOMER", password=PASSWORD) CustomerProfile.objects.create(user=owner) CustomerProfile.objects.create(user=other) ticket = create_ticket(customer=owner, category=category, subject="درخواست مرتبط با لینک", body="محتوای تیکت مرتبط") token = TicketMagicLink.issue(ticket) return other, ticket, token @pytest.mark.parametrize("width", [320, 390, 1280]) def test_confirmed_logout_opens_ticket_with_readable_responsive_page(browser_page, live_server, browser_magic_case, width): other, ticket, token = browser_magic_case with browser_page() as page: page.set_viewport_size({"width": width, "height": 844 if width < 640 else 900}) AuthenticationPage(page, live_server.url).login_customer(other, PASSWORD) confirmation = MagicLinkConfirmationPage(page, live_server.url) confirmation.open(token) expect(page.locator("#confirmation-description")).to_have_text(MESSAGE) expect(page.get_by_text("محتوای تیکت مرتبط", exact=True)).to_have_count(0) confirmation.expect_readable_layout() confirmation.continue_button.focus() expect(confirmation.continue_button).to_be_focused() assert confirmation.continue_button.evaluate("node => getComputedStyle(node).outlineStyle") == "solid" artifact = Path("test-results/e2e") / f"magic-confirmation-{width}.png" artifact.parent.mkdir(parents=True, exist_ok=True) page.screenshot(path=str(artifact), full_page=True) confirmation.continue_to_ticket(ticket) TicketConversationPage(page, live_server.url).send_reply("پاسخ مرورگر پس از خروج") confirmation.goto(reverse("accounts:profile")) expect(page).to_have_url(confirmation.url(reverse("accounts:login")) + "?next=" + reverse("accounts:profile")) def test_cancel_returns_to_logged_in_account(browser_page, live_server, browser_magic_case): other, ticket, token = browser_magic_case with browser_page() as page: AuthenticationPage(page, live_server.url).login_customer(other, PASSWORD) confirmation = MagicLinkConfirmationPage(page, live_server.url) confirmation.open(token) confirmation.cancel() confirmation.goto(reverse("accounts:profile")) expect(page.get_by_role("heading", name="پروفایل من")).to_be_visible() expect(page.locator("main")).to_contain_text(other.mobile) def test_confirmation_form_works_without_its_javascript(browser_page, live_server, browser_magic_case): other, ticket, token = browser_magic_case with browser_page() as page: AuthenticationPage(page, live_server.url).login_customer(other, PASSWORD) page.route("**/magic-link-confirmation.js*", lambda route: route.abort()) confirmation = MagicLinkConfirmationPage(page, live_server.url) confirmation.open(token) confirmation.continue_to_ticket(ticket)