Skip to content

test(alerts): add e2e for alerts - #12349

Open
H4ad wants to merge 19 commits into
mainfrom
feat/alert-e2e
Open

test(alerts): add e2e for alerts#12349
H4ad wants to merge 19 commits into
mainfrom
feat/alert-e2e

Conversation

@H4ad

@H4ad H4ad commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Pull Request


📄 Summary

Why does this change exist?
What problem does it solve, and why is this the right approach?

This adds a bunch of E2E tests for alerts, to test v1/v2 create and edit, and also tests for alert history.

This started as tests only for history but decided to just add tests for everything, while creating them, I found two bugs inside alerts, so they already helping us before even landing :)

The changes in the UI are only to add testIds, no change in logic (and no fix for the incidents)

Scope Before (main) After (this branch) Delta
Alerts E2E tests 2 191 +189
Alerts E2E spec files 1 31 +30
Whole E2E suite 141 330 +189

Alerts page shell (7)

File Test Status
page.spec.ts AL-01 all four top-level tabs render
page.spec.ts AL-02 default tab is Alert Rules
page.spec.ts AL-03 tab switch writes ?tab= and clears subTab
page.spec.ts AL-04 Configuration deep-link
page.spec.ts AL-05 Triggered Alerts tab smoke
page.spec.ts AL-06 Notification Channels tab smoke
page.spec.ts AL-07 tab state survives reload

Alert rules list (19)

File Test Status
list/columns.spec.ts LR-01 renders all default columns (Status, Alert Name, Severity, Labels, Actions)
list/columns.spec.ts LR-02 shows empty state when no rules exist skipped
list/columns.spec.ts LR-10 column selector hides and shows a column
list/navigation.spec.ts LR-11 row click opens the overview page
list/navigation.spec.ts LR-12 ctrl/cmd-click opens the overview in a new tab
list/navigation.spec.ts LR-13 actions menu Edit and Edit in New Tab navigate correctly
list/navigation.spec.ts LR-17 New Alert button navigates to alert creation
list/navigation.spec.ts LR-18 shows ErrorEmptyState when list fails to load skipped
list/pagination-sort.spec.ts LR-07 navigates between pages
list/pagination-sort.spec.ts LR-08 changes page size
list/pagination-sort.spec.ts LR-09 sorts by column header click
list/row-actions.spec.ts LR-14 Disable then Enable toggles the rule state
list/row-actions.spec.ts LR-15 Clone creates a copy and shows success toast
list/row-actions.spec.ts LR-16 Delete removes the rule and shows success toast
list/search.spec.ts LR-03 filters by name
list/search.spec.ts LR-04 filters by severity and by label
list/search.spec.ts LR-05 shows no-results state with clear button
list/search.spec.ts LR-06 resets pagination when searching
list/search.spec.ts LR-19 state and severity filters intersect, they do not union

Create alert (52)

