Degraded UI Buttons
Disable a critical button and assert that the page exposes an alternate path or an actionable message.
await injectChaos(page, {});await page.goto('/settings');await page.evaluate((config) => (window as any).chaosUtils.start(config), { seed: 42, ui: { assaults: [{ selector: 'button.save', action: 'disable', probability: 1 }] },});await expect(page.locator('button.save')).toBeDisabled();await expect(page.locator('[data-testid="autosave-state"]')).toBeVisible();expect((await getChaosLog(page)).some((event) => event.type === 'ui:assault' && event.applied)).toBe(true);cy.injectChaos({});cy.visit('/settings');cy.window().then((win) => { (win as any).chaosUtils.start({ seed: 42, ui: { assaults: [{ selector: 'button.save', action: 'disable', probability: 1 }] }, });});cy.get('button.save').should('be.disabled');cy.get('[data-testid="autosave-state"]').should('be.visible');cy.getChaosLog().should((log) => { expect(log.some((event) => event.type === 'ui:assault' && event.applied)).to.equal(true);});await browser.url('/settings');await injectChaos(browser, { seed: 42, ui: { assaults: [{ selector: 'button.save', action: 'disable', probability: 1 }] },});await expect($('button.save')).toBeDisabled();await expect($('[data-testid="autosave-state"]')).toBeDisplayed();expect((await getChaosLog(browser)).some((event) => event.type === 'ui:assault' && event.applied)).toBe(true);await injectChaos(page, {});await page.goto('http://localhost:3000/settings');await page.evaluate((config) => (window as any).chaosUtils.start(config), { seed: 42, ui: { assaults: [{ selector: 'button.save', action: 'disable', probability: 1 }] },});const disabled = await page.$eval('button.save', (button) => (button as HTMLButtonElement).disabled);if (!disabled) throw new Error('Expected save button to be disabled');await page.waitForSelector('[data-testid="autosave-state"]');const log = await getChaosLog(page);if (!log.some((event) => event.type === 'ui:assault' && event.applied)) { throw new Error('Expected UI assault chaos');}