Skip to content

Commit

Permalink
Handle timeout when waiting for page readiness (#30)
Browse files Browse the repository at this point in the history
Prior to this commit, if the Promise stored in the binding named
`loaded` rejected while the WebDriver "wait" command was being
evaluated, that rejection would trigger a Node.js global "unhandled
rejection" error and cause the process to crash.

Track all Promise values so that a rejection in any of them at any time
is handled by the caller. Recognize when the expected "load" event has
already occurred and stop waiting immediately.
  • Loading branch information
jugglinmike authored Nov 30, 2023
1 parent 58d7400 commit 891ddbd
Showing 1 changed file with 13 additions and 12 deletions.
25 changes: 13 additions & 12 deletions src/agent/driver-test-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { AgentMessage } from './messages.js';

const AFTER_NAVIGATION_DELAY = 1000;
const AFTER_KEYS_DELAY = 5000;
const AFTER_RUN_TEST_SETUP_BUTTON_DELAY = 5000;
const RUN_TEST_SETUP_BUTTON_TIMEOUT = 1000;

export class DriverTestRunner {
Expand Down Expand Up @@ -58,23 +57,25 @@ export class DriverTestRunner {
await this.webDriver.navigate().to(url.toString());

try {
const loaded = this.webDriver.executeAsyncScript(function (callback) {
new Promise(resolve => {
window.addEventListener('load', () => resolve());
})
// Wait until after any microtasks registered by other 'load' event
// handlers.
.then(() => Promise.resolve())
.then(callback);
await this.webDriver.executeAsyncScript(function (callback) {
if (document.readyState === 'complete') {
callback();
} else {
new Promise(resolve => {
window.addEventListener('load', () => resolve());
})
// Wait until after any microtasks registered by other 'load' event
// handlers.
.then(() => Promise.resolve())
.then(callback);
}
});

const runTestSetup = await this.webDriver.wait(
until.elementLocated(By.className('button-run-test-setup')),
RUN_TEST_SETUP_BUTTON_TIMEOUT
);
// TODO: Replace loaded and timeout race with a deterministic signal that
// the page is ready. This likely needs a change in aria-at's process.
await Promise.race([loaded, timeout(AFTER_RUN_TEST_SETUP_BUTTON_DELAY)]);

await runTestSetup.click();
} catch ({}) {
await this.log(AgentMessage.NO_RUN_TEST_SETUP, { referencePage });
Expand Down

0 comments on commit 891ddbd

Please sign in to comment.