File Test Status
create/edge.spec.ts CE-04 a server-side rejection opens the error modal and keeps the draft
create/edge.spec.ts CE-07 none of the four builder mounts logs a console error
create/edge.spec.ts CE-09 the v2 Discard button is clickable skipped
create/prefill.spec.ts CD-01 a compositeQuery alone selects the alert type
create/prefill.spec.ts CD-02 thresholds prefill from JSON, and a malformed value falls back
create/prefill.spec.ts CD-03 matchType and compareOp aliases normalise to the enum
create/prefill.spec.ts CD-04 ruleName and yAxisUnit apply once and never stomp an edit
create/prefill.spec.ts CD-05 evaluationWindowPreset=meter switches to the cumulative daily window
create/prefill.spec.ts CD-06 URL prefill is ignored in edit mode
create/shell.spec.ts CS-01 bare /alerts/new lists exactly the expected alert-type cards
create/shell.spec.ts CS-02 picking a card writes both params and mounts the v2 builder
create/shell.spec.ts CS-03 the anomaly card rewrites the rule type, not the alert type conditional
create/shell.spec.ts CS-04 modifier-clicking a card opens the builder in a new tab
create/shell.spec.ts CS-05 breadcrumb gains a third crumb after a type is picked
create/shell.spec.ts CS-06 create renders inside the Alert Rules tab and leaving drops subTab/search
create/shell.spec.ts CS-07 showClassicCreateAlertsPage=true renders the v1 form instead
create/shell.spec.ts CS-08 Switch to Classic Experience replaces history, so Back does not return to v2
create/v1.spec.ts CV1-01 the classic form renders its steps and the create-mode labels
create/v1.spec.ts CV1-02 the rendered severity is the default from the rule, not the select
create/v1.spec.ts CV1-03 one keystroke in the name field is enough to enable Save
create/v1.spec.ts CV1-04 Save stays disabled until the channel configuration resolves
create/v1.spec.ts CV1-05 broadcast-to-all saves the rule with the broadcast flag skipped
create/v1.spec.ts CV1-06 a cleared threshold is coerced to 0, so the required-threshold branch is dead
create/v1.spec.ts CV1-07 cancelling the confirm dialog does not save
create/v1.spec.ts CV1-08 the happy path posts the v1 body shape to the shared endpoint
create/v1.spec.ts CV1-09 CV1-10 description, labels and severity all land in the payload
create/v1.spec.ts CV1-11 test notification skips the dialog and reports no matching data
create/v1.spec.ts CV1-12 with no channels the form is a dead end
create/v1.spec.ts CV1-13 Cancel leaves the form without saving
create/v1.spec.ts CE-05 an empty PromQL expression is rejected behind the dialog
create/v1.spec.ts CE-06 an empty ClickHouse query is rejected behind the dialog
create/v1.spec.ts CV1-14 the condition sentence keeps its selections
create/v2.spec.ts CV2-01 initial state: one critical threshold, both actions gated
create/v2.spec.ts CV2-02 the save tooltip walks from the name gate to the channel gate
create/v2.spec.ts CV2-03 clearing a threshold label re-gates the save
create/v2.spec.ts CV2-04 a label added in the header survives the save round-trip
create/v2.spec.ts CV2-05 a rejected label key surfaces as a notification, not an inline message
create/v2.spec.ts CV2-06 CV2-07 the operator and match-type selects offer the documented options
create/v2.spec.ts CV2-08 the operator is rule-wide: one change reaches every threshold
create/v2.spec.ts CV2-09 CV2-10 added thresholds take preset tiers, and the first cannot be removed
create/v2.spec.ts CV2-11 a channel on one threshold is not enough — the validator loops all of them
create/v2.spec.ts CV2-12 the unit select is disabled while the query has no y-axis unit
create/v2.spec.ts CV2-13 the recovery threshold control is never rendered
create/v2.spec.ts CV2-14 CV2-15 the evaluation window and cadence reach the payload
create/v2.spec.ts CV2-18 with no channels the dropdown offers only a way to create one
create/v2.spec.ts CV2-19 routing policies unlock the save with zero channels
create/v2.spec.ts CV2-16 the group-by select is disabled until the query groups by something
create/v2.spec.ts CV2-17 repeat notifications enable their inputs and reach the payload
create/v2.spec.ts CV2-20 happy-path save posts the v2 shape and lands on the list
create/v2.spec.ts CV2-21 test notification reports that a non-firing rule matched nothing
create/v2.spec.ts CV2-22 discard leaves without posting and resets the form
create/v2.spec.ts CV2-23 every footer button is disabled while the save is in flight

Edit alert (22)

File Test Status
edit/edge.spec.ts CE-03 an unknown ruleId shows AlertNotFound on both entry URLs
edit/edge.spec.ts CE-03b /alerts/edit with no ruleId also lands on AlertNotFound
edit/v1.spec.ts EV1-01 the classic form renders in edit mode inside the details shell
edit/v1.spec.ts EV1-02 every seeded field prefills the form
edit/v1.spec.ts EV1-03 preferredChannels decide which channel control is prefilled
edit/v1.spec.ts EV1-04 the happy-path update PUTs the v1 body and keeps unrelated params
edit/v1.spec.ts EV1-05 Discard leaves without a PUT and without changing the rule
edit/v1.spec.ts EV1-06 the header title and the form name field agree
edit/v1.spec.ts EV1-07 /alerts/edit redirects for a v1 rule exactly as it does for v2
edit/v1.spec.ts EV1-08 editing a v1 rule never migrates it to the v2 schema
edit/v2.spec.ts EV2-01 the v2 editor renders inside the details shell
edit/v2.spec.ts EV2-02 name and labels prefill from the rule
edit/v2.spec.ts EV2-03 both thresholds prefill, and the sentence reads spec[0]
edit/v2.spec.ts EV2-04 the recovery threshold control never renders
edit/v2.spec.ts EV2-05 the evaluation window prefills, and a non-preset value collapses to custom
edit/v2.spec.ts EV2-06 repeat notifications prefill from the seeded renotify block
edit/v2.spec.ts EV2-07 alertOnAbsent prefills the advanced options
edit/v2.spec.ts EV2-08 the evaluation cadence always reads back in default mode
edit/v2.spec.ts EV2-09 changing a threshold PUTs the rule and the change survives a reload
edit/v2.spec.ts EV2-10 the footer save is what persists a rename made on the Overview tab
edit/v2.spec.ts EV2-11 Discard leaves without a PUT and without touching the rule
edit/v2.spec.ts EV2-12 /alerts/edit is a legacy alias that redirects into the details shell

