10

I am testing UI with Playwright and JavaScript. My code find an input element that can sometimes be a drop down, sometimes a text and sometimes a date. To handle this I enter value with 2 steps. First I fill the text and then click on tab key to invoke the JavaScript that formats the value in the element.

await page.fill("#myID", inputText); 
await page.keyboard.press('Tab');  // this line trigger the JS

// continue to the next element 

The problem, it is not waiting for JavaScript to finish. How can I wait for JS to finish before the code continue.

Jacob
  • 1,135
  • 5
  • 14
  • 29

2 Answers2

10

You could wait for some reaction to your click (some page change, or HTTP request made), for example:

dst
  • 121
  • 2
  • 5
7

Using the page.waitFor... functions

There are a slew of functions that playwright offers for when certain conditions are met that start with page.waitFor (e.g. page.waitForFunction). Probably page.waitForFunction is the most versatile, because you can pass a custom function that waits for a specific condition to be met.

Alternatively, use a timeout

I think you can use setTimeout with page.evaluate inside the page context to wait a bit for other JavaScript to run:

await page.evaluate(() => {
  // if this doesn't work, you can try to increase 0 to a higher number (i.e. 100)
  return new Promise((resolve) => setTimeout(resolve, 0));
});

This might be equivalent to page.waitForTimeout(0), but I'm not sure. Note that they recommend not to use page.waitForTimeout in production.

Steve
  • 10,435
  • 15
  • 21
  • Unfortunately, it is not good in this case. This pattern happens many times and if I use hardcoded value, the script will be very slow. I need to stop waiting when JS is finished. – Jacob Feb 18 '21 at 00:19
  • You can try using a timeout of 0, which may work, depending on how the events bubble, or you can abstract it to function that lets you pass a `timeout` argument. If that doesn't work, it's hard to determine when JS is "finished", without explicitly writing code that says that it is done (for example, if you can edit the client code, you could have a custom function called `doneClientSide()`, that you can check for in playwright). I have a feeling you'll have performance issues in general. – Steve Feb 18 '21 at 00:33
  • I think waitForFunction may help, though it won't be easy. I need to check. Thanks for that! – Jacob Feb 18 '21 at 01:09