Files
sam-hotfix/e2e/runner/eval_chunk_0.js

1 line
12 KiB
JavaScript
Raw Normal View History

window.__C = '/**\n * E2E Step Executor - Browser-injected test runner\n * Injected via playwright_evaluate, exposes window.__E2E__\n *\n * Handles both scenario JSON formats:\n * Format A: { action, target, value, ... }\n * Format B: { actions: [{ type, target, value }, ...] }\n */\n(function () {\n \'use strict\';\n\n // Prevent double-injection\n if (window.__E2E__ && window.__E2E__._version >= 1) return;\n\n // ─── Helpers ────────────────────────────────────────────\n\n const sleep = (ms) => new Promise((r) => setTimeout(r, ms));\n\n const now = () => Date.now();\n\n /** Scroll element into view center */\n const scrollIntoView = (el) => {\n if (el && el.scrollIntoView) {\n el.scrollIntoView({ block: \'center\', behavior: \'instant\' });\n }\n };\n\n // ─── ApiMonitor ─────────────────────────────────────────\n\n const ApiMonitor = {\n _logs: [],\n _errors: [],\n _installed: false,\n\n install() {\n if (this._installed) return;\n this._installed = true;\n const self = this;\n const origFetch = window.fetch;\n window.fetch = async function (...args) {\n const url = typeof args[0] === \'string\' ? args[0] : args[0]?.url || \'\';\n const method = (args[1]?.method || \'GET\').toUpperCase();\n const t0 = now();\n try {\n const resp = await origFetch.apply(this, args);\n const entry = {\n url,\n method,\n status: resp.status,\n ok: resp.ok,\n duration: now() - t0,\n ts: new Date().toISOString(),\n };\n self._logs.push(entry);\n if (!resp.ok) self._errors.push(entry);\n return resp;\n } catch (err) {\n self._errors.push({ url, method, error: err.message, ts: new Date().toISOString() });\n throw err;\n }\n };\n\n // Also intercept XMLHttpRequest\n const origOpen = XMLHttpRequest.prototype.open;\n const origSend = XMLHttpRequest.prototype.send;\n XMLHttpRequest.prototype.open = function (method, url, ...rest) {\n this.__e2e_method = (method || \'GET\').toUpperCase();\n this.__e2e_url = url;\n return origOpen.call(this, method, url, ...rest);\n };\n XMLHttpRequest.prototype.send = function (...args) {\n const t0 = now();\n const self2 = this;\n this.addEventListener(\'loadend\', function () {\n const entry = {\n url: self2.__e2e_url,\n method: self2.__e2e_method,\n status: self2.status,\n ok: self2.status >= 200 && self2.status < 300,\n duration: now() - t0,\n ts: new Date().toISOString(),\n };\n self._logs.push(entry);\n if (!entry.ok) self._errors.push(entry);\n });\n return origSend.apply(this, args);\n };\n },\n\n summary() {\n const logs = this._logs;\n return {\n total: logs.length,\n success: logs.filter((l) => l.ok).length,\n failed: this._errors.length,\n avgResponseTime:\n logs.length > 0\n ? Math.round(logs.reduce((s, l) => s + (l.duration || 0), 0) / logs.length)\n : 0,\n slowCalls: logs.filter((l) => l.duration > 2000).length,\n };\n },\n\n findCall(urlPattern, method) {\n return this._logs.find(\n (l) =>\n l.url.includes(urlPattern) && (!method || l.method === method.toUpperCase())\n );\n },\n\n reset() {\n this._logs = [];\n this._errors = [];\n },\n };\n\n // ─── ModalGuard ─────────────────────────────────────────\n\n const MODAL_SELECTORS = [\n "[role=\'dialog\']",\n "[aria-modal=\'true\']",\n "[class*=\'modal\']:not([class*=\'tooltip\']):not([class*=\'modal-back