docs/backend-migration/handoffs/e2e-tester-skill-library-2026-04-22.md
Branch: feat/backend-migration-e2e-skill-library
Last commit (pre-handoff): 028a560ca (docs(backend-migration): e2e report for skill-library pilot)
Repo: /Users/zhoukai/Documents/github/AionUi
Predecessor: this is replacement e2e-tester #1 (original was shut down for two
consecutive empty idles). All work below is mine as replacement.
Task 4 Steps 4.1 through 4.4 complete. Step 4.5 is this file. Step 4.6 is blocked on coordinator direction (all-fail outcome per plan §4.6 rubric — see "Known issues").
Verified on feat/backend-migration-e2e-skill-library at tip
3fd28d23a prior to writing the report. git log --oneline -5 shows the
coordinator merges (fe handoff + e2e-coverage) already present.
Inventoried 10 files / 29 tests under tests/e2e/features/settings/skills/.
Mapped each to the E1–E5 pilot surface and to the additional /api/skills/*
routes the helpers consume (detect-external, import-symlink, {name}
delete, export-symlink, external-paths, scan, import). Backend
implementation (skill_routes.rs:51–99) already covers every route the
helpers touch — no missing backend surface. Full matrix is in the
report's "Pilot scope → endpoint map" section.
~/.cargo/bin/aionui-backend built at 2026-04-22 20:58 from
feat/extension-skill-library (frontend-dev's cargo install). Fetched
origin on both repos; no non-docs commits since the install.bun run e2e, actual is
bun run test:e2e. Re-flagged in the report.bun run test:e2e tests/e2e/features/settings/skills/. Full run
completed in ~7 minutes. Log captured at /tmp/e2e-skill-library/run.log
(not committed — large, transient).Committed docs/backend-migration/e2e-reports/2026-04-22-skill-library.md
at 028a560ca. Contents:
fixtures.ts (real _electron.launch) and helpers (real DOM, real
preload bridge, no mocks).my-skills-section not rendering within 5s; secondary: legacy IPC
bridge keys in helpers incompatible with the HTTP migration).None from my side. Task 4 is at the reporting gate; the pilot rubric requires
Task 4 to NOT be marked completed until either all 29 pass and UI rendering
is verified (plan §4.6 "ALL PASS"), or the failures are routed, fixed, and
re-run (plan §4.6 "ANY FAIL" loop).
Coordinator has been messaged with the outcome and awaits routing decision.
All 29 tests fail at the same gate. goToSkillsHub times out waiting
for [data-testid="my-skills-section"]. The testid is unconditional in
SkillsHubSettings.tsx:391, so the component is not mounting within the
5s budget, or is mounting with a different tree (error boundary / wrong
route). No failure screenshot was retained — Playwright's
screenshot: 'only-on-failure' should have captured but artifact dirs
under tests/e2e/results/ were created empty. Verifying the artifact
pipeline is itself a follow-up item.
The e2e helpers use legacy IPC bridge keys. helpers/bridge.ts's
invokeBridge emits subscribe-<key> events to window.electronAPI,
using keys like list-available-skills, detect-and-count-external-skills,
import-skill-with-symlink, delete-skill, add-custom-external-path,
remove-custom-external-path, get-skill-paths, get-custom-external-paths,
get-skill-paths. Commit 5c4b010f5 deleted fsBridge.ts (1821 lines)
and those handlers no longer exist. Helpers will need rewriting to call
the HTTP bridge directly (e.g. via page.evaluate(() => fetch('/api/skills')))
before the skill-hub e2e suite can green. This is a secondary failure —
it is not the proximate cause of the 5s timeout — but it will need to be
fixed in parallel with the primary issue for the suite to fully pass.
Plan script-name delta. Plan says bun run e2e; actual is
bun run test:e2e. Frontend-dev already flagged the sibling case
(bun run dev vs bun start). Plan-text follow-up ticket recommended.
Playwright artifact retention gap. playwright.config.ts sets
screenshot: 'only-on-failure' and trace: 'on-first-retry', with
retries: 0 in dev mode. Result: no traces, no videos, empty screenshot
dirs — no visual evidence of WHICH screen the app was stuck on when the
section timeout fired. Follow-up: add a short-lived config override
(retain-on-failure) or re-run one case with inline overrides to capture.
Scope boundary uncertainty for E3/E4. The pilot mandates E1–E5
parity, but the Skills-Hub e2e feature folder (these 10 files) does
not exercise E3 (builtin-rule) or E4 (builtin-skill). Those flow
through usePresetAssistantResolver.ts and are covered only by
assistant-side unit tests. If "pilot E2E success" is interpreted
strictly as E1–E5 coverage, additional assistant-flow e2e is needed.
If it means "the Skills Hub user journey works end-to-end", the
10-file scope is correct but E3/E4 don't need e2e coverage here.
Flagging for coordinator decision.
Status of the original two items (asked for in the first commit of this handoff; both are now answered by the 2026-04-22 evening rerun):
UpdateDONE by frontend-dev in committests/e2e/helpers/skillsHub.tsto replaceinvokeBridge('subscribe-<old-key>')calls with HTTP.000676801. Verified at rerun — 17/29 now pass; the 12 remaining failures are no longer helper-layer issues.Verify whether theRESOLVED ON ITS OWN. Rerun confirmsmy-skills-sectionvisibility issue resolves on its own or needs separate investigation.my-skills-sectionis visible for every test that reaches it; the first run's blanket timeout was a cascade from a staleout/rendererbundle +aionui-backendnot on PATH (both called out in fe-dev's rerun prep instructions), not a rendering-layer regression.
Per coordinator's time-boxed Phase D directive, captured traces for TC-S-25 and TC-S-17 and probed backend directly. Full detail in the e2e report's "Phase D trace findings" section; summary:
POST /api/skills/external-paths returns
{success:true, HTTP 200} on duplicate path, silently overwriting the
existing entry's name. Renderer's handleAddCustomPath at
SkillsHubSettings.tsx:216 unconditionally closes the modal on no-throw.
Test expects an error + modal stays open. Backend contract gap
(inherited from migration; TS baseline likely rejected duplicates).
Fix scope: ~1 function + error mapping in
aionui-extension::external_paths_manager::add_custom_external_path.
Routing: backend-dev.~/.aionui/skills/ from prior runs) exposing
a broken-symlink filter edge case. Needs backend-dev instrumentation
(a debug! log in list_available_skills) + rerun to confirm.
Not proven 1-file-diff. Routing: backend-dev instrumentation first.Coordinator-rubric call (time-box ~23:55 local, deadline 10:00 tmr): Recommended (b) — close pilot at 22/29. Rationale in the e2e report; briefly:
Coordinator approved Option 1. Backend-dev landed the source field fix in
aionui-backend@3a86d58. Phase B rerun (after a first attempt surfaced
accumulated dirty state in ~/.aionui/custom-skill-paths.json, reset as
step zero, plus 89 leftover /var/folders/.../aionui-e2e-external-* temp
dirs removed) delivered:
Per coordinator's Phase B rubric, A/F not cleared → Phase D territory (trace + route to backend or fe). Not pilot-closing on my side alone.
See the e2e report's "Phase B rerun after backend source-field fix" section for the full per-case table.
The helper-fix rerun results (17 PASS / 12 FAIL — see the e2e report's "Rerun after helpers fix" section for the per-failure breakdown) split across three owners:
Backend fix (blocks class (D) failures — 5 tests). Add a source: String field to ExternalSkillSourceResponse in
aionui-backend/crates/aionui-api-types/src/skill.rs:116 and populate it
in skill_routes.rs:260–277. The renderer uses source.source at
SkillsHubSettings.tsx:289 as both the React key and the
data-testid="external-source-tab-${source}" suffix, and initialises
activeSourceTab from external[0].source. With the field omitted,
every external source collides on key undefined, the active tab never
resolves, and selected-tab-gated card DOM never renders. Evidence:
Playwright strict-mode diff on TC-S-08 shows two buttons both with
data-testid="external-source-tab-undefined". Fix scope: ~8 lines of
Rust + one unit-test update on the backend; no renderer change needed.
Test-authoring fixes (classes (B), (C), (E) — 4 tests). Reseed
builtin / extension / auto-skill directories before the affected tests,
or assert-presence-only-when-data-exists. Also tighten
button:has-text(...) matchers to exact-match to avoid TC-S-11 state
leakage. Not a migration regression.
Cross-stack investigation (classes (A), (F) — 3 tests). Bulk-import
completion race (TC-S-11, TC-S-25) and modal lifecycle on duplicate-path
error (TC-S-17). These need single-test reruns with E2E_TRACE=1 to
capture a visual trace before any fix is attempted.
Do NOT mark Task 4 complete. Plan §4.6 rubric remains ANY FAIL = yes.
Coordinator routing needed for items 1–3 above; Task 4 stays
in_progress until the backend fix lands and either the test-body
issues are fixed, OR the coordinator accepts a partial-pass as pilot
success criterion.
If another e2e-tester continues on this branch:
First, gather visual evidence. Patch playwright.config.ts locally
with trace: 'retain-on-failure', screenshot: 'on', video: 'retain-on-failure'
and re-run ONE test (tests/e2e/features/settings/skills/core-ui.e2e.ts
TC-S-01). Inspect tests/e2e/results/<test>/trace.zip via
bunx playwright show-trace to see exactly what screen the app renders
at the 5s timeout. This determines whether the SkillsHub tab is actually
rendered (indicating a testid drift), partially rendered (React error),
or not rendered at all (routing / mount failure).
Run a sanity check against a non-skill e2e file. For example
tests/e2e/features/settings/display-settings.e2e.ts or
any tests/e2e/features/conversation/ spec. If those also fail at
their own beforeEach step, the problem is bootstrap-level (app
doesn't finish booting in the expected window). If they pass, the
problem is specific to the Skills Hub tree.
Rewrite tests/e2e/helpers/skillsHub.ts bridge calls to HTTP.
Once the primary rendering issue is understood and fixed, the
helper's invokeBridge pathway must be replaced. Two options:
window.__e2eFetch = (path, init) => fetch(path, init) in dev mode,
then have helpers call page.evaluate(({path, body}) => window.__e2eFetch(path, {method:'POST', body}).then(r => r.json()), ...).Decide on E3/E4 coverage. If strict E1–E5 parity is required, find the assistant-side e2e that exercises preset rule/skill loading, or add one. If not, document the decision in the module record.
Do NOT mark Task 4 completed until all 29 pass AND UI rendering is re-verified after the helper rewrite. Coordinator's final completion criteria (plan §4.6) hinges on the all-pass + verified conjunction.
Do not merge this branch into feat/backend-migration.
Base-branch integration is explicitly deferred until after the
pilot closes (plan §5.2).
git status clean after handoff commit.Branch tip at handoff-write time: 028a560ca
(docs(backend-migration): e2e report for skill-library pilot).
After committing this handoff, the tip advances one commit. Coordinator
can inspect the full change set with:
git log --oneline origin/feat/backend-migration-e2e-skill-library ^origin/feat/backend-migration-fe-skill-library
Backend commit baseline remains 229b6e04 on feat/extension-skill-library.
Per the plan, this branches into the "ANY FAIL" loop. I have deliberately
NOT written an incident file and have NOT routed to frontend-dev or
backend-dev, because the failure spans both streams (renderer migration +
e2e-coverage) and the routing decision belongs to the coordinator. Task 4
status remains in_progress in TaskList.
Coordinator approved closure recommendation (b) at the end of the time-boxed Phase D. Task 4 is complete at 22 PASS / 7 FAIL, with the transport/migration layer validated CLEAN (class D = 0). The remaining failures are categorized and logged as separate followups — none of them is a regression from the pilot's own migration work.
Final artifacts pushed on feat/backend-migration-e2e-skill-library:
docs/backend-migration/modules/skill-library.md —
appended "Final pilot outcome (post-Phase-D)" section with full failure
classification, commit SHAs by role (backend E1–E5 + source field fix,
frontend helper migration, e2e-tester reports), and links to all four
role handoffs.docs/backend-migration/post-pilot/2026-04-23-skill-library-followups.md
— P0 (duplicate-path rejection + data-dir sandbox), P1 (five
test-authoring items), P2 (TC-S-25 bulk-import scale investigation).
Each ticket includes filepath-level repro/fix guidance.docs/backend-migration/e2e-reports/2026-04-22-skill-library.md —
0/29 first run → 17/12 helper-fix rerun → 22/7 Phase B → Phase D
trace findings → closure rationale.What the next teammate should read first: the module record's "Final pilot outcome" section for the one-page summary, then the post-pilot followup list for concrete next-ticket work. The full e2e report is available when deeper diagnosis is needed.
Shutdown: Task 4 complete from e2e-tester side. TaskUpdate to
completed lands concurrent with this commit's push; final SendMessage
to coordinator follows. Awaiting coordinator's shutdown_request as
the last act of Task 5.