Alert details (15)

File Test Status
details/actions.spec.ts AD-06 enable/disable toggle changes the rule state
details/actions.spec.ts AD-07 Duplicate creates a copy and navigates to overview
details/actions.spec.ts AD-08 Delete removes the rule and returns to the list
details/chrome.spec.ts AD-09 copy-link button copies the current URL to clipboard conditional
details/chrome.spec.ts AD-10 breadcrumb navigates back to the alert list
details/chrome.spec.ts AD-13 document title updates to show the rule name
details/header.spec.ts AD-01 v2 header shows editable name input without Rename menu item
details/header.spec.ts AD-02 v1 header shows static title with state, severity and labels
details/not-found.spec.ts AD-11 invalid ruleId shows AlertNotFound page
details/not-found.spec.ts AD-12 missing ruleId on overview shows AlertNotFound page
details/rename.spec.ts AD-03 v1 rename via modal updates the rule name
details/rename.spec.ts AD-04 v2 inline rename saves via Overview footer button
details/tabs.spec.ts AD-05 Overview/History tabs preserve ruleId and relativeTime
details/tabs.spec.ts AD-05b switching to History tab discards other history params
details/threshold-persistence.spec.ts TC-02 edit page displays the saved threshold value

Alert history (75)

File Test Status
history/cross-cutting.spec.ts AX-01 full deep-link with all params is honoured in one load
history/cross-cutting.spec.ts AX-02 page reload preserves all history params
history/cross-cutting.spec.ts AX-03 browser back/forward restores correct table state
history/cross-cutting.spec.ts AX-04 no unhandled console errors across full history session
history/cross-cutting.spec.ts AX-05 no request storm on mount (exactly one call per endpoint)
history/cross-cutting.spec.ts AX-06 v1 and v2 schema rules both render history correctly
history/cross-cutting.spec.ts AX-07 no legacy v1 history API calls during full session
history/cross-cutting.spec.ts AX-08 history API endpoints carry expected params
history/empty-and-errors.spec.ts AE-01 invalid filter expression shows syntax error and recovers on fix
history/empty-and-errors.spec.ts AE-02 empty filter_keys response still mounts editor (no suggestions)
history/empty-and-errors.spec.ts AE-02b bogus ruleId never reaches history APIs (shows AlertNotFound)
history/empty-and-errors.spec.ts AE-03 rule with no history renders empty state (not error)
history/empty-and-errors.spec.ts AE-04 time range with no data renders empty state
history/empty-and-errors.spec.ts AE-05 time-range change resets pagination to first page
history/empty-and-errors.spec.ts AE-06 absurd time range (90d) still renders
history/empty-and-errors.spec.ts AE-07 disabled rule history is still readable
history/empty-and-errors.spec.ts AE-08 deleted rule shows AlertNotFound on revisit
history/expression-filter.spec.ts AF-06 key suggestions load on page load
history/expression-filter.spec.ts AF-07 value suggestions fetch from filter_values endpoint
history/expression-filter.spec.ts AF-08 value suggestions filter client-side as user types
history/expression-filter.spec.ts AF-09 running equality expression filters the table
history/expression-filter.spec.ts AF-10 running expression resets pagination to first page
history/expression-filter.spec.ts AF-11 Run button re-fetches unchanged expression
history/expression-filter.spec.ts AF-12 in-flight query can be cancelled
history/expression-filter.spec.ts AF-13 threshold.name and severity keys filter correctly
history/expression-filter.spec.ts AF-14 unknown key returns 200 with zero rows (not 500)
history/expression-filter.spec.ts AF-15 expression is lost on Overview→History round-trip (known bug)
history/expression-filter.spec.ts AF-16 expression and state filter compose in request
history/expression-filter.spec.ts AF-17 clearing expression restores full unfiltered list
history/state-filter.spec.ts AF-01 All filter sends no state param in request
history/state-filter.spec.ts AF-02 Fired filter sends state=firing in request
history/state-filter.spec.ts AF-03 Resolved filter shows empty for rule with no resolutions
history/state-filter.spec.ts AF-03b Resolved filter shows rows for rule with resolutions
history/state-filter.spec.ts AF-04 deep-link ?timelineFilter=FIRED starts on Fired tab
history/state-filter.spec.ts AF-05 changing state filter resets pagination to first page
history/statistics.spec.ts AS-01 Total Triggered card shows the firing count
history/statistics.spec.ts AS-02 Avg. Resolution Time card shows "No Resolutions." when none exist
history/statistics.spec.ts AS-03 empty stats card never renders a sparkline
history/statistics.spec.ts AS-03b sparkline present with a multi-point series skipped
history/statistics.spec.ts AS-04 change-vs-past indicator shows "no previous data" when unavailable
history/statistics.spec.ts AS-09 stats update when time range changes
history/statistics.spec.ts AS-11 Avg. Resolution Time shows formatted duration when resolutions exist
history/statistics.spec.ts AS-12 Total Triggered counts only firing rows (not resolved)
history/timeline-graph.spec.ts AT-03 renders canvas with two segments (inactive→firing)
history/timeline-graph.spec.ts AT-03b renders canvas with three segments (inactive→firing→inactive)
history/timeline-graph.spec.ts AT-19 handles nodata state without console errors
history/timeline-pagination.spec.ts AT-06 next page sends cursor and shows different rows
history/timeline-pagination.spec.ts AT-07 prev page drops the cursor from request
history/timeline-pagination.spec.ts AT-08 pagination buttons disable at first and last page
history/timeline-pagination.spec.ts AT-09 browser back after paging returns to previous page
history/timeline-pagination.spec.ts AT-10 deep-link ?page=2 loads second page directly
history/timeline-pagination.spec.ts AT-11 default sort order is ascending
history/timeline-pagination.spec.ts AT-12 sorting toggles order and resets to first page
history/timeline-pagination.spec.ts AT-13 single page disables both pagination buttons
history/timeline-pagination.spec.ts AT-21 all pages together cover the complete row set
history/timeline-table.spec.ts AT-01 timeline section renders all chrome elements
history/timeline-table.spec.ts AT-02 Top 5 Contributors tab is disabled with Coming Soon indicator
history/timeline-table.spec.ts AT-04 table rows display state, labels and formatted timestamp
history/timeline-table.spec.ts AT-05 footer shows correct row range
history/timeline-table.spec.ts AT-14 row click does not navigate away
history/timeline-table.spec.ts AT-15 row actions link navigates to logs explorer
history/timeline-table.spec.ts AT-15b row actions link navigates to traces explorer
history/timeline-table.spec.ts AT-16 metrics rule rows show disabled action (no related links)
history/timeline-table.spec.ts AT-17 CREATED AT column respects app timezone setting
history/timeline-table.spec.ts AT-18 state cell renders Firing, Resolved, and No Data correctly
history/timeline-table.spec.ts AT-18b pending/recovering states render blank (coverage gap) skipped
history/timeline-table.spec.ts AT-18c disabled state renders as "Muted" (coverage gap) skipped
history/timeline-table.spec.ts AT-20 time-range boundaries inclusive/exclusive (coverage gap) skipped
history/top-contributors.spec.ts AS-05 card displays max 3 rows with count ratios
history/top-contributors.spec.ts AS-13 contributor bar width is the count as a percentage of the total
history/top-contributors.spec.ts AS-06 "View all" button only appears when more than 3 contributors
history/top-contributors.spec.ts AS-07 View-all drawer shows paginated list of all contributors
history/top-contributors.spec.ts AS-07b drawer opens from deep link with ?viewAllTopContributors=true
history/top-contributors.spec.ts AS-08 View-all click adds ?viewAllTopContributors=true to URL
history/top-contributors.spec.ts AS-10 contributor rows show related-logs link for logs-based rules

