import { test, expect } from '@playwright/test'; /** * Destructive Actions Confirmation Tests * * Tests that all destructive actions require confirmation */ test.describe('Destructive Actions Confirmation', () => { test('Delete action requires confirmation', async ({ page }) => { await page.goto('/plans'); await page.waitForLoadState('networkidle'); // Look for delete buttons const deleteButtons = page.locator('button:has-text("Delete"), button[aria-label*="delete"], button[title*="delete"]'); const deleteCount = await deleteButtons.count(); if (deleteCount > 0) { // Set up dialog handler to intercept confirmation let dialogShown = false; page.on('dialog', (dialog) => { dialogShown = true; dialog.dismiss(); }); // Click delete button await deleteButtons.first().click(); // Wait a moment for dialog to appear await page.waitForTimeout(500); // Verify that a confirmation dialog was shown expect(dialogShown).toBe(true); } }); test('Execute live trade requires confirmation', async ({ page }) => { await page.goto('/plans'); await page.waitForLoadState('networkidle'); // Look for trade execution buttons const tradeButtons = page.locator('button:has-text("Execute"), button:has-text("Trade"), button:has-text("Buy"), button:has-text("Sell")'); const tradeCount = await tradeButtons.count(); if (tradeCount > 0) { // Set up dialog handler let dialogShown = false; page.on('dialog', (dialog) => { dialogShown = true; dialog.dismiss(); }); // Click trade button await tradeButtons.first().click(); // Wait for dialog await page.waitForTimeout(500); // Verify confirmation dialog expect(dialogShown).toBe(true); } }); test('Dangerous actions have warning indicators', async ({ page }) => { await page.goto('/plans'); await page.waitForLoadState('networkidle'); // Look for dangerous buttons (delete, remove, clear, etc.) const dangerousButtons = page.locator('button:has-text("Delete"), button:has-text("Remove"), button:has-text("Clear"), button:has-text("Discard")'); const dangerousCount = await dangerousButtons.count(); if (dangerousCount > 0) { // Check that dangerous buttons have visual indicators for (let i = 0; i < Math.min(dangerousCount, 5); i++) { const button = dangerousButtons.nth(i); const isVisible = await button.isVisible(); if (isVisible) { // Check for danger styling (red color, warning icon, etc.) const bgColor = await button.evaluate((el) => { const computed = window.getComputedStyle(el); return computed.backgroundColor; }); // Danger buttons should have some indication (this is a basic check) // In production, you'd check for specific color values or classes expect(bgColor).toBeTruthy(); } } } }); test('Confirmation dialogs are clear about the action', async ({ page }) => { await page.goto('/plans'); await page.waitForLoadState('networkidle'); const deleteButtons = page.locator('button:has-text("Delete")'); const deleteCount = await deleteButtons.count(); if (deleteCount > 0) { page.on('dialog', async (dialog) => { const message = dialog.message(); // Dialog message should be clear about the action expect(message.toLowerCase()).toMatch(/delete|remove|confirm|sure/i); dialog.dismiss(); }); await deleteButtons.first().click(); await page.waitForTimeout(500); } }); });