AGENTS.md
e2e-playwright/alerting-suite/AGENTS.mdAGENTS.md
Quality
81/100
Scores the file, not the repository.Length
886 words
13 headings · 2 code blocksRepository
76k
— · pushed 0 days agoLast changed
3 days ago
First indexed 3 days ago.1# Alerting e2e tests — agent guide23This guide documents conventions for Playwright e2e tests under4`e2e-playwright/alerting-suite/`. Follow it when adding or modifying specs in this5directory.67## Test isolation and parallelism89Playwright's global config sets `fullyParallel: true`, which distributes individual10tests (not just files) across workers. The implications:1112- `beforeAll` / `afterAll` run **once per worker**, not once per file. With shared13 module-scoped state, every worker that picks up a test runs its own setup, creating14 duplicate resources (and resulting in strict-mode locator violations or 409s).15- Prefer `beforeEach` / `afterEach`. Each test owns its own resources, no shared16 module-scoped state to reason about, and parallel workers can't collide.17- Reach for `test.describe.configure({ mode: 'serial' })` only when shared state is18 unavoidable. It pins all tests in the file to a single worker, sacrificing19 parallelism for setup-cost reuse.2021## Unique resource names2223When the test creates server-side resources (folders, groups, rules), the name needs24to be unique **per invocation** — not per test definition.2526- Use `crypto.randomUUID().slice(0, 8)` (or similar) generated inside `beforeEach`.27 Each run produces a fresh name; parallel workers can't collide; orphans from a28 crashed previous run don't accumulate under the same title.29- Do **not** use `testInfo.testId` — it's stable across runs, so the same orphaned30 name keeps reappearing. Same applies to fixed names or `Date.now()` at module31 scope.32- Do **not** add pre-create cleanup loops to compensate for stable names. That's a33 workaround for using the wrong identifier.3435## Cleanup via cascade3637Each test owns one folder, created in `beforeEach`. Everything the test seeds lives38inside that folder. The `afterEach` deletes the folder with39`?forceDeleteRules=true`, which cascade-deletes all rule groups, rules, and seeded40data within.4142- Don't add per-resource cleanup hooks when the parent folder cascade covers it.43- The k8s `alertrule` API stores the folder reference under44 `metadata.annotations['grafana.app/folder']` — those rules are also caught by45 the folder cascade.46- One DELETE call per test is faster and partial-failure-safe vs. per-group47 cleanup.4849## Realistic test data5051Use names that look like real alerting entities. Examples in this suite:5253- Folders: `Infrastructure alerts <suffix>`54- Groups: `disk-alerts`, `infra-monitoring`, `platform-alerts`55- Rules: `High CPU usage`, `Disk space low`, `Memory pressure`, `Node load average`56- Seeded placeholders: `Node disk read latency`, `Pod restart rate`, `HTTP error rate`5758Avoid `E2E ...`, `e2e-seed-...`, or other test-betraying prefixes — they bleed into59the UI, the API, and any screenshots/traces, making the test data look fake even60when it covers real flows.6162## Page Object Models (POMs)6364Encapsulate UI interactions in class-based POMs under `pages/`. The existing65`AlertRuleEditPage` and `AlertRuleViewPage` demonstrate the pattern. Add new POMs66for new pages or for substantial subviews; do not inline complex locator logic in67specs.6869### Structure7071- One class per page or distinct view (`AlertRuleEditPage`, `AlertRuleViewPage`,72 `ContactPointsPage`, `SilencesListPage`, …).73- Constructor takes the Playwright `Page` and stashes it as a private field.74- High-level actions are public async methods that describe user intent75 (`setEvaluationInterval`, `useExistingGroup`, `setManualRouting`) — not raw76 click/fill operations.77- Locators that tests assert against (e.g. `nameHeading`, `evaluationIntervalText`)78 are public getters returning `Locator`. Locators that are only used internally79 are `protected` or `private`.8081### Locator strategy8283- Prefer accessibility queries: `getByRole`, `getByLabel`, `getByText`.84- Reach for `getByTestId` only when the component has no stable accessible name.85 If you find yourself adding a testid, consider whether the underlying component86 should expose an accessible name instead.87- When a label double-matches because of `<Field>` description-bleed, target the88 input by id or use a more specific role query rather than papering over it with89 `.first()`.90- For tree/list items that can appear in multiple sections (breadcrumbs vs.91 sidebar vs. metadata strip), scope the query (`getByRole('group', { name })`92 then drill in).9394### Documentation9596- Comment non-obvious locator choices inline — particularly when you've worked97 around a UI quirk (e.g. label double-match, dropdown race, hidden-when-flag-off98 inputs). Skip JSDoc for self-explanatory methods/getters; the comments should99 earn their place by explaining _why_ a selector looks the way it does.100101## Authentication102103All tests use the `request` and `page` fixtures from `@grafana/plugin-e2e`. Auth104is wired up at the project level in `playwright.config.ts` via `withAuth(...)`,105which adds the `authenticate` setup project as a dependency and points the test at106a saved storage state file.107108**Gotcha:** Playwright applies CLI file filters to dependency projects too. So109`yarn e2e:pw --project=alerting e2e-playwright/alerting-suite/foo.spec.ts` will110also filter the `authenticate` project's `auth.setup.js`, find no matches, and111skip generating the storage state — every API call then 403s.112113Workarounds:1141151. Run the setup project explicitly first:116```sh117 yarn e2e:pw --project=authenticate118 yarn e2e:pw --project=alerting --reporter=line e2e-playwright/alerting-suite/foo.spec.ts119```1202. Use `--grep` instead of a file path — title filters don't break dependency121 projects:122```sh123 yarn e2e:pw --project=alerting --reporter=line --grep "your test title"124```125126## SQLite / dev-env caveats127128The e2e Grafana instance uses SQLite with a small `max_open_conn` cap129(`scripts/grafana-server/custom.ini`). Under sustained parallel writes you'll130see flakes like `SQLITE_BUSY`, `sqlstore.max-retries-reached`, or 403s from131request handlers giving up. If the test logic looks correct, suspect the132connection pool before suspecting the test.133134## File organization135136Top-down: imports, config, shared state, hooks, `test.describe` blocks, then137helpers at the bottom. TypeScript hoists function declarations, so helpers can138be referenced from earlier test bodies.139140## Spec authoring141142Title tests by behavior, not mechanics. Push complex locator/action logic into143POM methods. Assert visible outcomes (rendered values, breadcrumbs, errors),144not internal state.145
Also in grafana/grafana
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| grafana/grafanaAGENTS.md · 76k | AGENTS.md | setupbuildtestlint-format+6 | 89/100 | 3 days ago | |
| grafana/grafanae2e-playwright/dashboard-new-layouts/AGENTS.md · 76k | AGENTS.md | teststyletesting-strategydatabase+1 | 62/100 | today | |
| grafana/grafanae2e-playwright/plugin-e2e/plugin-e2e-api-tests/AGENTS.md · 76k | AGENTS.md | teststyletesting-strategygit+4 | 70/100 | 3 days ago | |
| grafana/grafanapackages/grafana-ui/AGENTS.md · 76k | AGENTS.md | uiagent-behaviour | 16/100 | 3 days ago | |
| grafana/grafanapkg/storage/unified/AGENTS.md · 76k | AGENTS.md | do-not | 46/100 | 3 days ago | |
| grafana/grafanapublic/app/core/journeys/AGENTS.md · 76k | AGENTS.md | testtesting-strategygitagent-behaviour | 73/100 | 3 days ago | |
| grafana/grafanapublic/app/features/AGENTS.md · 76k | AGENTS.md | agent-behaviour | 16/100 | 3 days ago | |
| grafana/grafanapublic/app/features/alerting/unified/AGENTS.md · 76k | AGENTS.md | setuptestlint-formatstyle+11 | 76/100 | 3 days ago | |
| grafana/grafanapublic/app/features/expressions/components/SqlExpressions/SqlEditor/AGENTS.md · 76k | AGENTS.md | styleagent-behaviour | 43/100 | 3 days ago | |
| grafana/grafanapublic/app/plugins/panel/AGENTS.md · 76k | AGENTS.md | agent-behaviour | 16/100 | 3 days ago |
Diff against AGENTS.md Diff against e2e-playwright/dashboard-new-layouts/AGENTS.md Diff against e2e-playwright/plugin-e2e/plugin-e2e-api-tests/AGENTS.md Diff against packages/grafana-ui/AGENTS.md Diff against pkg/storage/unified/AGENTS.md Diff against public/app/core/journeys/AGENTS.md Diff against public/app/features/AGENTS.md Diff against public/app/features/alerting/unified/AGENTS.md Diff against public/app/features/expressions/components/SqlExpressions/SqlEditor/AGENTS.md Diff against public/app/plugins/panel/AGENTS.md
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | 3 days ago | |
| aaif-goose/gooseAGENTS.md · 52k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 3 days ago | |
| SkeneTechnologies/skene-cookbookAGENTS.md · 51 | AGENTS.md | setupbuildtestlint-format+7 | 100/100 | 2 days ago | |
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 199k | AGENTS.md | buildteststylearch+3 | 100/100 | 3 days ago | |
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 3 days ago | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 3 days ago | |
| trick77/agents-md-syncAGENTS.md · 2 | AGENTS.md | setupbuildteststyle+5 | 100/100 | 3 days ago | |
| code-yeongyu/oh-my-openagentpackages/web/AGENTS.md · 67k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 2 days ago |
