Skip to content

test: improve reliability on firefox for tests that inject stylesheets#4938

Merged
dbjorge merged 1 commit intodevelopfrom
preload-cssom-test-reliability
Nov 12, 2025
Merged

test: improve reliability on firefox for tests that inject stylesheets#4938
dbjorge merged 1 commit intodevelopfrom
preload-cssom-test-reliability

Conversation

@dbjorge
Copy link
Copy Markdown
Contributor

@dbjorge dbjorge commented Nov 12, 2025

In #4919, we found that the test_firefox job was unacceptably flaky in the preload-cssom tests. I believe this is because the GHA runners are slightly more resource-constrained than the circleci ones, which broke an assumption in axe.testUtils.addStyleSheet that adding a <style> element would result in document.styleSheets being updated accordingly within 100ms (in Chrome this happens instantly, but in Firefox there is a delay). I updated the test util to poll until it actually sees document.styleSheets update as expected, and to reject with a more actionable error if a timeout occurs (rather than letting a test run in an unexpected state). This also has a minor side-benefit of making the tests marginally faster on Chrome, since they no longer wait 100ms-per-injected-sheet unnecessarily.

You can see the results of this in #4936 - the preload-cssom test_firefox case only passed 6/10 runs without this fix and passed 10/10 runs with this fix.

The updates in preload-cssom.js turned out to be unnecessary to fix the issue, but they make errors in the test more actionable and make the test more consistent with others, so I left them in.

No QA required.

@dbjorge dbjorge marked this pull request as ready for review November 12, 2025 22:08
@dbjorge dbjorge requested a review from a team as a code owner November 12, 2025 22:08
Copilot AI review requested due to automatic review settings November 12, 2025 22:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR improves the reliability of Firefox tests by fixing flaky behavior in stylesheet injection. The main issue was that Firefox has a delay between adding a <style> element and it appearing in document.styleSheets, which was causing test failures on resource-constrained runners.

Key Changes:

  • Replaced fixed 100ms setTimeout with an active polling mechanism that checks when stylesheets actually load
  • Improved error messages in both test utilities and integration tests to make failures more actionable
  • Added timeout handling with clear error messages for debugging

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
test/testutils.js Replaced fixed 100ms delay with polling mechanism that actively checks document.styleSheets until the injected stylesheet appears (or times out after 500ms)
test/integration/full/preload-cssom/preload-cssom.js Refactored test to use predefined stylesheet constant and enhanced error message to show actual resolution value when rejection is expected

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +371 to +386
const interval = setInterval(function () {
const isLoaded = Array.from(doc.styleSheets).some(
sheet => sheet.ownerNode === style
);
if (isLoaded) {
clearInterval(interval);
resolve();
} else if (Date.now() > timeoutAt) {
clearInterval(interval);
reject(
new Error(
'Added <style> element was not reflected in doc.styleSheets within timeout'
)
);
}
}, 5);
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

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

The polling logic should be wrapped in a try-catch block to handle potential exceptions when accessing doc.styleSheets or sheet.ownerNode. If an error occurs (e.g., due to security restrictions or unexpected browser behavior), the interval will never be cleared, causing a memory leak and the promise will never resolve or reject.

Consider wrapping the logic in a try-catch:

const interval = setInterval(function () {
  try {
    const isLoaded = Array.from(doc.styleSheets).some(
      sheet => sheet.ownerNode === style
    );
    if (isLoaded) {
      clearInterval(interval);
      resolve();
    } else if (Date.now() > timeoutAt) {
      clearInterval(interval);
      reject(
        new Error(
          'Added <style> element was not reflected in doc.styleSheets within timeout'
        )
      );
    }
  } catch (err) {
    clearInterval(interval);
    reject(
      new Error(
        `Error while polling for stylesheet: ${err.message}`
      )
    );
  }
}, 5);

Copilot uses AI. Check for mistakes.
@dbjorge dbjorge merged commit fde5ef9 into develop Nov 12, 2025
30 checks passed
@dbjorge dbjorge deleted the preload-cssom-test-reliability branch November 12, 2025 23:26
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.

3 participants