Skip to content

[Bug]: requestAnimationFrame does not execute callbacks after page.clock.fastForward() for the duration of time that was fast forwarded #37635

@rodrigojmr

Description

@rodrigojmr

Version

1.55.1

Steps to reproduce

  1. clone https://github.com/rodrigojmr/playwright-raf-fastforward
  2. npm install
  3. npx playwright test tests/example.spec.ts --repeat-each 400 --max-failures=1

Eventually a test should fail. If not, either of the commented code in tests/example.spec.ts or index.html should improve the likelihood of it failing, especially doing requestAnimationFrame(step); twice in index.html.

Expected behavior

I expect requestAnimationFrame to continue executing as expected after page.clock.fastForward() runs its timers once. I'm aware that for the duration of time that was fast forwarded all requestAnimationFrame callbacks should execute only once, but then they should continue as normal.

Actual behavior

Sometimes, after a page.clock.fastForward() a requestAnimationFrame does not execute its callback for the amount of time that was fast forwarded - if 5000 milliseconds were fast forwarded, a requestAnimationFrame will not fire its callback for 5000 milliseconds. The same is more likely to happen if within a callback, another requestAnimationFrame is performed.

test-results.zip

Additional context

I work in an app for TVs using the Lightning.js framework which performs its render loop with requestAnimationFrame. https://github.com/rdkcentral/Lightning/blob/master/src/platforms/browser/WebPlatform.mjs#L105-L118 For our playwright tests, we often need to fast forward time for a variety of reasons, and due to this behaviour, sometimes the app remains frozen for the amount of time that was fast forwarded, so we must use a command like this to ensure the test doesn't fail. Simplified:

export function waitForAnimationFrame(page: Page) {
  return page.evaluate(() => {
    return new Promise<void>((resolve) => {
      function onFrameEnd() {
        resolve();
      }

      requestAnimationFrame(onFrameEnd);
    });
  });
}

Nearly every time we use page.clock.fastForward we must use this command to prevent flakyness, but it makes some runs where this occurs (1/10 or 1/30) significantly slower and forces us to add additional configuration so that the time we need to fast forward is often low (2-5s) as we do not want the test to hang for 10s+.

Environment

System:
    OS: macOS 15.6.1
    CPU: (12) arm64 Apple M2 Pro
    Memory: 120.89 MB / 32.00 GB
  Binaries:
    Node: 20.11.1 - ~/.nvm/versions/node/v20.11.1/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v20.11.1/bin/yarn
    npm: 10.9.2 - ~/.nvm/versions/node/v20.11.1/bin/npm
    bun: 1.2.10 - ~/.bun/bin/bun
  IDEs:
    VSCode: 1.104.1 - /usr/local/bin/code
  Languages:
    Bash: 3.2.57 - /bin/bash

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions