phase: 101_tokens_page_overhaul
All gates verified green — no defects found, nothing to fix. Final report:
## Phase 101 — final verification pass (all tasks already complete; verified, not re-implemented)
**Verified against the working tree** (task files 01–04 present in `complete/`):
- Active/revoked table split (Status column gone, section hidden while 0 revoked, per-table search with query state surviving re-renders) in `frontend/index.html` + `tokens.js`
- `generateToken()` refuses blank/whitespace names (`Give the token a name first.`, no request); `|| "token"` fallback deleted
- Atomic rotation: `regenerate_token` service + `POST /api/tokens/{id}/regenerate` (201 new-plaintext-once / 404 / 409 / router-wide 403) + `TokenListItem.revoked_at` (D5)
- Regenerate two-step confirm UI + CSS (`.token-regenerate`, neutral hover, no new hue); A4 pins intact
**Test / lint / coverage results:**
- `uv run pytest` → **2065 passed**
- `uv run pytest --cov=app --cov-report=term-missing` → **TOTAL 99%** (>90% ✓)
- `uv run ruff check . && uv run pyright` → clean (0 errors)
- `uv run pytest tests/e2e/test_tokens_page.py -v --no-cov` → **4 passed** (isolation, DB up)
- Regression, each in isolation: `test_api_tokens.py` **9 passed**, `test_admin_auth.py` **6 passed**, `test_shared_header.py` **6 passed**, `test_theme_semantic_completion.py` **8 passed** (its revoked-pill pin was correctly re-scoped to the revoked table in this phase)
**Completion criteria:** 1 ✓ split+search (E2E 1–2) · 2 ✓ required name (E2E 3 + source pin) · 3 ✓ rotation end-to-end, old token refused at gate (E2E 4 + API 404/409 pinned) · 4 ✓ A4 holds (list carries no plaintext/hashes) · 5 ✓ suite/coverage/lint green · 6 ✓ E2E + regressions green in isolation · 7 commit left to the harness per executor rules (all changes uncommitted in the working tree)
**Deviations:** none. Next pending phase: `98_sync_summary_visibility`.
This commit is contained in:
@@ -60,9 +60,12 @@ computed-style assertion):
|
||||
out-of-generation saved chat (the phase-53 seed pattern) renders
|
||||
the "Stale" pill in History — gray err-ink on gray err-bg with the
|
||||
gray err-line border, text intact.
|
||||
5. ``test_revoked_pill_gray_labeled`` — screenshot 6: a token
|
||||
generated + revoked THROUGH the Tokens UI renders the "Revoked"
|
||||
pill — the same gray err-family computed colors, text intact.
|
||||
5. ``test_revoked_table_state_labeled`` — screenshot 6: a token
|
||||
generated + revoked THROUGH the Tokens UI lands in the SEPARATE
|
||||
revoked table (phase 101 D1 re-scoped this pin: the "Revoked"
|
||||
pill is gone — the table's position IS the status) with its
|
||||
Revoked date cell, text intact (B5: text + position, never color
|
||||
alone).
|
||||
6. ``test_local_badge_gray_labeled`` — screenshot 3: a registered
|
||||
local-directory source renders the "Local" badge on Git sources —
|
||||
gray ok-ink on gray ok-bg, text intact.
|
||||
@@ -695,12 +698,14 @@ def test_stale_pill_gray_labeled(page: Page, app_url: str, db_ready: None) -> No
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 5. Tokens: the "Revoked" pill (screenshot 6) — gray err family, text
|
||||
# intact (generated + revoked THROUGH the UI two-step)
|
||||
# 5. Tokens: the revoked-table state (screenshot 6) — phase 101 D1
|
||||
# replaced the "Revoked" pill: the row's very presence in the
|
||||
# revoked table below + its Revoked date cell (text, never color
|
||||
# alone — B5; generated + revoked THROUGH the UI two-step)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_revoked_pill_gray_labeled(page: Page, app_url: str, db_ready: None) -> None:
|
||||
def test_revoked_table_state_labeled(page: Page, app_url: str, db_ready: None) -> None:
|
||||
page.set_default_timeout(30_000)
|
||||
login(page, app_url, next="/")
|
||||
_seed_theme(app_url, _cookies(page))
|
||||
@@ -714,7 +719,7 @@ def test_revoked_pill_gray_labeled(page: Page, app_url: str, db_ready: None) ->
|
||||
page.click("#token-generate")
|
||||
row = page.locator("#tokens-tbody tr", has_text="e2e-theme93")
|
||||
expect(row).to_have_count(1, timeout=15_000)
|
||||
expect(row.locator(".stale-pill")).to_have_count(0) # Active: the em-dash
|
||||
expect(row.locator(".stale-pill")).to_have_count(0) # Phase 101: no status column
|
||||
|
||||
# Revoke through the UI two-step (Revoke → Yes — the inline
|
||||
# confirm, no native dialog).
|
||||
@@ -722,17 +727,16 @@ def test_revoked_pill_gray_labeled(page: Page, app_url: str, db_ready: None) ->
|
||||
expect(row.locator(".history-confirm-yes")).to_be_visible()
|
||||
row.locator(".history-confirm-yes").click()
|
||||
|
||||
# Screenshot 6: the red "Revoked" pill — now gray err-ink on gray
|
||||
# err-bg with the gray err-line border, text intact.
|
||||
revoked = page.locator("#tokens-tbody tr", has_text="e2e-theme93")
|
||||
pill = revoked.locator(".stale-pill")
|
||||
expect(pill).to_have_count(1)
|
||||
expect(pill).to_have_text("Revoked", timeout=15_000)
|
||||
_assert_gray(pill, "color", GRAY["err_ink"], label="revoked pill text")
|
||||
_assert_gray(pill, "backgroundColor", GRAY["err_bg"], label="revoked pill bg")
|
||||
_assert_gray(
|
||||
pill, "borderTopColor", GRAY["err_line"], label="revoked pill border"
|
||||
)
|
||||
# Screenshot 6, re-scoped by phase 101 (D1): the "Revoked" pill is
|
||||
# gone — the table IS the status. The row LEAVES the active table
|
||||
# and lands in the revoked table below with its Revoked date cell
|
||||
# (text + the table's position, never color alone — B5).
|
||||
active = page.locator("#tokens-tbody tr", has_text="e2e-theme93")
|
||||
expect(active).to_have_count(0)
|
||||
revoked = page.locator("#tokens-revoked-tbody tr", has_text="e2e-theme93")
|
||||
expect(revoked).to_have_count(1, timeout=15_000)
|
||||
expect(revoked.locator(".stale-pill")).to_have_count(0)
|
||||
expect(revoked.locator("td.tokens-date-cell").last).not_to_be_empty()
|
||||
expect(page.locator("#tokens-status")).to_have_text('Revoked "e2e-theme93".')
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user