Hydration Proof

Search documentation

Find a page or section

HP5008: A custom interaction failed

HP5008 (interaction-failed) means an interaction from your config threw an error or caused a page error. Run it in a headed browser to see where it fails.

HP5008 (interaction-failed) means one of the custom interactions in your config threw an error, or caused an uncaught error on the page while it ran. Either the steps no longer match the page, or the page breaks when a user does the same thing. Run the interaction in a headed browser to see where it fails.

CodeHP5008
Nameinteraction-failed
Default severityError
GroupInteraction during hydration
What it meansAn interaction from the config threw an error or caused a page error.

What the HP5008 interaction failed finding means

Custom interactions are Playwright steps you add under interactions in the config. Each one runs on the routes it matches, after hydration by default or with the page's scripts held back (when: "before-hydration"). hydration-proof reports the interaction by name:

"continue to payment" failed: locator.click: Timeout 30000ms exceeded.
"continue to payment" caused an error on the page: TypeError: Cannot read properties of undefined (reading 'total')

Uncaught errors count only when they happen after the steps started. The page errors are listed as evidence. It is an error, because either the test or the page is broken.

Likely causes

  • A selector in the steps that no longer matches, after a change to the page.
  • Steps that wait for something the page never shows.
  • A before-hydration interaction that expects React to handle an event: while the scripts are held back, only plain HTML behavior works.
  • A real bug: the page throws when a user does these steps.
  • The page did not hydrate, so the steps never ran; the message says so.

How to fix it

  1. Run the interaction in a headed browser (--headed) to see where it fails; the command is below.
  2. If a step fails, update the locator or the wait in the config. Locators by role or label (getByRole, getByLabel) survive markup changes better than CSS selectors.
  3. If the page throws, fix the page: the finding's evidence has the error.
  4. If a page did not hydrate, look at that page's own findings first, such as HP9001.
npx hydration-proof test --route /checkout --headed --workers 1

A step that finds its elements by label and role:

hydration-proof.config.ts
import { defineConfig } from "hydration-proof";
 
export default defineConfig({
  interactions: [
    {
      route: "/checkout",
      name: "continue to payment",
      steps: async ({ page }) => {
        await page.getByLabel("Email").fill("test@example.com");
        await page.getByRole("button", { name: "Continue" }).click();
        await page.getByText("Payment").waitFor();
      },
    },
  ],
});

Interactions documents every field, including when and scenarios.