99 lines
4.1 KiB
Python
99 lines
4.1 KiB
Python
|
|
"""Drive the homepage BookingWizard in a mobile viewport and check the success modal appears."""
|
||
|
|
from playwright.sync_api import sync_playwright
|
||
|
|
import sys, io
|
||
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
||
|
|
|
||
|
|
BASE = "http://127.0.0.1:5180"
|
||
|
|
|
||
|
|
def run():
|
||
|
|
with sync_playwright() as p:
|
||
|
|
browser = p.chromium.launch()
|
||
|
|
ctx = browser.new_context(
|
||
|
|
viewport={"width": 390, "height": 844},
|
||
|
|
user_agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 Mobile/15E148 Safari/604.1",
|
||
|
|
is_mobile=True,
|
||
|
|
has_touch=True,
|
||
|
|
device_scale_factor=3,
|
||
|
|
)
|
||
|
|
page = ctx.new_page()
|
||
|
|
console_logs = []
|
||
|
|
page.on("console", lambda msg: console_logs.append(f"[{msg.type}] {msg.text}"))
|
||
|
|
page.on("pageerror", lambda err: console_logs.append(f"[pageerror] {err}"))
|
||
|
|
|
||
|
|
def handle_submit(route):
|
||
|
|
print(f" intercepted /api/submit -> returning 200")
|
||
|
|
route.fulfill(status=200, content_type="application/json", body='{"ok":true}')
|
||
|
|
page.route("**/api/submit", handle_submit)
|
||
|
|
|
||
|
|
print("[1] Loading homepage…")
|
||
|
|
page.goto(BASE + "/#newlead", wait_until="networkidle", timeout=30000)
|
||
|
|
page.locator("#newlead").scroll_into_view_if_needed()
|
||
|
|
page.wait_for_timeout(400)
|
||
|
|
|
||
|
|
print("[2] Step 1 — dog details")
|
||
|
|
# Pet name (avoid honeypot which uses autocomplete="new-password")
|
||
|
|
page.locator('.wiz-form input[placeholder*="Teddy"]').fill("Rex")
|
||
|
|
# Pick first service
|
||
|
|
page.locator('.wiz-service').first.click()
|
||
|
|
# Message (textarea)
|
||
|
|
page.locator('.wiz-form textarea').first.fill("Friendly dog, two years old, recall fine.")
|
||
|
|
|
||
|
|
# Continue
|
||
|
|
cont = page.get_by_role("button", name="Continue")
|
||
|
|
print(f" Continue button visible: {cont.is_visible()}")
|
||
|
|
cont.click()
|
||
|
|
page.wait_for_timeout(1200)
|
||
|
|
page.locator("#newlead").screenshot(path="scripts/mobile-step2.png")
|
||
|
|
errs = page.locator('.wiz-error').all()
|
||
|
|
print(f" visible errors after Continue: {len(errs)}")
|
||
|
|
for e in errs:
|
||
|
|
try: print(f" -> {e.inner_text()}")
|
||
|
|
except: pass
|
||
|
|
print(f" inputs after Continue: {page.locator('.wiz-form input').count()}")
|
||
|
|
for inp in page.locator('.wiz-form input').all():
|
||
|
|
print(f" autocomplete={inp.get_attribute('autocomplete')!r} type={inp.get_attribute('type')!r} visible={inp.is_visible()}")
|
||
|
|
|
||
|
|
print("[3] Step 2 — owner details")
|
||
|
|
page.locator('.wiz-form input[autocomplete="name"]').fill("Test User")
|
||
|
|
page.locator('.wiz-form input[type="email"]').fill("test@example.com")
|
||
|
|
page.locator('.wiz-form input[type="tel"]').fill("0211234567")
|
||
|
|
page.locator('.wiz-form input[autocomplete="address-level2"]').fill("Mt Eden")
|
||
|
|
|
||
|
|
print("[4] Submit")
|
||
|
|
page.get_by_role("button", name="Send my details").click()
|
||
|
|
|
||
|
|
print("[5] Waiting for success modal…")
|
||
|
|
try:
|
||
|
|
page.wait_for_selector('[role="dialog"]', timeout=8000, state="attached")
|
||
|
|
print(" PASS: dialog attached")
|
||
|
|
except Exception:
|
||
|
|
print(" FAIL: dialog never attached")
|
||
|
|
return 1
|
||
|
|
|
||
|
|
# Snapshot immediately
|
||
|
|
page.screenshot(path="scripts/mobile-modal-immediate.png", full_page=False)
|
||
|
|
c0 = page.locator('canvas').count()
|
||
|
|
d0 = page.locator('[role="dialog"]').count()
|
||
|
|
print(f" t=0ms: dialogs={d0} canvases={c0}")
|
||
|
|
|
||
|
|
for delay in (200, 500, 1000, 2000):
|
||
|
|
page.wait_for_timeout(delay)
|
||
|
|
d = page.locator('[role="dialog"]').count()
|
||
|
|
c = page.locator('canvas').count()
|
||
|
|
print(f" after +{delay}ms: dialogs={d} canvases={c}")
|
||
|
|
if d == 0:
|
||
|
|
print(" Modal vanished!")
|
||
|
|
page.screenshot(path=f"scripts/mobile-vanished-{delay}.png", full_page=False)
|
||
|
|
break
|
||
|
|
|
||
|
|
page.screenshot(path="scripts/mobile-modal-final.png", full_page=False)
|
||
|
|
|
||
|
|
print("\nConsole tail:")
|
||
|
|
for line in console_logs[-12:]:
|
||
|
|
print(f" {line}")
|
||
|
|
|
||
|
|
browser.close()
|
||
|
|
return 0
|
||
|
|
|
||
|
|
sys.exit(run())
|