r"""
auth/password_entry.py — the eCW password is TYPED key by key, never set
with fill() (2026-10-20: a filled password left Log In doing nothing).
python tests\test_password_entry.py
"""
import re
import sys
import inspect
import pathlib
ROOT = pathlib.Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "src"))
from ecw_bot.auth import password_entry # noqa: E402
LOGIN_PAGE = """
"""
FAKE = "Fake#Pass 123!" # a test value, not a credential
CASES = []
def case(fn):
CASES.append(fn)
return fn
@case
def it_types_one_key_event_per_character(page):
page.set_content(LOGIN_PAGE)
password_entry.type_password(page, FAKE)
assert page.input_value("#passwordField") == FAKE
# At least one keydown per character (Shift may add its own).
assert page.evaluate("window.keys") >= len(FAKE)
@case
def whatever_was_in_the_field_is_replaced(page):
page.set_content(LOGIN_PAGE)
password_entry.type_password(page, "abc")
password_entry.type_password(page, "xyz")
assert page.input_value("#passwordField") == "xyz"
@case
def login_and_captcha_never_fill_the_password_field(page):
for path in ("src/ecw_bot/auth/login.py", "src/ecw_bot/auth/captcha.py"):
text = (ROOT / path).read_text(encoding="utf-8")
assert not re.search(r"\.fill\(\s*sel\.SEL_PASSWORD", text), path
assert "type_password(" in text, path
def main() -> int:
from playwright.sync_api import sync_playwright
failures = 0
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())