mirror of
https://github.com/SigNoz/signoz.git
synced 2026-08-30 16:20:27 +01:00
## 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. | | 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 - [x] 🧪 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 - [x] Tests added or explicitly not required - [ ] Manually tested - [ ] Breaking changes documented - [ ] Backward compatibility considered