Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Taiko timeouts when popup is triggered after closing tab #2313

Open
mikkopitkaenen opened this issue Dec 19, 2022 · 3 comments
Open

Taiko timeouts when popup is triggered after closing tab #2313

mikkopitkaenen opened this issue Dec 19, 2022 · 3 comments

Comments

@mikkopitkaenen
Copy link

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
@zabil
Copy link
Member

zabil commented Dec 20, 2022

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();
    }
  })();

@zabil zabil closed this as completed Dec 20, 2022
@mikkopitkaenen
Copy link
Author

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();
    }
  })();

@zabil
Copy link
Member

zabil commented Dec 20, 2022

Thanks for spending time to explain this issue and specify the code samples. Re-opening it

@zabil zabil reopened this Dec 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants