import { describe, test, expect, beforeEach, vi } from 'vitest'; import type { Page } from 'playwright'; describe('Wizard Dismissal Detection', () => { let mockPage: Page; beforeEach(() => { mockPage = { locator: vi.fn(), waitForTimeout: vi.fn().mockResolvedValue(undefined), } as unknown as Page; }); describe('isWizardModalDismissed', () => { test('should return FALSE when modal is transitioning between steps (temporarily hidden)', async () => { const modalSelector = '.modal.fade.in'; // Simulate step transition: modal not visible initially, then reappears after 500ms let checkCount = 0; const mockLocator = { isVisible: vi.fn().mockImplementation(() => { checkCount++; // First check: modal not visible (transitioning) if (checkCount === 1) return Promise.resolve(false); // Second check after 500ms delay: modal reappears (transition complete) if (checkCount === 2) return Promise.resolve(true); return Promise.resolve(false); }), }; vi.mocked(mockPage.locator).mockReturnValue(mockLocator as unknown as ReturnType); // Simulate the isWizardModalDismissed logic const isWizardModalDismissed = async (): Promise => { const modalVisible = await mockPage.locator(modalSelector).isVisible().catch(() => false); if (modalVisible) { return false; } // Wait 500ms to distinguish between transition and dismissal await mockPage.waitForTimeout(500); // Check again after delay const stillNotVisible = !await mockPage.locator(modalSelector).isVisible().catch(() => false); return stillNotVisible; }; const result = await isWizardModalDismissed(); // Should be FALSE because modal reappeared after transition expect(result).toBe(false); expect(mockPage.waitForTimeout).toHaveBeenCalledWith(500); expect(mockLocator.isVisible).toHaveBeenCalledTimes(2); }); test('should return TRUE when modal is permanently dismissed by user', async () => { const modalSelector = '.modal.fade.in'; // Simulate user dismissal: modal not visible and stays not visible const mockLocator = { isVisible: vi.fn().mockResolvedValue(false), }; vi.mocked(mockPage.locator).mockReturnValue(mockLocator as unknown as ReturnType); const isWizardModalDismissed = async (): Promise => { const modalVisible = await mockPage.locator(modalSelector).isVisible().catch(() => false); if (modalVisible) { return false; } await mockPage.waitForTimeout(500); const stillNotVisible = !await mockPage.locator(modalSelector).isVisible().catch(() => false); return stillNotVisible; }; const result = await isWizardModalDismissed(); expect(result).toBe(true); expect(mockLocator.isVisible).toHaveBeenCalledTimes(2); }); test('should return FALSE when modal is visible (user did not dismiss)', async () => { const modalSelector = '.modal.fade.in'; const mockLocator = { isVisible: vi.fn().mockResolvedValue(true), }; vi.mocked(mockPage.locator).mockReturnValue(mockLocator as unknown as ReturnType); const isWizardModalDismissed = async (): Promise => { const modalVisible = await mockPage.locator(modalSelector).isVisible().catch(() => false); if (modalVisible) { return false; } await mockPage.waitForTimeout(500); const stillNotVisible = !await mockPage.locator(modalSelector).isVisible().catch(() => false); return stillNotVisible; }; const result = await isWizardModalDismissed(); expect(result).toBe(false); // Should not wait or check again if modal is visible expect(mockPage.waitForTimeout).not.toHaveBeenCalled(); expect(mockLocator.isVisible).toHaveBeenCalledTimes(1); }); }); });