Initial import: eCW Charge Validation bot and results Portal
Snapshot of the working project as of 2026-10-23 (local 2d4d4fc), one commit with no earlier history: the tracked files were de-identified first (synthetic claim ids and patient data only; see Context.md section 7). Credentials, run logs, screenshots, claim reports and client workbooks are gitignored and not included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
ba15a574ab
205 files changed
+56772
No files matched your search
@@ -0,0 +1,88 @@
|
||||
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 = """
|
||||
<input id="passwordField" type="password" value="left over">
|
||||
<input id="Login" type="button" value="Log In">
|
||||
<script>
|
||||
window.keys = 0;
|
||||
document.getElementById('passwordField')
|
||||
.addEventListener('keydown', () => window.keys++);
|
||||
</script>
|
||||
"""
|
||||
|
||||
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())
|
||||
Reference in new issue
Block a user