2.9 KiB
2.9 KiB
type, status, category, isAgentGenerated
| type | status | category | isAgentGenerated |
|---|---|---|---|
| Task | AI Gen TODO | QA | true |
Test: Toast Notification Timing and Dismissal
Description
Verify that toast notifications appear with correct error/success styling, auto-dismiss after the expected duration (~1.3s), and multiple toasts stack properly when triggered in rapid succession.
Rationale
The Build Calculator shows toast notifications for errors ("Missing Requirements", "Not Enough Ether") and potentially for success/addition confirmations. The existing toast test (tests/buildCalculator.spec.js) only checks whether a toast appears within 3 seconds; it does not validate:
- The toast's CSS class (
.errorvs.success). - The exact display duration.
- Stacking behavior when multiple errors are triggered rapidly.
- Whether a toast persists if the condition that triggered it is resolved.
Playwright Feature
This test uses page.clock (Playwright's clock API) to control time without waiting real seconds, plus page.waitForSelector with exact timeout values and page.evaluate to inspect DOM classes.
Clock-based Timing Test
// Install fake timers before navigation
await page.clock.install();
await page.clock.fastForward(5000); // Simulate WASM loading delay
await calc.goto();
// Trigger a toast by clicking E (Soul Foundry without Legion Hall)
await calc.hotkeys.clickKey('E');
await page.clock.fastForward(500); // small delay for render
// Assert toast appears with error styling
const toast = page.locator('.toastsContainer .toastContainer');
await expect(toast).toHaveClass(/error/);
// Fast-forward to just before auto-dismiss
await page.clock.fastForward(1200);
await expect(toast).toBeVisible(); // still visible at ~1.2s
// Fast-forward past dismissal
await page.clock.fastForward(200);
await expect(toast).not.toBeVisible(); // gone by ~1.4s
Stacking Test
// Trigger two toasts in rapid succession
calc.filter.selectFaction("Q'Rath");
await calc.hotkeys.clickKey('E'); // Missing Requirements
// Without waiting, trigger another (e.g., click an entity with zero ether)
await calc.hotkeys.clickKey('Q');
await calc.hotkeys.clickKey('E'); // Not Enough Ether
await page.waitForTimeout(300);
// Assert TWO toasts are visible, stacked
const toasts = page.locator('.toastsContainer .toastContainer');
await expect(toasts).toHaveCount(2);
// Assert the first toast has error styling and correct title
await expect(toasts.nth(0).locator('.toastTitle')).toHaveText('Missing Requirements');
await expect(toasts.nth(1).locator('.toastTitle')).toHaveText('Not Enough Ether');
What This Test Catches
- Auto-dismiss timer drift (toast stays too long or disappears too early).
- Success vs. error CSS class mismatch (all toasts get the same styling).
- Stacking order (new toasts should appear above or below older ones).
- Memory leaks (stale toast DOM nodes that never get removed).
- Race conditions between
ToastService.AddToastandStateHasChanged.