Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
f5d5cb6 to
c9b80d6
Compare
6534dd1 to
812c23b
Compare
c9b80d6 to
cca6a1f
Compare
812c23b to
054ff0e
Compare
cca6a1f to
aa4b84a
Compare
054ff0e to
948159e
Compare
948159e to
f4d2f79
Compare
aa4b84a to
24cc2d9
Compare
f4d2f79 to
e2f6c6d
Compare
24cc2d9 to
f8430c6
Compare
e2f6c6d to
d892ee8
Compare
d892ee8 to
64ab746
Compare
9ff8224 to
d2b07be
Compare
29dfa72 to
9fdc90b
Compare
d2b07be to
71cf082
Compare
9fdc90b to
9ef5dba
Compare
71cf082 to
bf160b6
Compare
54c3837 to
1f9585b
Compare
byrichardpowell
left a comment
There was a problem hiding this comment.
Nice.
Approving so you don't need a second review, but please check the comments and address anything that is important.
1f9585b to
65a37b0
Compare
There was a problem hiding this comment.
Pull request overview
Improves E2E test reliability and speed by polishing per-test teardown, hardening browser automation checks, and upgrading CLI PTY helpers used in E2E flows.
Changes:
- Refactors teardown orchestration into gated phases with consistent retry structure and faster delete verification.
- Adds browser automation utilities (
isVisibleWithin, main-frame status tracking) and updates store/app delete/uninstall flows to use them. - Enhances CLI PTY
waitForOutputto support cancellation and updates tests to useE2E_SKIP_TEARDOWN.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/e2e/tests/toml-config.spec.ts | Rename skip env var to E2E_SKIP_TEARDOWN and update cleanup comment. |
| packages/e2e/tests/toml-config-invalid.spec.ts | Rename skip env var to E2E_SKIP_TEARDOWN and update cleanup comment. |
| packages/e2e/tests/multi-config-dev.spec.ts | Rename skip env var to E2E_SKIP_TEARDOWN and update cleanup comment. |
| packages/e2e/tests/dev-hot-reload.spec.ts | Rename skip env var to E2E_SKIP_TEARDOWN and update cleanup comment. |
| packages/e2e/tests/app-scaffold.spec.ts | Rename skip env var to E2E_SKIP_TEARDOWN and update cleanup comment. |
| packages/e2e/tests/app-dev-server.spec.ts | Rename skip env var to E2E_SKIP_TEARDOWN and update cleanup comment. |
| packages/e2e/tests/app-deploy.spec.ts | Rename skip env var to E2E_SKIP_TEARDOWN and update cleanup comment. |
| packages/e2e/setup/teardown.ts | Reworks teardown phase gating/retries and adds fail-fast handling for “still has installs”. |
| packages/e2e/setup/store.ts | Refines store create/uninstall/delete flows; uses isVisibleWithin and new delete verification. |
| packages/e2e/setup/global-auth.ts | Uses isVisibleWithin for account-picker handling during global auth. |
| packages/e2e/setup/cli.ts | Extends PTY waitForOutput API to support abort/cancellation and safer waiter iteration. |
| packages/e2e/setup/browser.ts | Adds main-frame HTTP status tracking, isVisibleWithin, and status-based error refresh. |
| packages/e2e/setup/app.ts | Updates CLI helper arg ordering, adds interactive configLink, and speeds app deletion verification via 404 status. |
| packages/e2e/helpers/browser-login.ts | Uses isVisibleWithin for login flow branching and submit confirmation detection. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (signal) { | ||
| signal.addEventListener( | ||
| 'abort', | ||
| () => { | ||
| clearTimeout(timer) | ||
| removeWaiter() | ||
| reject(new Error(`Cancelled waiting for output: "${text}"`)) | ||
| }, | ||
| {once: true}, | ||
| ) | ||
| } |
There was a problem hiding this comment.
waitForOutput registers an AbortSignal abort listener but never removes it when the waiter resolves/rejects normally. If a long-lived signal is passed and never aborted, this retains closures (timer/output buffer refs) unnecessarily. Consider storing the abort handler function and calling signal.removeEventListener('abort', handler) inside both resolve and reject paths (and after timeout) to ensure cleanup even when the signal is never aborted.
|
|
||
| // If still visible — reload and check again | ||
| // Step 5: Reload the page to confirm the app is no longer listed. | ||
| // Success → app is not on listed on the page. |
There was a problem hiding this comment.
Typo in comment: "app is not on listed on the page" → "app is not listed on the page".
| // Success → app is not on listed on the page. | |
| // Success → app is not listed on the page. |
| // Gate: confirm the store has zero apps before attempting delete app. | ||
| if (!uninstalled) { | ||
| log.log(wCtx, 'skipping app delete — uninstall failed, run `pnpm test:e2e-cleanup-apps` after') | ||
| return |
There was a problem hiding this comment.
Do not stop teardown when uninstall verification flakes
teardownAll now returns before Phase 3 when Phase 1 does not verify uninstall, but uninstallAppFromStore can return false because of transient admin UI failures rather than because the app is definitely still installed. One concrete path is when the actions menu opens but the Uninstall item never becomes visible in packages/e2e/setup/store.ts:161-163. That kind of eventual-consistency/UI flake is exactly what the rest of teardown retries around, so treating it as terminal causes store-backed specs to skip app deletion and leak dev-dashboard apps into the shared org. The fallback mentioned in the log message also appears to be unavailable, because there is no test:e2e-cleanup-apps script in the repository.
React with 👍/👎 — all feedback helps improve the agent.

WHY are these changes introduced?
Improves reliability and speed of per-test teardown.
WHAT is this pull request doing?
Refactors teardown so phases have consistent structure, fixes/optimizes browser verification, and upgrades CLI helpers.
Now a complete store + app teardown looks like this:
@admin/…/settings/appsuninstallAppFromStore:click ⋯ → Uninstall → Confirm
(reload
admin/…/settings/apps)uninstallAppFromStore:reload
/apps,check app span gone
→ success
(gate: step 2 passed)
@admin/…/settings/plan/cancelisStoreAppsEmpty→
safeToDelete = true→
deleteStore(reload
admin/…/settings/plan/cancel)deleteStore:reload
/cancel,check if it gets redirect to
admin/…/access_account→ success
(gate: step 2 passed)
@dashboard/../app/…/settingsuninstalled = true→ proceed to delete app
(reload
dashboard/../app/…/settings)deleteAppFromDevDashboard:reload
/settings,check if 404
→ success
1. Faster app deletion verification (
setup/app.ts)Before:
waitForURL(url !== urlBefore)burned up to 60s for the page to navigate away (usually takes 10-20 sec).delete-app-automatic-redirect.mov
After: reloads
{appUrl}/settings—404= deleted, other = fail/retry. Completes in seconds.delete-app-force-refresh.mov
Also: early 404 short-circuit on initial load,
scrollIntoViewIfNeededfor below-fold button,STILL_HAS_INSTALLSfail-fast (throw instead of spinning on disabled Delete button), optionalDELETEconfirmation input.2. Faster store deletion verification (
setup/store.ts)Before: navigated to
/settings/plan, clicked shadow DOM button, verified viawaitForURL(/access_account/)— burned 60s on silent failure.After: navigates to
/settings/plan/cancel(auto-opens modal, no shadow DOM click needed), verifies vianetworkidle+ reload →access_accountredirect check.Modal scoped by title (
.Polaris-Modal-Dialog__Modal:has-text("Review before deleting store")) to avoid matching stale modals.3. Consistent uninstall verification (
setup/store.ts)Before: checked stale DOM first, only reloaded as fallback.
After: always reloads → dismisses Dev Console → checks. Matches cleanup-stores pattern.
4. Teardown orchestrator cleanup (
setup/teardown.ts)Each helper now owns its own verification; teardown becomes the orchestrator:
STILL_HAS_INSTALLSand fails fast (cleanup-apps reaps orphans)isStoreAppsEmptybefore attempting store delete5. CLI helper upgrades (
setup/app.ts)configLinkrewritten — fromexecwith--client-idto interactive PTY spawn that answers org/app prompts (needed for tests that create apps from scratch)createAppauto-defaults--flavor javascriptfor reactRouter/remix (prevents PTY hang)versionsListaccepts optionalconfig(needed for multi-config tests)--pathalways last across all helpers6. Minor fixes
E2E_SKIP_CLEANUP→E2E_SKIP_TEARDOWNacross 7 test specs (matches what it actually controls)refreshIfPageError:Internal Server Error→500: Internal Server Error(tighter match)How to test your changes?
Run an E2E test and confirm teardown completes cleanly:
Expand for complete log
Checklist
pnpm changeset add