UNPKG

@web/test-runner-webdriver

Version:
150 lines 5.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IFrameManager = void 0; const coverage_js_1 = require("./coverage.js"); /** * Manages tests to be executed in iframes on a page. */ class IFrameManager { constructor(config, driver, isIE) { this.framePerSession = new Map(); this.inactiveFrames = []; this.frameCount = 0; this.initialized = false; this.config = config; this.driver = driver; this.isIE = isIE; } async _initialize(url) { const pageUrl = `${new URL(url).origin}/?mode=iframe`; await this.driver.navigateTo(pageUrl); } isActive(id) { return this.framePerSession.has(id); } async getBrowserUrl(sessionId) { const frameId = this.getFrameId(sessionId); const returnValue = (await this.driver.execute(` try { var iframe = document.getElementById("${frameId}"); return iframe.contentWindow.location.href; } catch (_) { return undefined; } `)); return returnValue; } getFrameId(sessionId) { const frameId = this.framePerSession.get(sessionId); if (!frameId) { throw new Error(`Something went wrong while running tests, there is no frame id for session ${sessionId}`); } return frameId; } async scheduleCommand(fn) { if (!this.isIE) { return fn(); } while (this.locked) { await this.locked; } const fnPromise = fn(); this.locked = fnPromise; const result = await fnPromise; this.locked = undefined; return result; } async queueStartSession(id, url) { if (!this.initializePromise && !this.initialized) { this.initializePromise = this._initialize(url); } if (this.initializePromise) { await this.initializePromise; this.initializePromise = undefined; this.initialized = true; } this.scheduleCommand(() => this.startSession(id, url)); } async startSession(id, url) { let frameId; if (this.inactiveFrames.length > 0) { frameId = this.inactiveFrames.pop(); await this.driver.execute(` var iframe = document.getElementById("${frameId}"); iframe.src = "${url}"; `); } else { this.frameCount += 1; frameId = `wtr-test-frame-${this.frameCount}`; await this.driver.execute(` var iframe = document.createElement("iframe"); iframe.id = "${frameId}"; iframe.src = "${url}"; document.body.appendChild(iframe); `); } this.framePerSession.set(id, frameId); } async queueStopSession(id) { return this.scheduleCommand(() => this.stopSession(id)); } async stopSession(id) { const frameId = this.getFrameId(id); // Retrieve test results from iframe const returnValue = await this.driver.executeAsync(` var iframe = document.getElementById("${frameId}"); var testCoverage; try { testCoverage = iframe.contentWindow.__coverage__; } catch (error) { // iframe can throw a cross-origin error if the test navigated } // Don't move on until the iframe has settled after unloading the page var done = arguments[arguments.length-1]; var loaded = function() { iframe.removeEventListener('load', loaded); iframe.removeEventListener('error', loaded); done({ testCoverage: testCoverage }); }; iframe.addEventListener('load', loaded); iframe.addEventListener('error', loaded); // set src after retrieving values to avoid the iframe from navigating away iframe.src = "about:blank"; `); if (!(0, coverage_js_1.validateBrowserResult)(returnValue)) { throw new Error(); } const { testCoverage } = returnValue; this.inactiveFrames.push(frameId); return { testCoverage: this.config.coverage ? testCoverage : undefined }; } async sendKeys(sessionId, keys) { const frameId = this.getFrameId(sessionId); const frame = await this.driver.$(`iframe#${frameId}`); await this.driver.switchToFrame(frame); return this.driver.keys(keys); } // eslint-disable-next-line @typescript-eslint/no-unused-vars async performActions(_, _actions) { throw new Error('Unsupported operation. In order to use device actions in Webdriver, set "concurrency" to 1.'); } async takeScreenshot(sessionId, locator) { const frameId = this.getFrameId(sessionId); const frame = await this.driver.$(`iframe#${frameId}`); await this.driver.switchToFrame(frame); const elementData = (await this.driver.execute(locator, [])); const element = await this.driver.$(elementData).getElement(); let base64 = ''; try { base64 = await this.driver.takeElementScreenshot(element.elementId); } catch (err) { console.log('Failed to take a screenshot:', err); } await this.driver.switchToParentFrame(); return Buffer.from(base64, 'base64'); } } exports.IFrameManager = IFrameManager; //# sourceMappingURL=IFrameManager.js.map