UNPKG

@applitools/eyes-playwright

Version:
111 lines (110 loc) 6.08 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /** * Report Renderer - Orchestrates Eyes integration into Playwright HTML reports * * Initial Flow: * 1. Waits for test results, calls window.onload() to refresh Playwright UI with Eyes data * 2. After 200ms delay (for React render), creates Eyes UI elements via DOM observer * 3. Renders batch link (list mode), navigation filters, test badges (list mode), iframes (detail mode) * 4. Starts polling Eyes server every 5s for status updates * * Polling & Update Flow: * - Detects changes by comparing status fields before updating * - Continues indefinitely unless all tests reach `aborted` status * - On changes: merges updates, recalculates Playwright statuses, updates window.playwrightReportBase64 * - Triggers window.onload() for React re-render (removes all Eyes elements from DOM) * - After 200ms delay, recreates Eyes elements in order: batch link, filters, badges, iframes */ const dataParser_js_1 = require("./data/dataParser.js"); const navigationState_js_1 = require("./state/navigationState.js"); const scrollPreserver_js_1 = require("./utils/scrollPreserver.js"); const scriptTagRestorer_js_1 = require("./utils/scriptTagRestorer.js"); const eyesResultsBatchLinkUI_js_1 = require("./ui/eyesResultsBatchLinkUI.js"); const navigationUI_js_1 = require("./ui/navigationUI.js"); const filterManager_js_1 = require("./ui/filterManager.js"); const testListUI_js_1 = require("./ui/testListUI.js"); const testDetailUI_js_1 = require("./ui/testDetailUI.js"); const pollingManager_js_1 = require("./management/pollingManager.js"); const urlChangeHandler_js_1 = require("./handlers/urlChangeHandler.js"); const domChangesHandler_js_1 = require("./handlers/domChangesHandler.js"); const statusUpdateHandler_js_1 = require("./handlers/statusUpdateHandler.js"); const log_1 = __importDefault(require("./core/log")); const logger = (0, log_1.default)(); class ReportRenderer { constructor(waitForResults, options = {}) { this.updatePlaywrightWithEyesResults = () => { // Capture scroll position before triggering window.onload this.scrollPreserver.captureScrollPosition(); // Ensure the script tag exists before calling window.onload (Playwright 1.57+ compatibility) (0, scriptTagRestorer_js_1.ensureScriptTagExists)(); if (typeof window.onload === 'function') { const onloadHandler = window.onload; onloadHandler(new Event('load')); } setTimeout(() => { this.urlChangeHandler.handleUrlChange(); // Restore scroll position after React has re-rendered this.scrollPreserver.restoreScrollPosition(); }, 200); }; this.handleStatusUpdate = async (testResults) => { this.waitForResults = Promise.resolve(testResults); await this.statusUpdateHandler.handleStatusUpdate(testResults); }; this.waitForResults = waitForResults; this.useTestMode = options.useTestMode || false; // Create shared navigation state this.navigationState = new navigationState_js_1.NavigationState(); this.scrollPreserver = new scrollPreserver_js_1.ScrollPreserver(); this.filterManager = new filterManager_js_1.FilterManager(); this.eyesResultsBatchLinkUI = new eyesResultsBatchLinkUI_js_1.EyesResultsBatchLinkUI(); this.navigationUI = new navigationUI_js_1.NavigationUI(this.filterManager); this.testListUI = new testListUI_js_1.TestListUI(); this.testDetailUI = new testDetailUI_js_1.TestDetailUI(this.navigationState, { useTestMode: this.useTestMode }); this.urlChangeHandler = new urlChangeHandler_js_1.UrlChangeHandler(this.waitForResults, this.navigationState, this.filterManager, this.eyesResultsBatchLinkUI, this.navigationUI, this.testDetailUI); this.domChangesHandler = new domChangesHandler_js_1.DomChangesHandler(this.waitForResults, this.filterManager, this.eyesResultsBatchLinkUI, this.navigationUI, this.testListUI); this.statusUpdateHandler = new statusUpdateHandler_js_1.StatusUpdateHandler(this.scrollPreserver, this.eyesResultsBatchLinkUI, this.navigationUI, this.testListUI, this.testDetailUI); this.pollingManager = new pollingManager_js_1.PollingManager(); this.pollingManager.onStatusUpdate = this.handleStatusUpdate; this.waitForResults.then(this.updatePlaywrightWithEyesResults); } render() { window.addEventListener('hashchange', this.urlChangeHandler.handleUrlChange); window.addEventListener('popstate', this.urlChangeHandler.handleUrlChange); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', this.urlChangeHandler.handleUrlChange); } else { this.urlChangeHandler.handleUrlChange(); } this.observeDomChanges(); this.pollingManager.startPolling(this.waitForResults); } observeDomChanges() { const mutationObserver = new MutationObserver(this.domChangesHandler.handleDomChanges); const rootElement = document.getElementById('root'); if (!rootElement) { logger.warn('No root element found for observation'); return; } mutationObserver.observe(rootElement, { childList: true, subtree: true, }); } updateFilterCounts(testResults) { this.navigationUI.updateFilterCounts(testResults); } } window.__initEyesReport = (options = {}) => { const useTestMode = options.useTestMode || false; logger.log('Before Initialized'); const waitForResults = (0, dataParser_js_1.getTestResults)(); const reportRenderer = new ReportRenderer(waitForResults, { useTestMode }); reportRenderer.render(); logger.log('Initialized'); };