UNPKG

aye-spy

Version:
211 lines (166 loc) 6.41 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _jimp = require('jimp'); var _jimp2 = _interopRequireDefault(_jimp); var _logger = require('./logger'); var _logger2 = _interopRequireDefault(_logger); var _executeScript = require('./executeScript'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* eslint-disable import/no-dynamic-require*/ class SnapShotter { constructor({ label = 'label', latest = __dirname, gridUrl = 'http://localhost:4444', width = 700, height = 1024, browser = 'chrome', mobileDeviceName, cookies, cropToSelector, removeElements, hideElements, waitForElement, wait, url = 'http://localhost:80', viewportLabel = 'viewportLabel', onBeforeScript, onReadyScript }, selenium, onComplete, onError) { this._label = label; this._latest = latest; this._gridUrl = gridUrl; this._width = width; this._height = height; this._browser = browser; this._mobileDeviceName = mobileDeviceName; this._cookies = cookies; this._cropToSelector = cropToSelector; this._removeElements = removeElements; this._hideElements = hideElements; this._waitForElement = waitForElement; this._url = url; this.wait = wait; this._onBeforeScript = onBeforeScript; this._onReadyScript = onReadyScript; this._viewportLabel = viewportLabel; this._By = selenium.By; this._until = selenium.until; this._webdriver = selenium.webdriver; this._onComplete = onComplete; this._onError = onError; const browserCapability = this._browser.includes('chrome') ? this._webdriver.Capabilities.chrome : this._webdriver.Capabilities.firefox; this._capability = mobileDeviceName ? this.getMobileBrowserCapability() : browserCapability(); } get driver() { return this._driver; } getMobileBrowserCapability() { return { browserName: 'chrome', version: '*', 'goog:chromeOptions': { mobileEmulation: { deviceName: this._mobileDeviceName }, args: ['incognito'] } }; } async snooze(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async removeTheSelectors() { for (let i = 0; i < this._removeElements.length; i++) { const script = `document.querySelectorAll('${this._removeElements[i]}').forEach(element => element.remove())`; await this.driver.executeScript(script); } } async hideTheSelectors() { for (let i = 0; i < this._hideElements.length; i++) { const script = `document.querySelectorAll('${this._hideElements[i]}').forEach(element => element.style.opacity = '0')`; await this.driver.executeScript(script); } } async applyCookies() { for (let i = 0; i < this._cookies.length; i++) { const { name, value } = this._cookies[i]; await this.driver.manage().addCookie({ name, value }); } await this.driver.get(this._url); } async waitForElement() { const timeout = 10000; const element = await this.driver.findElement(this._By.css(this._waitForElement)); try { await this.driver.wait(this._until.elementIsVisible(element), timeout); } catch (error) { console.log(''); // eslint-disable-line no-console // space for progress bar _logger2.default.error('snapshotter', `❌ Unable to find the specified waitForElement element on the page! ❌ ${error}`); } } getElementDimensions(selector) { return this._driver.findElement(this._By.css(selector)).getRect().then(dimensions => { if (!dimensions) throw new Error(`"cropToSelector" (${selector}') could not be found on the page.`); return dimensions; }); } async writeCroppedScreenshot(filename, screenshot, selector) { _logger2.default.verbose('Cropping', `selector: ${selector}`); const { x, y, width, height } = await this.getElementDimensions(selector); await _jimp2.default.read(Buffer.from(screenshot, 'base64')).then(image => image.crop(x, y, width, height)).then(cropped => cropped.write(filename)); } writeScreenshot(filename, screenshot) { _fs2.default.writeFileSync(filename, screenshot, 'base64'); } handleScriptError(error) { _logger2.default.error('snapshotter', `❌ Unable to run script for scenario: ${this._label} \n due to: ${error}`); } async takeSnap() { try { this._driver = await new this._webdriver.Builder().usingServer(this._gridUrl).withCapabilities(this._capability).build(); } catch (err) { this._onError(); _logger2.default.error('snapshotter', `❌ Unable to connect to the grid at ${this._gridUrl}`); process.exitCode = 1; return; } try { _logger2.default.verbose('Snapshotting', `${this._label}-${this._viewportLabel} : Url: ${this._url}`); await this.driver.get(this._url); await this._driver.manage().window().setRect({ width: this._width, height: this._height }); if (this._onBeforeScript) await (0, _executeScript.executeScriptWithDriver)(this._driver, this._onBeforeScript).catch(this.handleScriptError); if (this._cookies) await this.applyCookies(); if (this._waitForElement) await this.waitForElement(); if (this._onReadyScript) await (0, _executeScript.executeScriptWithDriver)(this._driver, this._onReadyScript).catch(this.handleScriptError); if (this._hideElements) await this.hideTheSelectors(); if (this._removeElements) await this.removeTheSelectors(); if (this.wait) await this.snooze(this.wait); const filename = `${this._latest}/${this._label}-${this._viewportLabel}.png`; const screenshot = await this.driver.takeScreenshot(); if (this._cropToSelector) { await this.writeCroppedScreenshot(filename, screenshot, this._cropToSelector); } else { this.writeScreenshot(filename, screenshot); } this._onComplete(); } catch (err) { this._onError(); _logger2.default.error('snapshotter', `❌ Unable to take snapshot for ${this._label}-${this._viewportLabel}! ❌ : ${err}`); process.exitCode = 1; } finally { await this.driver.quit(); } } } exports.default = SnapShotter;