6

How to Make Playwright Wait for Hydration in SvelteKit Tests

 11 months ago
source link: https://spin.atomicobject.com/2023/07/19/hydration-sveltekit-tests/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

We’re using SvelteKit on my current software development project, along with Playwright for end-to-end browser testing. Some tests would intermittently fail – so I spent some time investigating.

The Issue

The problem arose on pages where text was being entered into a form. Playwright starts filling out the form as soon as the page is loaded in the browser (coming back from SSR). However, when the page is hydrated moments later, the text in the form is cleared out!

Although Playwright is able to start entering data into a form much faster than a human could, it’s not out of the question that something might get delayed, causing a human user to experience the same issue. So it seems this might be a bug but perhaps one with such a low chance of occurrence that it’s not really an issue. The only mention I’ve been able to find of this is related to automated test frameworks.

The Workaround

After some searching, I found a workaround mentioned in a GitHub issue. The first step is to use an onMount callback that adds a class to the body tag. This will be executed during hydration. The following code snippet can be added to the layout.svelte file so it will be run regardless of the page that’s first loaded by the browser.

TypeScript
  onMount(() => {
    // Indicate that the SvelteKit app has started
    document.body.classList.add("started");
  });

We now have a way of knowing when the page has been hydrated. The next step is to wait for the started class to be added to the body when doing initial page navigation in the tests.

In the SvelteKit project tests, this has been done by enhancing the Playwright navigation helpers. I chose to go a different route. Instead, I added a goto helper to my TestUtils module:

TypeScript
  const goto = async (page: Page, url: string, opts?: { waitForStarted?: boolean }) => {
    await page.goto(url);
    if (opts?.waitForStarted !== false) {
      await page.waitForSelector("body.started", { timeout: 5000 });
    }
  };

Hydration Problem Solved

Now, when making an initial page navigation, I use TestUtils.goto('/'), and I know that Playwright won’t start entering text into form fields until after hydration has completed. Problem solved!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK