phase: 128_sync_label_mobile
Everything verified and 100% green. The earlier rejection was a report-format issue, not a test failure — all work is in the working tree. Final report: **Phase 128 final pass — verified (all 3 tasks complete; no code defects found)** - Verified: `#sync-label` parts markup, `setSyncLabel` writer, part builders (A4 untruncated title/aria-live), flex-row CSS + mobile media query — all match design 1:1. - `uv run pytest --cov=app --cov-report=term`: 3024 passed; TOTAL coverage **99%** (>90% gate). - `uv run pytest tests/e2e/test_sync_label_mobile.py -v --no-cov`: 4 passed (119s, isolated). - `uv run ruff check .`: clean; `uv run pyright`: 0 errors. - Criteria: (1) mobile 390×844 label in-viewport, count visible in import+summaries — ✅ E2E; (2) desktop strings/cap/title unchanged — ✅ E2E+unit; (3) E2E isolated green — ✅; (4) full suite green — ✅. - Docs: README.md fixed 5 pre-existing gaps (PDF phase-126 section + `pdf` token, hidden-folders toggle ph.105, document dates ph.106, private git-source masked tokens ph.121, doc-draft Discard ph.115); AGENTS.md verified consistent — no changes. - Notable: double-`-q` (addopts `-q` + CLI `-q`) suppresses pytest's summary line — standard `-qq` behavior, not a bug; exit codes confirm green. - Next pending phase: `129_sync_chunk_progress`.
This commit is contained in:
@@ -604,9 +604,23 @@ def test_upload_toast_then_navigate_away(
|
||||
expect(page.locator("#sync-error-banner")).to_be_hidden()
|
||||
|
||||
# UI layer: the label gains the live file at the page's 2 s poll
|
||||
# tick ("Syncing… <source/relative/path> (n/m)").
|
||||
# tick — the file rides the MAIN part, "(n/m)" the pinned COUNT
|
||||
# span (phase 128: the space between them is the CSS gap, so the
|
||||
# rendered concatenation carries none — the FULL string with the
|
||||
# space rides the button title, A4).
|
||||
expect(page.locator("#sync-label")).to_have_text(
|
||||
re.compile(rf"Syncing… {re.escape(UPLOAD_NAME)}/.+\.md \(\d+/{N_FILES}\)"),
|
||||
re.compile(rf"Syncing… {re.escape(UPLOAD_NAME)}/.+\.md\(\d+/{N_FILES}\)"),
|
||||
timeout=SETTLE_TIMEOUT_MS,
|
||||
)
|
||||
# Phase 128: the "(n/m)" is NEVER clipped — it sits in its own
|
||||
# visible count span, and the button title carries the full
|
||||
# untruncated string (main + " " + count, A4).
|
||||
expect(page.locator("#sync-label .sync-label-count")).to_be_visible(
|
||||
timeout=SETTLE_TIMEOUT_MS
|
||||
)
|
||||
expect(btn).to_have_attribute(
|
||||
"title",
|
||||
re.compile(rf"^Syncing… {re.escape(UPLOAD_NAME)}/.+\.md \(\d+/{N_FILES}\)$"),
|
||||
timeout=SETTLE_TIMEOUT_MS,
|
||||
)
|
||||
|
||||
@@ -774,9 +788,23 @@ def test_sync_live_file_label(
|
||||
expect(page.locator("#sync-error-banner")).to_be_hidden()
|
||||
|
||||
# UI layer: the label gains the live file at the page's 2 s poll
|
||||
# tick ("Syncing… <source/relative/path> (n/m)").
|
||||
# tick — the file rides the MAIN part, "(n/m)" the pinned COUNT
|
||||
# span (phase 128: the space between them is the CSS gap, so the
|
||||
# rendered concatenation carries none — the FULL string with the
|
||||
# space rides the button title, A4).
|
||||
expect(page.locator("#sync-label")).to_have_text(
|
||||
re.compile(rf"Syncing… {re.escape(SYNC_SOURCE_DIR)}/.+\.md \(\d+/{N_FILES}\)"),
|
||||
re.compile(rf"Syncing… {re.escape(SYNC_SOURCE_DIR)}/.+\.md\(\d+/{N_FILES}\)"),
|
||||
timeout=SETTLE_TIMEOUT_MS,
|
||||
)
|
||||
# Phase 128: the "(n/m)" is NEVER clipped — it sits in its own
|
||||
# visible count span, and the button title carries the full
|
||||
# untruncated string (main + " " + count, A4).
|
||||
expect(page.locator("#sync-label .sync-label-count")).to_be_visible(
|
||||
timeout=SETTLE_TIMEOUT_MS
|
||||
)
|
||||
expect(btn).to_have_attribute(
|
||||
"title",
|
||||
re.compile(rf"^Syncing… {re.escape(SYNC_SOURCE_DIR)}/.+\.md \(\d+/{N_FILES}\)$"),
|
||||
timeout=SETTLE_TIMEOUT_MS,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user