Commit graph

3 commits

Author SHA1 Message Date
Johannes Millan
238b91aa59
test(e2e): accept beforeunload prompt in shared dialog fallback (#9122)
The USE_REMOTE crash-resume spec reloads Client B mid-sync. While
isSyncInProgress is set, startup.service's beforeunload handler calls
preventDefault(), so Chrome raises a beforeunload prompt (the preceding
button click supplies the user activation it requires). Playwright
auto-accepts such prompts only when no 'dialog' listener is registered —
but installDevErrorDialogHandler registers one on every page and early-
returned on beforeunload, leaving the prompt unanswered. The navigation
then never starts and reload() times out (observed on SuperSync shard
6/6; the earlier load→domcontentloaded de-flake could not help because
navigation is blocked before any lifecycle event).

Accept beforeunload in the shared fallback, restoring Playwright's
default; other dialog types keep flowing to spec-specific handlers.
Corrects the two crash-resume comments that encoded the wrong theory.
2026-07-17 17:34:29 +02:00
johannesjo
f1d9161d13 test(e2e): dismiss devError native dialogs so sync tests don't hang
devError() in non-production builds opens window.alert("devERR: …") then
window.confirm("Throw an error for error? ––– …"). Both are page-blocking,
so any Playwright call (goto/click/waitFor) hangs until the dialog is
handled. After the project-task-page signal subscription added in
34af7b103, selectProjectById fires devError whenever sync removes the
project the user is currently viewing — which masters' webdav delete-
cascade and supersync legacy-migration tests trigger by design.

Add installDevErrorDialogHandler that matches the exact two devError
shapes and dismisses them, then wire it into the four E2E page-creation
sites: the default test fixture, setupSyncClient, createSimulatedClient,
and createLegacyMigratedClient. Production code is untouched.

Also carve out the devError confirm in setupSyncClient's strict confirm
validator so it doesn't raise an unhandled rejection alongside our
dismiss, and drop the unused createLegacyMigratedClientNoDialogHandler
wrapper (it now lies — the underlying helper does install a handler).
2026-05-23 23:13:09 +02:00
Johannes Millan
77f83c5687
test(e2e): harden failure signals and provider gates (#7753)
* test: harden e2e failure signals

Fail otherwise-passing E2E tests on browser runtime errors, keep Playwright retries disabled, preserve Docker E2E exit codes, and make plugin/WebDAV setup failures hard failures instead of logged or skipped conditions.

* test: harden provider e2e runners

Make WebDAV and SuperSync runner scripts require provider readiness, preserve cleanup and argument forwarding, and fail manual sync clients on uncaught page errors.

* ci: require providers for scheduled e2e

Set required-provider flags in scheduled WebDAV and SuperSync jobs, and remove the duplicate provider runner scripts while keeping local npm aliases inline.

* test: catch e2e teardown pageerrors and tighten fixture

- closeClient now asserts runtime errors AFTER context.close() so
  pageerrors emitted during teardown (Angular destroy hooks, late RxJS
  errors) are captured instead of dropped. Matches the pattern in
  guardContextCloseWithRuntimeErrorCheck.
- test.fixture.ts isolatedContext now spreads Playwright's merged
  contextOptions instead of destructuring 23 fields by hand. Future
  option additions propagate automatically; the page fixture uses the
  shared attachPageErrorCollector and only fails on pageerror (not
  console.error, which is too noisy). Guards against a configured 0
  timeout being treated as undefined.
- plugin-loading.spec.ts second test now hard-asserts that the plugin
  menu entry reappears after re-enable, matching the first test instead
  of silently logging when not visible.

* test(sync): stabilize ImmediateUploadService spec

Two complementary fixes for flaky failures observed under full-suite
random-order runs where the upload pipeline silently never fires:

- Pin navigator.onLine = true in beforeEach (restored in afterEach).
  isOnline() inside _canUpload reads navigator.onLine directly. The
  keyboard-layout spec replaces the whole navigator and the is-online
  spec spies on it; if order or restoration ever drifts, every "should
  fire upload" test fails trivially while the "should NOT" tests pass.
- Replace tick(2100) with tick(2000); flush(). The await chain inside
  withSession() (provider.isReady, withSession entry, uploadPendingOps,
  optional LWW re-upload) requires more microtask drain than tick's
  fixed-time window reliably provides under load. flush() drains the
  pipeline regardless.

* test(e2e): guard skipOnboarding init script against data: frames

The new page-error collector started failing plugin specs because
addInitScript runs in every frame — including the empty data:text/html
iframe that plugin-index swaps in on destroy — and localStorage access
in a data: URL throws SecurityError. Wrap the four setItem calls in
try/catch so the helper noops in storage-less frames.
2026-05-23 20:33:04 +02:00