Skip to content

test(admin): wait for the deleted block's exit before reading rows - #4778

Open
khoinguyenpham04 wants to merge 2 commits into
mainfrom
noah/blocks-motion-test-flake
Open

khoinguyenpham04 wants to merge 2 commits into
mainfrom
noah/blocks-motion-test-flake

Conversation

@khoinguyenpham04

Copy link
Copy Markdown
Collaborator

What does this PR do?

Fixes a timing flake in the admin browser test BlocksField.undo.test.tsx > "Structure motion" > "leaves the rows above in place when the last block is deleted at the end of the page". It failed CI's Browser Tests job twice on unrelated PRs, each time the only failure:

AssertionError: expected [ 'one', 'two', 'three', 'four' ] to deeply equal [ 'one', 'two', 'three' ]

The test sampled the rows above for a fixed 450 ms, starting before the Delete click. On a loaded runner, the click can reach the page late, so the window closes before the deleted row has shrunk away and been removed. The row list then still holds it.

The sampler now runs until the deleted row is gone and nothing on the page is animating. The assertions are unchanged, and the sampled window now always covers the whole exit motion, however late it starts. Only the test file changes.

Type of change

  • Bug fix
  • Feature (requires an accepted feature plan or RFC)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Your connection to this change

  • I use EmDash and ran into the problem this PR addresses
  • I maintain a tool, dependency, or service that EmDash uses, and this change concerns that integration
  • A Maintainer approved this specific change before I opened the PR

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation (if applicable). Not applicable: no UI strings change.
  • I have added and reviewed the user-facing changeset (if this PR changes a published package). Not applicable: test-only change.
  • New features link to their merged design PR. Not applicable.
  • I have included screenshots below if this PR changes the UI. Not applicable: no UI change.

AI assistance disclosure

  • This PR includes AI-generated code or text — model/tool: Claude Opus 5.5

Screenshots / test output

Not applicable for screenshots.

Reproduction. CPU throttling alone (Emulation.setCPUThrottlingRate at 4× and 20×, 10 runs each) did not reproduce it: throttling slows the page's own work, not the gap between the sampler starting and Playwright's click arriving. Holding the click back 250 ms inside the sample window, a stand-in for slow click delivery on a busy runner, made the old test fail with the same message as CI. The scratch edits used for this are not part of the PR.

Verification.

  • Old test, click delayed 250 ms: fails with expected [ 'one', 'two', 'three', 'four' ] to deeply equal [ 'one', 'two', 'three' ].
  • New test, click delayed 250 ms: 5 of 5 runs pass.
  • New test, click delayed 1000 ms: 5 of 5 runs pass.
  • Unmodified file, both Chromium projects: 33 of 33 tests pass.
  • pnpm --silent lint:json | jq '.diagnostics | length' returns 0; pnpm typecheck passes.

The end-of-page delete test sampled the rows above for a fixed 450 ms
that started before the Delete click. When the click reached the page
late, as on loaded CI runners, the window closed before the deleted
row had shrunk away, so the row list still held it.

Sample until the deleted row is gone and nothing animates, so the
check covers the whole exit however late it starts.
@changeset-bot

changeset-bot Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 86fd631

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The approach is sound. The sampler now stops once row "four" is gone and no animations are running, rather than after a fixed 450 ms that began before the Delete click. This addresses the slow-runner CI failure without weakening the position assertions, and only the test file changes. Both reviewers approved. One non-blocking suggestion: the new loop has no frame cap, so a delete that never takes effect would hang until the Vitest timeout instead of failing with a clear assertion. The until helper in the same file caps itself at 120 frames. Also, because the stop condition already requires "four" to be gone, the later rowKeys() assertion now only re-checks the order of the remaining rows.


Reviewed by anthropic/claude-opus-5-5 and openai/gpt-6.1-sol.

if (now - start < ms) requestAnimationFrame(tick);
else resolve();
if (done()) resolve();
else requestAnimationFrame(tick);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] Nothing bounds this loop. If done() never becomes true (the delete doesn't happen, or an animation never finishes), the test hangs until the Vitest timeout instead of failing quickly with a useful message. The until helper above stops after 120 frames. Consider a similar cap here, for example resolving after N frames and letting the assertions that follow report the failure:

if (done() || frames.length >= 300) resolve();
else requestAnimationFrame(tick);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, capped it at 300 frames in 86fd631, so a row that never goes now fails on the row-list check in a few seconds.

A regression that never removes the row now fails on the row-list
assertion within a few seconds instead of hanging until the test
timeout.
@emdashbot emdashbot Bot added review/needs-review No maintainer or bot review yet and removed review/needs-review No maintainer or bot review yet labels Nov 9, 2026

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The follow-up is sound: the 300-frame cap addresses the earlier suggestion while retaining condition-based sampling and the existing position assertions. I checked the follow-up diff and surrounding sampler/call-site code; if deletion never completes, the row-list assertion can now report the failure rather than waiting indefinitely for the sampler. The prior finding is resolved, and I found no new issues in the changed code. Static review only; tests were not run.


Follow-up review by openai/gpt-6.1-sol, scoped to the changes since the last review.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview URL: https://noah-blocks-motion-test-flake.try.emdashcms.com, https://noah-blocks-motion-test-flake-emdash-playground.emdash-cms.workers.dev (commit 86fd631)

This URL reflects your latest Preview deployment

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://5e820541.try.emdashcms.com, https://5e820541-emdash-playground.emdash-cms.workers.dev 86fd631 2026-11-09T14:24:58.053Z Visit the dashboard ↗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant