webdriverio-automation
Version:
WebdriverIO-Automation android ios project
201 lines (154 loc) • 5.54 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _fs = _interopRequireDefault(require("fs"));
var _path = _interopRequireDefault(require("path"));
var _uuid = require("uuid");
var _logger = _interopRequireDefault(require("@wdio/logger"));
var _utils = require("@wdio/utils");
var _elementstore = _interopRequireDefault(require("./elementstore"));
var _utils2 = require("./utils");
var _constants = require("./constants");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const log = (0, _logger.default)('devtools');
class DevToolsDriver {
constructor(browser, pages) {
this.commands = {};
this.elementStore = new _elementstore.default();
this.windows = new Map();
this.timeouts = new Map();
this.activeDialog = null;
this.browser = browser;
const dir = _path.default.resolve(__dirname, 'commands');
const files = _fs.default.readdirSync(dir);
for (let filename of files) {
const commandName = _path.default.basename(filename, _path.default.extname(filename));
this.commands[commandName] = (0, _utils.safeRequire)(_path.default.join(dir, commandName)).default;
}
for (const page of pages) {
const pageId = (0, _uuid.v4)();
this.windows.set(pageId, page);
this.currentFrame = page;
this.currentWindowHandle = pageId;
}
this.setTimeouts(_constants.DEFAULT_IMPLICIT_TIMEOUT, _constants.DEFAULT_PAGELOAD_TIMEOUT, _constants.DEFAULT_SCRIPT_TIMEOUT);
const page = this.getPageHandle();
page.on('dialog', this.dialogHandler.bind(this));
page.on('framenavigated', this.framenavigatedHandler.bind(this));
}
static requireCommand(filePath) {
return require(filePath).default;
}
register(commandInfo) {
const self = this;
const {
command,
ref,
parameters,
variables = []
} = commandInfo;
if (typeof this.commands[command] !== 'function') {
return () => {
throw new Error(`Command "${command}" is not yet implemented`);
};
}
let retries = 0;
const wrappedCommand = async function (...args) {
await self.checkPendingNavigations();
const params = (0, _utils2.validate)(command, parameters, variables, ref, args);
let result;
try {
this.emit('command', {
command,
params,
retries
});
result = await self.commands[command].call(self, params);
} catch (err) {
if (err.message.includes('most likely because of a navigation')) {
log.debug('Command failed due to unfinished page transition, retrying...');
const page = self.getPageHandle();
await new Promise((resolve, reject) => {
const pageloadTimeout = setTimeout(() => reject(new Error('page load timeout')), self.timeouts.get('pageLoad'));
page.once('load', () => {
clearTimeout(pageloadTimeout);
resolve();
});
});
++retries;
return wrappedCommand.apply(this, args);
}
throw (0, _utils2.sanitizeError)(err);
}
this.emit('result', {
command,
params,
retries,
result: {
value: result
}
});
if (typeof result !== 'undefined') {
const isScreenshot = command.toLowerCase().includes('screenshot') && typeof result === 'string' && result.length > 64;
log.info('RESULT', isScreenshot ? `${result.substr(0, 61)}...` : result);
}
return result;
};
return wrappedCommand;
}
dialogHandler(dialog) {
this.activeDialog = dialog;
}
framenavigatedHandler(frame) {
this.currentFrameUrl = frame.url();
this.elementStore.clear();
}
setTimeouts(implicit, pageLoad, script) {
if (typeof implicit === 'number') {
this.timeouts.set('implicit', implicit);
}
if (typeof pageLoad === 'number') {
this.timeouts.set('pageLoad', pageLoad);
}
if (typeof script === 'number') {
this.timeouts.set('script', script);
}
const page = this.getPageHandle();
page.setDefaultTimeout(this.timeouts.get('pageLoad'));
}
getPageHandle(isInFrame = false) {
if (isInFrame && this.currentFrame) {
return this.currentFrame;
}
return this.windows.get(this.currentWindowHandle);
}
async checkPendingNavigations(pendingNavigationStart) {
let page = this.getPageHandle();
if (this.activeDialog || !page) {
return;
}
pendingNavigationStart = pendingNavigationStart || Date.now();
const pageloadTimeout = this.timeouts.get('pageLoad');
if (!page.mainFrame) {
const pages = await this.browser.pages();
page = pages.find(browserPage => browserPage.frames().find(frame => page === frame));
}
const pageloadTimeoutReached = Date.now() - pendingNavigationStart > pageloadTimeout;
const executionContext = await page.mainFrame().executionContext();
try {
await executionContext.evaluate('1');
const readyState = await executionContext.evaluate('document.readyState');
if (readyState !== 'complete' && !pageloadTimeoutReached) {
return this.checkPendingNavigations(pendingNavigationStart);
}
} catch (err) {
if (pageloadTimeoutReached) {
throw err;
}
return this.checkPendingNavigations(pendingNavigationStart);
}
}
}
exports.default = DevToolsDriver;