UNPKG

playwright-ai-auto-debug

Version:

Automatic Playwright test debugging with AI assistance + UI Test Coverage Analysis

278 lines (232 loc) 11.4 kB
import { test } from '../lib/simpleFixture.js'; import { expect } from '@playwright/test'; import { UICoverageAnalyzer } from '../lib/uiCoverageAnalyzer.js'; import fs from 'fs'; test.describe('🎯 UI Coverage Analysis with MCP', () => { let analyzer; test.beforeEach(async () => { // Инициализация анализатора с критичными элементами analyzer = new UICoverageAnalyzer({ criticalElements: [ { type: 'button', name: 'Get started', selector: 'text=Get started' }, { type: 'button', name: 'Search', selector: 'button:has-text("Search")' }, { type: 'link', name: 'Docs', selector: 'text=Docs' }, { type: 'navigation', name: 'Main', selector: 'navigation' }, { type: 'button', name: 'Node.js', selector: 'button:has-text("Node.js")' } ] }); }); test('🌳 1. Анализ дерева доступности главной страницы', async ({ page }) => { await test.step('Переход на главную страницу', async () => { await page.goto('/'); await page.waitForLoadState('networkidle'); }); await test.step('Получение DOM snapshot через MCP', async () => { // Имитируем получение snapshot от MCP // В реальной реализации это будет вызов MCP API const mockSnapshot = await getMockSnapshot(page); // Парсинг accessibility tree const accessibilityTree = analyzer.parseAccessibilityTree(mockSnapshot); console.log('🌳 Accessibility Tree Analysis:'); console.log(`Total elements: ${accessibilityTree.totalCount}`); console.log('Elements by type:', accessibilityTree.byType); // Проверки expect(accessibilityTree.totalCount).toBeGreaterThan(0); expect(accessibilityTree.byType.button).toBeDefined(); expect(accessibilityTree.byType.link).toBeDefined(); }); }); test('✅ 2. Подсчет элементов и проверка свойств', async ({ page }) => { await test.step('Навигация и анализ элементов', async () => { await page.goto('/'); await page.waitForLoadState('networkidle'); const mockSnapshot = await getMockSnapshot(page); const accessibilityTree = analyzer.parseAccessibilityTree(mockSnapshot); // Анализ покрытия элементов const elementStats = analyzer.analyzeElementCoverage(accessibilityTree); console.log('📊 Element Coverage Analysis:'); console.log('Summary:', elementStats.summary); // Создание отчета const report = { accessibilityTree, elementStats }; const coverageReport = analyzer.generateCoverageReport(report, 'playwright-homepage'); // Сохранение отчета await analyzer.saveReport(coverageReport, `ui-coverage-${Date.now()}.md`); // Проверки expect(elementStats.summary.totalElements).toBeGreaterThan(10); expect(elementStats.summary.buttons).toBeGreaterThan(0); expect(elementStats.summary.links).toBeGreaterThan(0); expect(elementStats.summary.interactive).toBeGreaterThan(0); }); }); test('🔄 3. Проверка критичных элементов', async ({ page }) => { await test.step('Анализ критичных элементов страницы', async () => { await page.goto('/'); await page.waitForLoadState('networkidle'); const mockSnapshot = await getMockSnapshot(page); const accessibilityTree = analyzer.parseAccessibilityTree(mockSnapshot); // Проверка критичных элементов const criticalCheck = analyzer.checkCriticalElements( accessibilityTree, analyzer.config.criticalElements ); console.log('🔍 Critical Elements Check:'); console.log(`Found critical: ${criticalCheck.foundCritical.length}`); console.log(`Missing critical: ${criticalCheck.missingCritical.length}`); console.log('Recommendations:', criticalCheck.recommendations); // Создание полного отчета const fullReport = { accessibilityTree, elementStats: analyzer.analyzeElementCoverage(accessibilityTree), criticalCheck }; const coverageReport = analyzer.generateCoverageReport(fullReport, 'critical-elements-check'); await analyzer.saveReport(coverageReport, `critical-check-${Date.now()}.md`); // Проверки expect(criticalCheck.foundCritical.length).toBeGreaterThan(0); // Логирование для демонстрации if (criticalCheck.missingCritical.length > 0) { console.log('⚠️ Missing critical elements detected!'); criticalCheck.missingCritical.forEach(missing => { console.log(`❌ ${missing.name} (${missing.type})`); }); } }); }); test('📊 4. Сравнение с золотой версией', async ({ page }) => { await test.step('Создание и сравнение с эталонным snapshot', async () => { await page.goto('/'); await page.waitForLoadState('networkidle'); const currentSnapshot = await getMockSnapshot(page); const currentTree = analyzer.parseAccessibilityTree(currentSnapshot); // Создание "золотой" версии (для демонстрации) const goldenSnapshot = await createGoldenSnapshot(); const goldenTree = analyzer.parseAccessibilityTree(goldenSnapshot); // Сравнение с эталоном const goldenComparison = analyzer.compareWithGolden(currentTree, goldenTree); console.log('🔗 Golden Comparison:'); console.log(`Identical: ${goldenComparison.identical}`); console.log(`New elements: ${goldenComparison.newElements.length}`); console.log(`Removed elements: ${goldenComparison.removedElements.length}`); console.log('Differences:', goldenComparison.differences); // Создание итогового отчета const fullAnalysis = { accessibilityTree: currentTree, elementStats: analyzer.analyzeElementCoverage(currentTree), criticalCheck: analyzer.checkCriticalElements(currentTree, analyzer.config.criticalElements), goldenComparison }; const finalReport = analyzer.generateCoverageReport(fullAnalysis, 'golden-comparison'); await analyzer.saveReport(finalReport, `golden-comparison-${Date.now()}.md`); // Проверки expect(goldenComparison).toBeDefined(); expect(Array.isArray(goldenComparison.differences)).toBe(true); }); }); test('⚙️ 5. Интеграция в CI/CD pipeline', async ({ page }) => { await test.step('Полный цикл анализа для CI/CD', async () => { await page.goto('/'); await page.waitForLoadState('networkidle'); // Полный анализ страницы const snapshot = await getMockSnapshot(page); const accessibilityTree = analyzer.parseAccessibilityTree(snapshot); const elementStats = analyzer.analyzeElementCoverage(accessibilityTree); const criticalCheck = analyzer.checkCriticalElements(accessibilityTree, analyzer.config.criticalElements); // Создание CI/CD отчета const ciReport = { accessibilityTree, elementStats, criticalCheck, // goldenComparison можно добавить при наличии эталона }; const coverageReport = analyzer.generateCoverageReport(ciReport, 'ci-cd-pipeline'); const reportPath = await analyzer.saveReport(coverageReport, `ci-report-${Date.now()}.md`); // Проверки для CI/CD console.log('🚀 CI/CD Integration Results:'); console.log(`Report saved to: ${reportPath}`); console.log(`Coverage: ${coverageReport.summary.coveragePercentage}%`); console.log(`Accessibility Score: ${coverageReport.summary.accessibilityScore}%`); // Условия прохождения для CI/CD expect(coverageReport.summary.totalElements).toBeGreaterThan(5); expect(coverageReport.summary.interactiveElements).toBeGreaterThan(2); // Проверка критичных элементов if (!criticalCheck.allCriticalPresent) { console.warn('⚠️ Some critical elements are missing!'); // В реальном CI/CD можно настроить fail теста } // Логирование рекомендаций console.log('📋 Recommendations:'); coverageReport.recommendations.forEach(rec => console.log(` ${rec}`)); }); }); }); // Вспомогательные функции /** * Получение mock snapshot (имитация MCP) */ async function getMockSnapshot(page) { // В реальной реализации здесь будет вызов MCP API // Пока используем имитацию на основе реального DOM const snapshot = `# Page snapshot - region "Skip to main content": - link "Skip to main content": - /url: "#__docusaurus_skipToContent_fallback" - navigation "Main": - link "Playwright logo Playwright": - /url: / - img "Playwright logo" - text: Playwright - link "Docs": - /url: /docs/intro - link "API": - /url: /docs/api/class-playwright - button "Node.js" - link "Community": - /url: /community/welcome - link "GitHub repository": - /url: https://github.com/microsoft/playwright - button "Switch between dark and light mode" - button "Search (Command+K)": Search ⌘ K - banner: - heading "Playwright enables reliable end-to-end testing" [level=1] - link "Get started": - /url: /docs/intro - link "Star microsoft/playwright on GitHub": - /url: https://github.com/microsoft/playwright - main: - img "Browsers (Chromium, Firefox, WebKit)" - heading "Any browser • Any platform • One API" [level=3] - paragraph: Cross-browser. Playwright supports all modern rendering engines - link "TypeScript": - /url: https://playwright.dev/docs/intro - link "JavaScript": - /url: https://playwright.dev/docs/intro`; return snapshot; } /** * Создание эталонного snapshot для сравнения */ async function createGoldenSnapshot() { // Имитация "золотой" версии с небольшими отличиями return `# Page snapshot - region "Skip to main content": - link "Skip to main content": - /url: "#__docusaurus_skipToContent_fallback" - navigation "Main": - link "Playwright logo Playwright": - /url: / - link "Docs": - /url: /docs/intro - button "Node.js" - link "Community": - /url: /community/welcome - button "Search (Command+K)": Search ⌘ K - banner: - heading "Playwright enables reliable end-to-end testing" [level=1] - link "Get started": - /url: /docs/intro - main: - heading "Any browser • Any platform • One API" [level=3]`; }