Portal Delete run (Super Admin), lab codes #3/#4, Z23 pointer #45, T1017 #46, payer note, login security-image wait
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a8af44e673
commit
fafa5285eb
21 files changed
+1509
-63
No files matched your search
@@ -0,0 +1,109 @@
|
||||
r"""
|
||||
auth/login.py `wait_after_username()` — what comes after the username's
|
||||
Next (live 2026-10-28 17:59: the security image page came late, the old
|
||||
one-look check missed it, and the bot clicked a password box that stayed
|
||||
disabled until it timed out).
|
||||
|
||||
It waits, up to its timeout, for whichever comes first: eCW's "VERIFY YOUR
|
||||
SECURITY IMAGE" page or a password box that is visible AND enabled. Neither
|
||||
→ a screenshot (with the DOM) and an error that says so.
|
||||
|
||||
python tests\test_login_username_step.py
|
||||
|
||||
Local headless chromium, `page.set_content()` only. No eCW, no login.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import time
|
||||
import pathlib
|
||||
import tempfile
|
||||
|
||||
ROOT = pathlib.Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(ROOT / "src"))
|
||||
|
||||
from ecw_bot import settings as cfg # noqa: E402
|
||||
from ecw_bot.auth import login # noqa: E402
|
||||
|
||||
CASES = []
|
||||
|
||||
|
||||
def case(fn):
|
||||
CASES.append(fn)
|
||||
return fn
|
||||
|
||||
|
||||
# The password box is on the page from the start, disabled — the shape
|
||||
# seen live; eCW enables it once the username step is done.
|
||||
_PAGE = """
|
||||
<input id="doctorID" value="someone">
|
||||
<input disabled type="password" id="passwordField">
|
||||
<div id="img" style="display:none">VERIFY YOUR SECURITY IMAGE</div>
|
||||
<script>%s</script>
|
||||
"""
|
||||
|
||||
|
||||
@case
|
||||
def a_late_security_image_page_is_seen(page):
|
||||
page.set_content(_PAGE % "setTimeout(() => document.getElementById("
|
||||
"'img').style.display = '', 3000);")
|
||||
assert login.wait_after_username(page, 10_000) == "image"
|
||||
|
||||
|
||||
@case
|
||||
def a_password_box_enabled_late_is_waited_for(page):
|
||||
page.set_content(_PAGE % "setTimeout(() => document.getElementById("
|
||||
"'passwordField').disabled = false, 2500);")
|
||||
t0 = time.monotonic()
|
||||
assert login.wait_after_username(page, 10_000) == "password"
|
||||
assert time.monotonic() - t0 >= 2, "returned before it was enabled"
|
||||
|
||||
|
||||
@case
|
||||
def after_the_image_only_the_password_box_counts(page):
|
||||
page.set_content(_PAGE % "document.getElementById('img').style.display"
|
||||
" = ''; setTimeout(() => document.getElementById("
|
||||
"'passwordField').disabled = false, 1500);")
|
||||
assert login.wait_after_username(page, 10_000, image=False) == "password"
|
||||
|
||||
|
||||
@case
|
||||
def a_password_box_that_stays_disabled_is_an_error_with_a_screenshot(page):
|
||||
page.set_content(_PAGE % "")
|
||||
try:
|
||||
login.wait_after_username(page, 2_000)
|
||||
except RuntimeError as exc:
|
||||
assert "password box stayed disabled" in str(exc), exc
|
||||
else:
|
||||
raise AssertionError("no error for a box that never enabled")
|
||||
shots = list(pathlib.Path(cfg.SCREENSHOTS).glob("*_username_step_disabled.*"))
|
||||
assert {p.suffix for p in shots} == {".png", ".html"}, shots
|
||||
|
||||
|
||||
def main() -> int:
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
failures = 0
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
cfg.SCREENSHOTS = pathlib.Path(tmp) # never the real folder
|
||||
with sync_playwright() as pw:
|
||||
browser = pw.chromium.launch(headless=True)
|
||||
page = browser.new_page()
|
||||
for fn in CASES:
|
||||
name = fn.__name__.replace("_", " ")
|
||||
try:
|
||||
fn(page)
|
||||
print(f" ok {name}")
|
||||
except AssertionError as exc:
|
||||
print(f" FAIL {name}: {exc}")
|
||||
failures += 1
|
||||
except Exception as exc:
|
||||
print(f" ERROR {name}: {type(exc).__name__}: {exc}")
|
||||
failures += 1
|
||||
browser.close()
|
||||
|
||||
print(f"\n{len(CASES) - failures}/{len(CASES)} passed")
|
||||
return 1 if failures else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user