qape
Version:
Monkey testing library
170 lines (136 loc) • 4.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _ActionsHelper = _interopRequireDefault(require("./ActionsHelper"));
var _globAll = _interopRequireDefault(require("glob-all"));
var _path = _interopRequireDefault(require("path"));
var _helpers = require("../../shared/helpers");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Actions handler which can work with specific actions.
*/
class ActionsHandler {
/**
* @param {Object} config
*/
constructor(config) {
this._config = config;
this._actionsHelper = null;
this._actions = {};
}
/**
* Initializes actions handler dependencies
* @returns {ActionsHandler} this
*/
init() {
this._initActionsHelper();
this._loadActions();
return this;
}
/**
* Executes specific, or random action
* @param {Browser} instance
* @param {string} [actionId] Random if not defined
* @param {Object} [actionConfig]
* @returns {Promise<Object>} Resolves with action results
*/
async execute(instance, actionId, actionConfig) {
let pageAction;
try {
await this._actionsHelper.waitForReadyState(instance.page);
pageAction = await this._getAction(instance, actionId, actionConfig);
} catch (e) {
return {
executionError: e.stack
};
}
if (!pageAction) {
return {
executionError: 'pageAction not defined!'
};
}
let {
Action,
element
} = pageAction;
let action = new Action(this._config, this._actionsHelper, actionConfig);
return action.execute(element, instance);
}
/**
* Gets random or specific action
* @param {Browser} instance
* @param {string} [actionId]
* @param {Object} [actionConfig]
* @returns {Object} { Action, element }
*/
async _getAction({
page
}, actionId, actionConfig) {
if (actionId && actionConfig && actionConfig.selector) {
return {
Action: this._actions[actionId],
element: await this._actionsHelper.getElement(page, actionConfig)
};
}
let actions = actionId ? [actionId] : Object.keys(this._actions);
let pageActions = await this._getAvailablePageActions(page, actions);
if (pageActions.length > 0) {
return (0, _helpers.getRandomElementFromArray)(pageActions);
}
throw Error('QApe is unable to determine any available actions ' + `on the current page (url: '${page.url()}'). This can be caused by trying to ` + 'peform an action during a page load state, or wrong ' + 'configuration of "elementSelector".');
}
/**
* Initializes actions helper
*/
_initActionsHelper() {
this._actionsHelper = new _ActionsHelper.default(this._config);
}
/**
* Loads all defined actions
*/
_loadActions() {
/*
* @FIXME Back action can get you to `about:blank` page,
* which does not have any elements available and causes
* crash of the QApe run. Back action should never get user
* to `about:blank` page. This needs to be fixed at
* `BackAction.prototype.isActionAvailable()`.
*/
let paths = [_path.default.join(__dirname, '!(Abstract|Back)Action.js')];
if (this._config.customActions && this._config.customActions.length > 0) {
this._config.customActions.forEach(action => paths.push(_path.default.join(process.cwd(), action)));
}
_globAll.default.sync(paths).map(actionFile => {
let action = require(actionFile).default;
if (this._actions[action.id]) {
throw Error('ActionsHandler: The same action id for multiple actions has been set. Action id must be unique!');
}
this._actions[action.id] = action;
});
}
/**
* @param {puppeteer.Page} page
* @param {string[]} availableActionIds
* @returns {Promise<Object[]>} Returns array of objects with keys
* Action and element, which are all available page actions
*/
async _getAvailablePageActions(page, availableActionIds) {
let elements = await this._actionsHelper.getAllVisiblePageElements(page);
let actions = [];
await Promise.all(elements.map(element => {
return Promise.all(availableActionIds.map(async id => {
let Action = this._actions[id];
if (await Action.isActionAvailable(element, page, this._config)) {
actions.push({
Action,
element
});
}
}));
}));
return actions;
}
}
exports.default = ActionsHandler;