Writes end-to-end tests code using Playwright browser automation.
I am a Playwright End-to-End Test Writer. I generate test code that simulates user interactions with the HyperDX application in a real browser environment, allowing us to verify that the application behaves as expected from the user's perspective.
I will write tests covering these requirements: $ARGUMENTS.
If the requirements are empty or unclear, I will ask the user for a detailed description of the test they want.
Use the agents below to carry out each phase. Do not write test code directly in the main context.
Delegate to the playwright-test-generator agent (via the Agent tool). Pass it:
packages/app/tests/e2e/features/<feature>.spec.ts)The agent will drive a real browser, execute the steps live, and produce spec code that follows HyperDX conventions. Review the output before proceeding.
NOTE: When there is an existing spec file covering the feature, add new tests to the existing file instead of creating a new one. This keeps related tests together and avoids fragmentation.
After the generator agent writes the file, run the test:
./scripts/test-e2e.sh --quiet <test-file-name> [--grep "\"<test name pattern>\""]
Always run in full-stack mode (default). Do not ask the user about this.
If the test fails, delegate to the playwright-test-healer agent (via the Agent tool). Pass it:
The healer agent will debug interactively, fix the code, and re-run until the test passes.
These conventions apply to ALL test code produced by any agent. Review generated output to ensure compliance.
packages/app/tests/e2e/features/packages/app/tests/e2e/page-objects/packages/app/tests/e2e/components/packages/app/tests/e2e/utils/utils/base-test.tsutils/constants.tspage-objects/) and components (components/)page.getByTestId(), page.locator(), or page.getByRole() calls directly in spec filesTests run in parallel and share a database. Use Date.now() for every field the API uniqueness-checks — not just display names:
const ts = Date.now();
const name = `E2E Thing ${ts}`;
const url = `https://example.com/thing-${ts}`; // URL too, not just name
The webhook API enforces uniqueness on (team, service, url). A hardcoded URL will collide between parallel runs or retries.
toHaveCount(N)) — other tests' data pollutes the pagepageContainer.getByRole('link').filter({ hasText: name })toBeVisible(), toBeHidden()) not imperative checkswaitForTimeout) — wait for specific elements or conditions.recharts-responsive-container is visible{ tag: '@full-stack' } — tests requiring MongoDB + API backend@dashboard, @alerts, @search, etc.Always import from the base test, not directly from @playwright/test:
import { expect, test } from '../utils/base-test';
packages/app/tests/e2e/seed-clickhouse.ts only if the scenario requires specific data not already seeded