Skip to content

Avoid retrying side-effecting browser actions#227

Open
CalorieStar wants to merge 1 commit into
pestphp:4.xfrom
CalorieStar:fix-do-not-retr-browser-actions
Open

Avoid retrying side-effecting browser actions#227
CalorieStar wants to merge 1 commit into
pestphp:4.xfrom
CalorieStar:fix-do-not-retr-browser-actions

Conversation

@CalorieStar

Copy link
Copy Markdown

Summary

I had an issue where click() was timing out on some pages, even though the click visibly occurred in the browser when using --debug.

This appears to relate to the behaviour described in:

Related to pestphp/pest#1511

What changed

This PR updates AwaitableWebpage so state-changing browser actions are no longer routed through Execution::waitForExpectation().

This includes actions such as:

  • click
  • press
  • fill
  • check
  • select
  • drag
  • attach
  • similar browser actions that may alter page or application state

Assertions and read-style expectations still use the existing retry loop.

Why

Execution::waitForExpectation() retries the callback using a 1000ms Playwright timeout. That behaviour is useful for assertions, because repeatedly checking whether something is true is usually safe.

For example, retrying an assertion such as assertSee() is useful because the page may need time to update.

However, this retry behaviour is less suitable for browser actions. Actions such as click() and press() can change the page, trigger JavaScript, submit forms, start navigation, or update application state.

In these cases, the action may already have succeeded, but Pest may still report Timeout 1000ms exceeded if the operation did not complete within the 1000ms attempt window. Retrying the action can then cause further issues because:

  • the original element may no longer exist
  • navigation may already have started or completed
  • the page may now be in a different state
  • the same action may be attempted more than once
  • form submissions or JavaScript handlers may be triggered more than intended

This PR avoids the pattern where a browser action visibly succeeds, but Pest still fails because the action was handled through the expectation retry loop.

Behaviour after this change

State-changing browser actions are attempted once and use the configured Playwright/browser timeout.

Assertions continue to be retried until the configured timeout expires.

This preserves the useful retry behaviour for assertions, while avoiding unsafe retries for actions that may alter browser or application state.

Side-effecting / state-changing actions

A side-effecting action is an operation that changes something.

In browser testing, this means the command does not merely observe the page. It may alter:

  • the DOM
  • form values
  • browser state
  • page state
  • application state
  • server state
  • database records
  • navigation state

Examples include click, press, fill, check, select, drag, and attach.

These actions should be awaited using the configured action timeout, but not retried in the same way as assertions.

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