Skip to content

spinner-waiter: inputValue waits like an action, and a target that is ready by the loading check proceeds - #47

Merged
jonastemplestein merged 1 commit into
mainfrom
input-value-loading-aware
Oct 7, 2026
Merged

jonastemplestein merged 1 commit into
mainfrom
input-value-loading-aware

Conversation

@jonastemplestein

Copy link
Copy Markdown
Contributor

Ports the branch fix/input-value-loading onto main. iterate/private has run on that branch since before the repo split: it pins pkg.pr.new/middlewright@e3f2374, a build of the branch, not of main. Without this PR, iterate/private cannot move to a main build with #46's fix without losing the two changes below.

What changes

inputValue waits like an action. It joins the patched Locator methods. A read of an input that has not appeared yet waits while loading UI is visible, then returns the current value. It does not wait for a particular value. An explicit timeout still passes through.

// a composer that shows "Opening chat…" for 2 s
expect(await page.getByLabel("Message").inputValue()).toBe("About my edited note");

Before: locator.inputValue: Timeout 1000ms exceeded. After: it returns the value. iterate/private's browser specs call inputValue() in 8 places.

A target that is ready by the loading check proceeds. Before the no-spinner fast-fail, the waiter checks the target once more. A target that became ready while loadingVisible ran (the spinner left and the control enabled between the two observations) now gets its normal action budget, not a 1 ms timeout. The cost is one isVisible (and isEnabled for actions) round trip on the fast-fail path only.

Tests

Three rows from the branch, unchanged:

  • inputValue waits for a loading composer and returns its value
  • inputValue preserves an explicit timeout and can read disabled inputs
  • a control becoming ready during the loading check keeps its normal action budget (a custom selector engine finishes the UI update at the exact moment the loading check runs)

Local: pnpm typecheck, pnpm lint, pnpm build clean; pnpm test 162 passed, 3 skipped (with ffmpeg-full).

The branch's CI change (publishing builds of fix/input-value-loading on push) is left out.

Risk map

  • Riskiest part: the recheck sits next to spinner-waiter: a document that commits mid-check gets its own quick check #46's new navigation loop. It runs only after the loop decided "nothing loading", so it can only turn a fast-fail into a success, never a wait.
  • On merge: inputValue goes through the plugin chain, so other plugins (video mode, screenshots) see it as an action. This is what iterate/private already runs.
  • Review order: src/plugins/spinner-waiter.ts, src/plugin-system.ts, the spec, the README.

todo-app baseline video

mw-todo-app.mp4

🤖 Generated with Claude Code

… ready by the loading check proceeds

Port of the branch fix/input-value-loading, which iterate/private has run on
since before the repo split (pinned as pkg.pr.new/middlewright@e3f2374):

- inputValue joins the patched methods, so a read of an input that has not
  appeared yet waits while loading UI is visible, then returns the current
  value. An explicit timeout still passes through.
- Before the no-spinner fast-fail, the target is checked once more. A target
  that became ready while the loading check ran proceeds with its normal
  budget instead of a 1 ms timeout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
Patching inputValue changes behavior for all plugin-enabled pages (other plugins now see reads as actions), and the fast-fail recheck adds an extra readiness round-trip on the no-spinner path only.

Overview
inputValue is now a patched locator method, so it runs through the same middleware chain as click and fill. With spinnerWaiter, reading a field that isn’t on the page yet waits while loading UI is visible, then returns the current value—it does not wait for a specific value. Explicit { timeout } still bypasses spinner logic; disabled but visible inputs remain readable.

Spinner-waiter no-spinner path: after deciding nothing is loading (including post-navigation checks), it re-checks whether the target is already ready before applying the 1 ms fast-fail. Controls that become ready in the gap between the readiness poll and the loading check keep the normal action timeout instead of failing instantly.

README and three Playwright specs cover composer inputValue, explicit timeout on inputValue, and the ready-during-loading-check race (custom selector engine).

Reviewed by Cursor Bugbot for commit 20eacef. Bugbot is set up for automated code reviews on this repo. Configure here.

@pkg-pr-new

pkg-pr-new Bot commented Oct 7, 2026

Copy link
Copy Markdown

Open in StackBlitz

pnpm add https://pkg.pr.new/middlewright@47

commit: 20eacef

@jonastemplestein
jonastemplestein merged commit 8cb3155 into main Oct 7, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant