from pathlib import Path import pytest ROOT = Path(__file__).parents[2] @pytest.mark.parametrize("viewport", [(320, 568), (390, 844)]) def test_mobile_received_review_feedback_opens_matching_change(viewport): playwright = pytest.importorskip("playwright.sync_api") html = (ROOT / "frontend" / "index.html").read_text() detail = { "state": "open", "draft": False, "mergeable": True, "merged": False, "ci_state": "success", "head_sha": "current-head", "reviewers": [{ "login": "sam", "status": "outdated", "head_sha": "old-head-123456", "blocking": True, "summary": "Please handle the narrow empty state before merging.", "comments": [{ "path": "src/a/very/long/mobile/path/review_target.py", "body": "Return before parsing when the payload is empty.", "line": 12, }], }], "files": [{ "filename": "src/a/very/long/mobile/path/review_target.py", "status": "modified", "additions": 2, "deletions": 1, "diff_available": True, "diff_lines": ["@@ -10,2 +10,3 @@", "-parse(payload)", "+if not payload: return", "+parse(payload)"], }], } with playwright.sync_playwright() as runtime: try: browser = runtime.chromium.launch(headless=True) except Exception as error: pytest.skip(f"Chromium is not installed: {error}") page = browser.new_page(viewport={"width": viewport[0], "height": viewport[1]}) page.set_content(html, wait_until="domcontentloaded") page.add_style_tag(path=ROOT / "frontend" / "dashboard.css") page.add_script_tag(path=ROOT / "frontend" / "pull-sheet.js") page.evaluate( """detail => { document.querySelector('#pull-sheet').classList.add('open'); document.querySelector('#pull-review').open = true; createPullSheet.review(detail, null, document); document.querySelector('#pull-files').innerHTML = detail.files.map((file, index) => createPullSheet.renderFile(file, index, false, value => String(value) .replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>')) ).join(''); }""", detail, ) page.locator(".pull-review-feedback summary").click() jump = page.locator('[data-review-feedback-file]') jump.click() metrics = page.evaluate( """() => { const jump = document.querySelector('[data-review-feedback-file]'); const toggle = document.querySelector('.pull-file-toggle'); const panel = document.getElementById(toggle.getAttribute('aria-controls')); return { scrollWidth: document.documentElement.scrollWidth, clientWidth: document.documentElement.clientWidth, jumpHeight: jump.getBoundingClientRect().height, expanded: toggle.getAttribute('aria-expanded'), panelHidden: panel.hidden, focused: document.activeElement === toggle, reviewedHead: document.querySelector('.pull-review-feedback').textContent, updatedReviewVisible: !document.querySelector('#request-updated-pull-review').hidden, }; }""" ) browser.close() assert metrics["scrollWidth"] <= metrics["clientWidth"] assert metrics["jumpHeight"] >= 44 assert metrics["expanded"] == "true" assert metrics["panelHidden"] is False assert metrics["focused"] is True assert "Reviewed head old-head" in metrics["reviewedHead"] assert metrics["updatedReviewVisible"] is True