Notification channels (1)

File Test Status
channels/edit.spec.ts NC-01 an edited recipient persists after reload

Skipped tests

Test File Kind Reason
the v2 Discard button is clickable create/edge.spec.ts hard test.skip( Real bug: the button is not clickable. Test written, left ready to flip.
broadcast-to-all saves the rule with the broadcast flag create/v1.spec.ts hard test.skip( Real bug: the broadcast flag is not persisted.
sparkline present with a multi-point series history/statistics.spec.ts test.skip(true) Flaky by construction: the sparkline only renders with more than one data point, and whether the seeded ~2-minute window lands in one stats bucket or two depends on where it falls relative to the bucket boundary.
pending/recovering states render blank history/timeline-table.spec.ts test.skip(true) Unreachable: pending and recovering are transient states, and no fixture can reliably catch a rule mid-transition.
disabled state renders as "Muted" history/timeline-table.spec.ts test.skip(true) Unreachable: a disabled history row is policy-driven, and disabling a rule appends no row (verified).
time-range boundaries inclusive/exclusive history/timeline-table.spec.ts test.skip(true) Unreachable: asserting a row exactly at start and one at start-1ms means controlling row timestamps, but evaluation times are whatever the ruler chose.
shows empty state when no rules exist list/columns.spec.ts test.skip(true) Needs a workspace with zero rules, which means tearing down the shared rules fixture mid-suite while parallel workers use the same stack. Covered by the component test instead.
shows ErrorEmptyState when list fails to load list/navigation.spec.ts test.skip(true) No server-side way to make GET /api/v1/rules fail on demand, and the suite does not stub the network. Left explicitly untested rather than mocked.
the anomaly card rewrites the rule type, not the alert type create/shell.spec.ts conditional Runs only where the ANOMALY_DETECTION feature flag is active; it is off on this stack.
copy-link button copies the current URL to clipboard details/chrome.spec.ts conditional Runs on Chromium only — Playwright grants clipboard-read nowhere else.

Issues closed by this PR

Reference issues using Closes #issue-number to enable automatic closure on merge.

Closes https://github.com/SigNoz/engineering-pod/issues/4917


✅ Change Type

Select all that apply

  • ✨ Feature
  • 🐛 Bug fix
  • ♻️ Refactor
  • 🛠️ Infra / Tooling
  • 🧪 Test-only

⚠️ Risk & Impact Assessment

What could break? How do we recover?

  • Blast radius: Alerts
  • Potential regressions: None, only test ids
  • Rollback plan: Find and fix the issue specifically

📝 Changelog

Fill only if this affects users, APIs, UI, or documented behavior
Use N/A for internal or non-user-facing changes

Field Value
Deployment Type Cloud / OSS / Enterprise
Change Type Maintenance
Description We added more E2E tests for Alerts page.

📋 Checklist

  • Tests added or explicitly not required
  • Manually tested
  • Breaking changes documented
  • Backward compatibility considered

@github-actions github-actions Bot added the enhancement New feature or request label Jul 30, 2026
@H4ad H4ad added safe-to-e2e Run e2e tests and removed safe-to-e2e Run e2e tests labels Jul 30, 2026
@H4ad H4ad added safe-to-e2e Run e2e tests and removed safe-to-e2e Run e2e tests labels Aug 2, 2026
@H4ad H4ad added safe-to-e2e Run e2e tests and removed safe-to-e2e Run e2e tests labels Aug 2, 2026
@H4ad
H4ad marked this pull request as ready for review August 2, 2026 22:54
@H4ad
H4ad requested review from a team, AshwinBhatkal and therealpandey as code owners August 2, 2026 22:54
@H4ad H4ad changed the title feat(alerts): add e2e test(alerts): add e2e for alerts Aug 2, 2026
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
GOARCH=${TARGETARCH} GOOS=${OS} go build -C ./cmd/enterprise -race -tags timetzdata -o /root/signoz \
GOARCH=${TARGETARCH} GOOS=${OS} go build -C ./cmd/enterprise -tags timetzdata -o /root/signoz \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we remove the race flag @H4ad, the build cache will become useless and thrash with the integration build cache effectively meaning no cache.

Comment thread tests/e2e/package.json
"main": "index.js",
"scripts": {
"preinstall": "npx only-allow pnpm",
"env:start": "cd .. && uv run pytest --basetemp=./tmp/ -vv --reuse --with-web e2e/bootstrap/setup.py::test_setup",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has changed now to make use of the build cache. Please see the updated command in contributing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request safe-to-e2e Run e2e tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants