gauge
gauge copied to clipboard
Taiko timeouts when popup is triggered after closing tab
Describe the bug Throws an error "There is no handler registered..." when confirm/prompt is triggered after a new tab is closed. Happens only in headless mode.
To Reproduce
(async () => {
try {
await openBrowser({ headless: true });
await goto('https://google.com');
await openTab();
await waitFor(500);
await closeTab();
confirm('testing confirm', () => accept('OK'));
await evaluate(() => confirm('testing confirm'));
} catch (error) {
console.error('error', error);
} finally {
await closeBrowser();
}
})();
Logs
✔ Browser opened
> ✔ Navigated to URL https://google.com
> ✔ Opened tab with URL about:blank
> ✔ Closed current tab matching about:blank
> Uncaught:
There is no handler registered for confirm popup displayed on the page https://www.google.com/.
This might interfere with your test flow. You can use Taiko's confirm API to handle this popup.
Please visit https://docs.taiko.dev/#confirm for more details
Expected behavior Should not throw an error
Versions:
- Taiko: Version: 1.3.5 (Chromium: 104.0.5109.0) RELEASE
- Ubuntu 22.04.1 LTS jammy
- Node.js: v18.10.0
This is mentioned in the docs https://docs.taiko.dev/api/confirm/
Under
// Note: Taiko's `confirm` listener has to be setup before the confirm
// popup displays on the page. For example, if clicking on a button
// shows the confirm popup, the Taiko script is
Happy to re-open this issue if it this still happens after modifying the script to
(async () => {
try {
await openBrowser({ headless: true });
await goto('https://google.com');
confirm('testing confirm', () => accept('OK'));
await evaluate(() => confirm('testing confirm'));
await openTab();
await waitFor(500);
await closeTab();
} catch (error) {
console.error('error', error);
} finally {
await closeBrowser();
}
})();
Thank you for your reply.
I think my issue description was a bit too simplified. Let me explain the use case a bit more in detail.
Some background information. We are using gauge to run taiko. When running in gauge, the code doesn't time out, mostly the code completes successfully. It just throws lots of these unhandled popup errors in the logs. But every now and then the run gets stuck and timeouts. Having hundreds of these unconfirmed popup handler error messages in gauge logs could have something to do with the occasional timeout. To simplify the issue report, when running the same directly in Taiko, it times out.
The code example is about boxes. A great deal of our tests is follows the logic: We create a box, we do one or more tests on it, and at the end we delete the box. Everything goes fine if the tests run in the same tab. But the issue occurs when there is a link that opens in new tab. Or to be more specific, after closing the tab and triggering a popup.
We would like to build the tests like this:
Gauge steps
* Create box (has confirmation popup for box creation)
* Test stuff
* Delete box (has confirmation popup for box deletion)
We cannot have this structure if there is a test that contains a popup. Throws the unhandled popup error
Gauge steps
* Create box (has confirmation popup for box creation)
* Tests in a new tab
* Delete box (has confirmation popup for box deletion)
(Ref code snippet Problem case 1)
As you presented, we could include the confirm handler for deletion in advance. In our use case it would mean that step("Create box") would include creation and deletion popup handlers
Gauge steps
* Create box (has confirmation popup for box creation and deletion)
* Tests in a new tab
* Delete box
(Ref code snippet Problem case 2) Taiko will throw an error nevertheless where it is located. We have tests that include opening of links in new tab multiple times in one test, In context of gauge, an unhandled error is thrown for each opened/closed tab and for each confirm/prompt popup that is triggered after tab closing interactions.
Back to the original snippet. If I copied your answer and added a new "test" that triggers a popup after the closeTab, then the problem occurs. The tricky thing is that it doesnt happen every time. I ran the snippet below 10 times, of which it failed 6 times
(async () => {
try {
await openBrowser({ headless: true });
await goto('https://google.com');
confirm('testing confirm', () => accept('OK'));
await evaluate(() => confirm('testing confirm'));
await openTab();
await waitFor(500);
await closeTab();
confirm('testing confirm after closeTab', () => accept('OK'));
await evaluate(() => confirm('testing confirm after closeTab'));
} catch (error) {
console.error('error', error);
} finally {
await closeBrowser();
}
})();
Code references:
<!DOCTYPE html>
<html>
<head>
<title>Issue description</title>
</head>
<input type = "button" value="Create box" onclick = "confirm('Create box?')"><br>
<input type = "button" value="Delete box" onclick = "confirm('Delete box?')"><br>
<a href="https://google.com" target="_blank">Sub page that opens in new tab</a>
</body>
</html>
Problem case 1:
const beforeSuite = async () => {
await openBrowser({ headless: true });
await goto('http://127.0.0.1:8080/');
};
const createBox = async () => {
confirm('Create box?', () => accept('OK'));
await click('Create box');
};
const deleteBox = async () => {
confirm('Delete box?', () => accept('OK'));
await click('Delete box');
};
const testsInNewTab = async () => {
await click('Sub page that opens in new tab');
await waitFor(500);
await closeTab();
};
(async () => {
try {
await beforeSuite();
await createBox();
await testsInNewTab();
await deleteBox();
} catch (error) {
console.error('error', error);
} finally {
await closeBrowser();
}
})();
Problem case 2:
const beforeSuite = async () => {
await openBrowser({ headless: true });
await goto('http://127.0.0.1:8080/');
};
const createBox = async () => {
confirm('Create box?', () => accept('OK'));
confirm('Delete box?', () => accept('OK')); //Moving the handler here will still fail
await click('Create box');
};
const deleteBox = async () => {
await click('Delete box');
};
const testsInNewTab = async () => {
await click('Sub page that opens in new tab');
await waitFor(500);
await closeTab();
};
(async () => {
try {
await beforeSuite();
await createBox();
await testsInNewTab();
await deleteBox();
} catch (error) {
console.error('error', error);
} finally {
await closeBrowser();
}
})();
Thanks for spending time to explain this issue and specify the code samples. Re-opening it