Search code examples
svelteplaywright

Playwright not waiting for elements to be visible


I'm trying to write a "hello world" test using Playwright to start testing my Svelte app. The app shows a loading screen for about two seconds, then shows the app itself, which shows some data in a table. I want to simply detect that there is a table on the screen.

To get past the loading screen, I'm using the waitFor() method, but it keeps timing out after about two seconds no matter what I put for the timeout value in the Playwright config. I even put it to 100000ms and it still times out after about two seconds (same amount of time as the loading screen is on the screen). The error that appears is that the 100000ms timeout has been exceeded, which obviously isn't true. I even tried the page.slow() option, but then it just says I've exceeded the 300000ms timeout.

Here's the test I'm trying to get to work. Any help would be hugely appreciated.

test('The table is present after the loading screen disappears', async ({page}) => {
    await page.goto('localhost:3000');
    const tbl = await page.locator('table');
    await tbl.waitFor();
    await expect(tbl.count()).toBeGreaterThan(0);
});

Here's what the relevant part of my playwright.config.ts look like:

export default defineConfig({
  testDir: './e2e',
  /* Maximum time one test can run for. */
  timeout: 100 * 1000,
  expect: {
    /**
     * Maximum time expect() should wait for the condition to be met.
     * For example in `await expect(locator).toHaveText();`
     */
    timeout: 500000000
  },

Here's the error: enter image description here


Solution

  • Hard to tell, why your script isn't working, without really debugging it. I recommend running npx playwright test --debug or the VS Code extension to have a detailed look.

    Side note: as @AJG pointed out, locators are lazy and don't need to be awaited. They're only evaluated when you're using them with e.g. expect.

    That said, for the use case of an element being visible, you should rely on Playwright's web-first assertions.

    Playwright has auto-waiting built-in so that you can usually avoid manual waitFor statements. E.g. await expect(locator).toBeVisible() waits and retries until the condition is met (or it times out).

    For your case (and assuming that there's only one table on the page), the following should do the trick:

    test('The table is present after the loading screen disappears', async ({page}) => {
        // wait for the 'load' event
        // which probably doesn't help in your case
        await page.goto('localhost:3000');
        const tbl = page.locator('table');
        // waits until `tbl` becomes visible
        // timeout in your case is `500000000`
        await expect(tbl).toBeVisible();
    });