DevExpress / testcafe-react-selectors

TestCafe selector extensions for React apps.
https://testcafe.io
MIT License
205 stars 43 forks source link

Tests sometimes executes before onclick eventhandlers are available #192

Closed oyvindwe closed 1 year ago

oyvindwe commented 1 year ago

We have a complex React webapp (built with React 18.1.0) where we have some flaky tests that sometimes fails when clicking buttons. The screenshots from the failed tests show an outline around the button, identical to the outline you get by navigating to the button using the tab key, and debugging has shown that the onclick event handler is not fired in these cases. The tests fails in the next step, e.g. when trying to click in a submenu or modal dialog that should have been opened by the initial click.

One of the places this occurs most frequently is on a specific top menu after calling navigateTo in this test, as this test uses a different page than set in the fixture's beforeEach handler. The test is as follows:

fixture("Data explorer page")
  .page(`${process.env.TEST_HOST}/data/explore/time-series`)
  .beforeEach(t => t.useRole(testUser));

test("Show data explorer", async t => {
  // Can navigate to page via global menu
  await t.navigateTo(process.env.TEST_HOST);
  await waitForReact();
  await t
    .click(Selector("[data-test-headermenu-data]"))           // <-- this action sometimes triggers before onclick is registered
    .click(Selector("[data-test-data-submenu-dataexplorer]")) // <-- causing this action to fail

This is consistently reproduced (given enough runs, sometimes > 100) with browser chrome:headless on macOS and Linux, but has not (yet) failed on Windows or in regular mode.

If we drop t.navigateTo and waitForReact, the tests always succeeds, even without waitForReact in the fixture.

Unfortunately the webapp isn't publicly available. We could try to make a repro with a simpler webapp, but I suspect that a part of the cause for the problem is that it is a complex webapp that takes a little time of processing time for the browser to render.

felis2803 commented 1 year ago

Without an example, we cannot understand what went wrong. However, there are two workarounds that will most likely work:

  1. Add a call to await t.wait(delay_in_milliseconds) before the click.
  2. Call a client function that will pause the test execution until the handler is set.
oyvindwe commented 1 year ago

Adding t.wait(100) seems to work around the issue. If this becomes more critical for us, we'll work on a repro.