Files
sam-hotfix/e2e/runner/chunk_0.txt

1 line
7.9 KiB
Plaintext
Raw Normal View History

"(function () { 'use strict'; if (window.__E2E__ && window.__E2E__._version >= 1) return; const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); const now = () => Date.now(); const scrollIntoView = (el) => { if (el && el.scrollIntoView) { el.scrollIntoView({ block: 'center', behavior: 'instant' }); } }; const ApiMonitor = { _logs: [], _errors: [], _installed: false, install() { if (this._installed) return; this._installed = true; const self = this; const origFetch = window.fetch; window.fetch = async function (...args) { const url = typeof args[0] === 'string' ? args[0] : args[0]?.url || ''; const method = (args[1]?.method || 'GET').toUpperCase(); const t0 = now(); try { const resp = await origFetch.apply(this, args); const entry = { url, method, status: resp.status, ok: resp.ok, duration: now() - t0, ts: new Date().toISOString(), }; self._logs.push(entry); if (!resp.ok) self._errors.push(entry); return resp; } catch (err) { self._errors.push({ url, method, error: err.message, ts: new Date().toISOString() }); throw err; } }; const origOpen = XMLHttpRequest.prototype.open; const origSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.open = function (method, url, ...rest) { this.__e2e_method = (method || 'GET').toUpperCase(); this.__e2e_url = url; return origOpen.call(this, method, url, ...rest); }; XMLHttpRequest.prototype.send = function (...args) { const t0 = now(); const self2 = this; this.addEventListener('loadend', function () { const entry = { url: self2.__e2e_url, method: self2.__e2e_method, status: self2.status, ok: self2.status >= 200 && self2.status < 300, duration: now() - t0, ts: new Date().toISOString(), }; self._logs.push(entry); if (!entry.ok) self._errors.push(entry); }); return origSend.apply(this, args); }; }, summary() { const logs = this._logs; return { total: logs.length, success: logs.filter((l) => l.ok).length, failed: this._errors.length, avgResponseTime: logs.length > 0 ? Math.round(logs.reduce((s, l) => s + (l.duration || 0), 0) / logs.length) : 0, slowCalls: logs.filter((l) => l.duration > 2000).length, }; }, findCall(urlPattern, method) { return this._logs.find( (l) => l.url.includes(urlPattern) && (!method || l.method === method.toUpperCase()) ); }, reset() { this._logs = []; this._errors = []; }, }; const MODAL_SELECTORS = [ \"[role='dialog']\", \"[aria-modal='true']\", \"[class*='modal']:not([class*='tooltip']):not([class*='modal-backdrop'])\", \"[class*='Modal']:not([class*='Tooltip'])\", \"[class*='Dialog']:not([class*='tooltip'])\", ]; const ModalGuard = { check() { for (const sel of MODAL_SELECTORS) { const el = document.querySelector(sel); if (el && el.offsetParent !== null) { return { open: true, element: el }; } } return { open: false, element: null }; }, focus() { const { open, element } = this.check(); if (open && element) { const first = element.querySelector( 'input:not([type=\"hidden\"]), textarea, select, button:not([class*=\"close\"])' ); if (first) first.focus(); return true; } return false; }, async close() { const MAX = 3; for (let i = 0; i < MAX; i++) { const { open, element } = this.check(); if (!open) return { closed: true }; const xBtn = element.querySelector( \"button[class*='close'], [aria-label='닫기'], [aria-label='Close'], button[class*='Close']\" ); if (xBtn) { xBtn.click(); await sleep(500); if (!this.check().open) return { closed: true }; } const textBtn = Array.from(element.querySelectorAll('button')).find((b) => ['닫기', 'Close', '취소', 'Cancel'].some((t) => b.innerText?.trim().includes(t)) ); if (textBtn) { textBtn.click(); await sleep(500); if (!this.check().open) return { closed: true }; } document.dispatchEvent( new KeyboardEvent('keydown', { key: 'Escape', keyCode: 27, bubbles: true }) ); await sleep(500); } return { closed: !this.check().open }; }, scopedQuery(selector) { const { open, element } = this.check(); const scope = open ? element : document; return scope.querySelector(selector); }, scopedQueryAll(selector) { const { open, element } = this.check(); const scope = open ? element : document; return scope.querySelectorAll(se