fix(e2e): navigate the router, not the URL fragment - #596
Conversation
The path-routing migration (e225828) left the workflow suite navigating by `location.hash`. Under `createWebHistory` that still changes the URL and still fires `hashchange`, but the router does not listen to it, so the route never changed and nothing threw. Every caller failed much later on a missing `.secret-list-item`, which read as a broken vault rather than a navigation that did nothing at all. `gotoVaultRoute` now pushes through the router instance, with a pushState + popstate fallback that drives `createWebHistory`'s own listener. Both keep the navigation in place, which the vault requires: the CryptoKey lives only in memory, so any reload drops it and the guard bounces to the lock gate. `openVault` delegates to the same helper instead of carrying a second, also hash-shaped copy of the logic, and the two specs that set `location.hash` inline now call the helper.
Quality Report — ConductionNL/keepiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 111/111 | |||
| npm | ✅ | ✅ 536/536 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ deferred — runs on the promotion into beta/main, not on a pull request into development | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-09-01 13:32 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/keepiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 111/111 | |||
| npm | ✅ | ✅ 536/536 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ deferred — runs on the promotion into beta/main, not on a pull request into development | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-01 13:38 UTC
Download the full PDF report from the workflow artifacts.
|
Verified against a live Nextcloud before merging, not just in CI. Ran The first CI run here failed gate-4 (composer-audit, exit 100 with no advisory named, so the audit could not reach its database). This branch touches only |
keepiq's E2E has been red on development since
e225828b feat(router): move keepiq off hash routing to clean path URLs. Three follow-up commits (#586, #585, #590) each fixed something real and the suite stayed red, because none of them touched the navigation helper.What actually broke.
gotoVaultRoutenavigated by settingwindow.location.hash. Under the old hash router that both changed the URL and drove the route. UndercreateWebHistorythe same line still appears to work: the URL gains a fragment andhashchangefires. ButcreateWebHistorydoes not listen tohashchange, so the route never changed, and nothing threw.That is why the failures were so hard to read. Every caller went on to fail 20 seconds later on a missing
.secret-list-itemor an invisible view, so 43 of them reportedelement(s) not foundand the suite looked like a broken vault. The vault was fine. The tests never left the page they started on.openVaulthad a second copy of the same hash logic: it looked for an anchor whose href matched#/secrets, and after the migration no such anchor exists, so it fell through to thelocation.hashbranch and did nothing either.The fix.
gotoVaultRoutepushes through the router instance on#keepiq-app, falling back tohistory.pushStateplus a dispatchedpopstate, which is the listenercreateWebHistoryactually installs. Both navigate in place, and that is not a stylistic preference here: the vault's CryptoKey lives only in memory, so any real reload drops it and the router guard bounces to the lock gate. The fallback derives its base exactly asrouterBase()in src/main.js does, so both the/apps/and/index.php/apps/URL forms resolve.openVaultnow delegates to that helper rather than keeping its own copy, and the two specs that setlocation.hashinline (compromise-recovery, folder-sharing) call the helper too.Verified locally:
playwright --listcollects 72 tests across 17 files, and lint reports 0 errors. The E2E job itself only runs on the push to development, not on this PR, so the real verdict lands after merge and I will report it there.