testcafe
Version:
Automated browser testing for the modern web development stack.
521 lines • 88 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const lodash_1 = require("lodash");
const builder_symbol_1 = __importDefault(require("../builder-symbol"));
const snapshot_properties_1 = require("./snapshot-properties");
const get_callsite_1 = require("../../errors/get-callsite");
const client_function_builder_1 = __importDefault(require("../client-function-builder"));
const re_executable_promise_1 = __importDefault(require("../../utils/re-executable-promise"));
const type_assertions_1 = require("../../errors/runtime/type-assertions");
const make_reg_exp_1 = __importDefault(require("../../utils/make-reg-exp"));
const selector_text_filter_1 = __importDefault(require("./selector-text-filter"));
const selector_attribute_filter_1 = __importDefault(require("./selector-attribute-filter"));
const prepare_api_args_1 = __importDefault(require("./prepare-api-args"));
const filterNodes = (new client_function_builder_1.default((nodes, filter, querySelectorRoot, originNode, ...filterArgs) => {
if (typeof filter === 'number') {
const matchingNode = filter < 0 ? nodes[nodes.length + filter] : nodes[filter];
return matchingNode ? [matchingNode] : [];
}
const result = [];
if (typeof filter === 'string') {
// NOTE: we can search for elements only in document or element.
if (querySelectorRoot.nodeType !== 1 && querySelectorRoot.nodeType !== 9)
return null;
const matching = querySelectorRoot.querySelectorAll(filter);
const matchingArr = [];
for (let i = 0; i < matching.length; i++)
matchingArr.push(matching[i]);
filter = node => matchingArr.indexOf(node) > -1;
}
if (typeof filter === 'function') {
for (let j = 0; j < nodes.length; j++) {
if (filter(nodes[j], j, originNode, ...filterArgs))
result.push(nodes[j]);
}
}
return result;
})).getFunction();
const expandSelectorResults = (new client_function_builder_1.default((selector, populateDerivativeNodes) => {
const nodes = selector();
if (!nodes.length)
return null;
const result = [];
for (let i = 0; i < nodes.length; i++) {
const derivativeNodes = populateDerivativeNodes(nodes[i]);
if (derivativeNodes) {
for (let j = 0; j < derivativeNodes.length; j++) {
if (result.indexOf(derivativeNodes[j]) < 0)
result.push(derivativeNodes[j]);
}
}
}
return result;
})).getFunction();
async function getSnapshot(getSelector, callsite, SelectorBuilder) {
let node = null;
const selector = new SelectorBuilder(getSelector(), { needError: true }, { instantiation: 'Selector' }).getFunction();
try {
node = await selector();
}
catch (err) {
err.callsite = callsite;
throw err;
}
return node;
}
function assertAddCustomDOMPropertiesOptions(properties) {
type_assertions_1.assertType(type_assertions_1.is.nonNullObject, 'addCustomDOMProperties', '"addCustomDOMProperties" option', properties);
Object.keys(properties).forEach(prop => {
type_assertions_1.assertType(type_assertions_1.is.function, 'addCustomDOMProperties', `Custom DOM properties method '${prop}'`, properties[prop]);
});
}
function assertAddCustomMethods(properties, opts) {
type_assertions_1.assertType(type_assertions_1.is.nonNullObject, 'addCustomMethods', '"addCustomMethods" option', properties);
if (opts !== void 0)
type_assertions_1.assertType(type_assertions_1.is.nonNullObject, 'addCustomMethods', '"addCustomMethods" option', opts);
Object.keys(properties).forEach(prop => {
type_assertions_1.assertType(type_assertions_1.is.function, 'addCustomMethods', `Custom method '${prop}'`, properties[prop]);
});
}
function getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, additionalDependencies) {
return Object.assign({}, options, { selectorFn, apiFn, filter, additionalDependencies });
}
function addSnapshotProperties(obj, getSelector, SelectorBuilder, properties) {
properties.forEach(prop => {
Object.defineProperty(obj, prop, {
get: () => {
const callsite = get_callsite_1.getCallsiteForMethod('get');
return re_executable_promise_1.default.fromFn(async () => {
const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder);
return snapshot[prop];
});
}
});
});
}
function addCustomMethods(obj, getSelector, SelectorBuilder, customMethods) {
const customMethodProps = customMethods ? Object.keys(customMethods) : [];
customMethodProps.forEach(prop => {
const { returnDOMNodes = false, method } = customMethods[prop];
const dependencies = {
customMethod: method,
selector: getSelector()
};
const callsiteNames = { instantiation: prop };
if (returnDOMNodes) {
obj[prop] = (...args) => {
const selectorFn = () => {
/* eslint-disable no-undef */
const nodes = selector();
return customMethod.apply(customMethod, [nodes].concat(args));
/* eslint-enable no-undef */
};
const apiFn = prepare_api_args_1.default(prop, ...args);
const filter = () => true;
const additionalDependencies = {
args,
customMethod: method
};
return createDerivativeSelectorWithFilter({ getSelector, SelectorBuilder, selectorFn, apiFn, filter, additionalDependencies });
};
}
else {
obj[prop] = (new client_function_builder_1.default((...args) => {
/* eslint-disable no-undef */
const node = selector();
return customMethod.apply(customMethod, [node].concat(args));
/* eslint-enable no-undef */
}, { dependencies }, callsiteNames)).getFunction();
}
});
}
exports.addCustomMethods = addCustomMethods;
function addSnapshotPropertyShorthands({ obj, getSelector, SelectorBuilder, customDOMProperties, customMethods }) {
let properties = snapshot_properties_1.SNAPSHOT_PROPERTIES;
if (customDOMProperties)
properties = properties.concat(Object.keys(customDOMProperties));
addSnapshotProperties(obj, getSelector, SelectorBuilder, properties);
addCustomMethods(obj, getSelector, SelectorBuilder, customMethods);
obj.getStyleProperty = prop => {
const callsite = get_callsite_1.getCallsiteForMethod('getStyleProperty');
return re_executable_promise_1.default.fromFn(async () => {
const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder);
return snapshot.style ? snapshot.style[prop] : void 0;
});
};
obj.getAttribute = attrName => {
const callsite = get_callsite_1.getCallsiteForMethod('getAttribute');
return re_executable_promise_1.default.fromFn(async () => {
const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder);
return snapshot.attributes ? snapshot.attributes[attrName] : void 0;
});
};
obj.hasAttribute = attrName => {
const callsite = get_callsite_1.getCallsiteForMethod('hasAttribute');
return re_executable_promise_1.default.fromFn(async () => {
const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder);
return snapshot.attributes ? snapshot.attributes.hasOwnProperty(attrName) : false;
});
};
obj.getBoundingClientRectProperty = prop => {
const callsite = get_callsite_1.getCallsiteForMethod('getBoundingClientRectProperty');
return re_executable_promise_1.default.fromFn(async () => {
const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder);
return snapshot.boundingClientRect ? snapshot.boundingClientRect[prop] : void 0;
});
};
obj.hasClass = name => {
const callsite = get_callsite_1.getCallsiteForMethod('hasClass');
return re_executable_promise_1.default.fromFn(async () => {
const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder);
return snapshot.classNames ? snapshot.classNames.indexOf(name) > -1 : false;
});
};
}
function createCounter(getSelector, SelectorBuilder) {
const builder = new SelectorBuilder(getSelector(), { counterMode: true }, { instantiation: 'Selector' });
const counter = builder.getFunction();
const callsite = get_callsite_1.getCallsiteForMethod('get');
return async () => {
try {
return await counter();
}
catch (err) {
err.callsite = callsite;
throw err;
}
};
}
function addCounterProperties({ obj, getSelector, SelectorBuilder }) {
Object.defineProperty(obj, 'count', {
get: () => {
const counter = createCounter(getSelector, SelectorBuilder);
return re_executable_promise_1.default.fromFn(() => counter());
}
});
Object.defineProperty(obj, 'exists', {
get: () => {
const counter = createCounter(getSelector, SelectorBuilder);
return re_executable_promise_1.default.fromFn(async () => await counter() > 0);
}
});
}
function convertFilterToClientFunctionIfNecessary(callsiteName, filter, dependencies) {
if (typeof filter === 'function') {
const builder = filter[builder_symbol_1.default];
const fn = builder ? builder.fn : filter;
const options = builder ? lodash_1.assign({}, builder.options, { dependencies }) : { dependencies };
return (new client_function_builder_1.default(fn, options, { instantiation: callsiteName })).getFunction();
}
return filter;
}
function createDerivativeSelectorWithFilter({ getSelector, SelectorBuilder, selectorFn, apiFn, filter, additionalDependencies }) {
const collectionModeSelectorBuilder = new SelectorBuilder(getSelector(), { collectionMode: true });
const customDOMProperties = collectionModeSelectorBuilder.options.customDOMProperties;
const customMethods = collectionModeSelectorBuilder.options.customMethods;
let dependencies = {
selector: collectionModeSelectorBuilder.getFunction(),
filter: filter,
filterNodes: filterNodes
};
const { boundTestRun, timeout, visibilityCheck, apiFnChain } = collectionModeSelectorBuilder.options;
dependencies = lodash_1.assign(dependencies, additionalDependencies);
const builder = new SelectorBuilder(selectorFn, {
dependencies,
customDOMProperties,
customMethods,
boundTestRun,
timeout,
visibilityCheck,
apiFnChain,
apiFn
}, { instantiation: 'Selector' });
return builder.getFunction();
}
const filterByText = convertFilterToClientFunctionIfNecessary('filter', selector_text_filter_1.default);
const filterByAttr = convertFilterToClientFunctionIfNecessary('filter', selector_attribute_filter_1.default);
function ensureRegExpContext(str) {
// NOTE: if a regexp is created in a separate context (via the 'vm' module) we
// should wrap it with new RegExp() to make the `instanceof RegExp` check successful.
if (typeof str !== 'string' && !(str instanceof RegExp))
return new RegExp(str);
return str;
}
function addFilterMethods(options) {
const { obj, getSelector, SelectorBuilder } = options;
obj.nth = index => {
type_assertions_1.assertType(type_assertions_1.is.number, 'nth', '"index" argument', index);
const apiFn = prepare_api_args_1.default('nth', index);
const builder = new SelectorBuilder(getSelector(), { index, apiFn }, { instantiation: 'Selector' });
return builder.getFunction();
};
obj.withText = text => {
type_assertions_1.assertType([type_assertions_1.is.string, type_assertions_1.is.regExp], 'withText', '"text" argument', text);
const apiFn = prepare_api_args_1.default('withText', text);
text = ensureRegExpContext(text);
const selectorFn = () => {
/* eslint-disable no-undef */
const nodes = selector();
if (!nodes.length)
return null;
return filterNodes(nodes, filter, document, void 0, textRe);
/* eslint-enable no-undef */
};
const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filterByText, { textRe: make_reg_exp_1.default(text) });
return createDerivativeSelectorWithFilter(args);
};
obj.withExactText = text => {
type_assertions_1.assertType(type_assertions_1.is.string, 'withExactText', '"text" argument', text);
const selectorFn = () => {
/* eslint-disable no-undef */
const nodes = selector();
if (!nodes.length)
return null;
return filterNodes(nodes, filter, document, void 0, exactText);
/* eslint-enable no-undef */
};
const apiFn = prepare_api_args_1.default('withExactText', text);
const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filterByText, { exactText: text });
return createDerivativeSelectorWithFilter(args);
};
obj.withAttribute = (attrName, attrValue) => {
type_assertions_1.assertType([type_assertions_1.is.string, type_assertions_1.is.regExp], 'withAttribute', '"attrName" argument', attrName);
const apiFn = prepare_api_args_1.default('withAttribute', attrName, attrValue);
attrName = ensureRegExpContext(attrName);
if (attrValue !== void 0) {
type_assertions_1.assertType([type_assertions_1.is.string, type_assertions_1.is.regExp], 'withAttribute', '"attrValue" argument', attrValue);
attrValue = ensureRegExpContext(attrValue);
}
const selectorFn = () => {
/* eslint-disable no-undef */
const nodes = selector();
if (!nodes.length)
return null;
return filterNodes(nodes, filter, document, void 0, attrName, attrValue);
/* eslint-enable no-undef */
};
const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filterByAttr, {
attrName,
attrValue
});
return createDerivativeSelectorWithFilter(args);
};
obj.filter = (filter, dependencies) => {
type_assertions_1.assertType([type_assertions_1.is.string, type_assertions_1.is.function], 'filter', '"filter" argument', filter);
const apiFn = prepare_api_args_1.default('filter', filter);
filter = convertFilterToClientFunctionIfNecessary('filter', filter, dependencies);
const selectorFn = () => {
/* eslint-disable no-undef */
const nodes = selector();
if (!nodes.length)
return null;
return filterNodes(nodes, filter, document, void 0);
/* eslint-enable no-undef */
};
const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter);
return createDerivativeSelectorWithFilter(args);
};
obj.filterVisible = () => {
const apiFn = prepare_api_args_1.default('filterVisible');
const builder = new SelectorBuilder(getSelector(), { filterVisible: true, apiFn }, { instantiation: 'Selector' });
return builder.getFunction();
};
obj.filterHidden = () => {
const apiFn = prepare_api_args_1.default('filterHidden');
const builder = new SelectorBuilder(getSelector(), { filterHidden: true, apiFn }, { instantiation: 'Selector' });
return builder.getFunction();
};
}
function addCustomDOMPropertiesMethod({ obj, getSelector, SelectorBuilder }) {
obj.addCustomDOMProperties = customDOMProperties => {
assertAddCustomDOMPropertiesOptions(customDOMProperties);
const builder = new SelectorBuilder(getSelector(), { customDOMProperties }, { instantiation: 'Selector' });
return builder.getFunction();
};
}
function addCustomMethodsMethod({ obj, getSelector, SelectorBuilder }) {
obj.addCustomMethods = function (methods, opts) {
assertAddCustomMethods(methods, opts);
const customMethods = {};
Object.keys(methods).forEach(methodName => {
customMethods[methodName] = {
method: methods[methodName],
returnDOMNodes: opts && !!opts.returnDOMNodes
};
});
const builder = new SelectorBuilder(getSelector(), { customMethods }, { instantiation: 'Selector' });
return builder.getFunction();
};
}
function addHierarchicalSelectors(options) {
const { obj } = options;
// Find
obj.find = (filter, dependencies) => {
type_assertions_1.assertType([type_assertions_1.is.string, type_assertions_1.is.function], 'find', '"filter" argument', filter);
const apiFn = prepare_api_args_1.default('find', filter);
filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies);
const selectorFn = () => {
/* eslint-disable no-undef */
return expandSelectorResults(selector, node => {
if (typeof filter === 'string') {
return typeof node.querySelectorAll === 'function' ?
node.querySelectorAll(filter) :
null;
}
const results = [];
const visitNode = currentNode => {
const cnLength = currentNode.childNodes.length;
for (let i = 0; i < cnLength; i++) {
const child = currentNode.childNodes[i];
results.push(child);
visitNode(child);
}
};
visitNode(node);
return filterNodes(results, filter, null, node);
});
/* eslint-enable no-undef */
};
const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults });
return createDerivativeSelectorWithFilter(args);
};
// Parent
obj.parent = (filter, dependencies) => {
if (filter !== void 0)
type_assertions_1.assertType([type_assertions_1.is.string, type_assertions_1.is.function, type_assertions_1.is.number], 'parent', '"filter" argument', filter);
const apiFn = prepare_api_args_1.default('parent', filter);
filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies);
const selectorFn = () => {
/* eslint-disable no-undef */
return expandSelectorResults(selector, node => {
const parents = [];
for (let parent = node.parentNode; parent; parent = parent.parentNode)
parents.push(parent);
return filter !== void 0 ? filterNodes(parents, filter, document, node) : parents;
});
/* eslint-enable no-undef */
};
const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults });
return createDerivativeSelectorWithFilter(args);
};
// Child
obj.child = (filter, dependencies) => {
if (filter !== void 0)
type_assertions_1.assertType([type_assertions_1.is.string, type_assertions_1.is.function, type_assertions_1.is.number], 'child', '"filter" argument', filter);
const apiFn = prepare_api_args_1.default('child', filter);
filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies);
const selectorFn = () => {
/* eslint-disable no-undef */
return expandSelectorResults(selector, node => {
const childElements = [];
const cnLength = node.childNodes.length;
for (let i = 0; i < cnLength; i++) {
const child = node.childNodes[i];
if (child.nodeType === 1)
childElements.push(child);
}
return filter !== void 0 ? filterNodes(childElements, filter, node, node) : childElements;
});
/* eslint-enable no-undef */
};
const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults });
return createDerivativeSelectorWithFilter(args);
};
// Sibling
obj.sibling = (filter, dependencies) => {
if (filter !== void 0)
type_assertions_1.assertType([type_assertions_1.is.string, type_assertions_1.is.function, type_assertions_1.is.number], 'sibling', '"filter" argument', filter);
const apiFn = prepare_api_args_1.default('sibling', filter);
filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies);
const selectorFn = () => {
/* eslint-disable no-undef */
return expandSelectorResults(selector, node => {
const parent = node.parentNode;
if (!parent)
return null;
const siblings = [];
const cnLength = parent.childNodes.length;
for (let i = 0; i < cnLength; i++) {
const child = parent.childNodes[i];
if (child.nodeType === 1 && child !== node)
siblings.push(child);
}
return filter !== void 0 ? filterNodes(siblings, filter, parent, node) : siblings;
});
/* eslint-enable no-undef */
};
const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults });
return createDerivativeSelectorWithFilter(args);
};
// Next sibling
obj.nextSibling = (filter, dependencies) => {
if (filter !== void 0)
type_assertions_1.assertType([type_assertions_1.is.string, type_assertions_1.is.function, type_assertions_1.is.number], 'nextSibling', '"filter" argument', filter);
const apiFn = prepare_api_args_1.default('nextSibling', filter);
filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies);
const selectorFn = () => {
/* eslint-disable no-undef */
return expandSelectorResults(selector, node => {
const parent = node.parentNode;
if (!parent)
return null;
const siblings = [];
const cnLength = parent.childNodes.length;
let afterNode = false;
for (let i = 0; i < cnLength; i++) {
const child = parent.childNodes[i];
if (child === node)
afterNode = true;
else if (afterNode && child.nodeType === 1)
siblings.push(child);
}
return filter !== void 0 ? filterNodes(siblings, filter, parent, node) : siblings;
});
/* eslint-enable no-undef */
};
const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults });
return createDerivativeSelectorWithFilter(args);
};
// Prev sibling
obj.prevSibling = (filter, dependencies) => {
if (filter !== void 0)
type_assertions_1.assertType([type_assertions_1.is.string, type_assertions_1.is.function, type_assertions_1.is.number], 'prevSibling', '"filter" argument', filter);
const apiFn = prepare_api_args_1.default('prevSibling', filter);
filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies);
const selectorFn = () => {
/* eslint-disable no-undef */
return expandSelectorResults(selector, node => {
const parent = node.parentNode;
if (!parent)
return null;
const siblings = [];
const cnLength = parent.childNodes.length;
for (let i = 0; i < cnLength; i++) {
const child = parent.childNodes[i];
if (child === node)
break;
if (child.nodeType === 1)
siblings.push(child);
}
return filter !== void 0 ? filterNodes(siblings, filter, parent, node) : siblings;
});
/* eslint-enable no-undef */
};
const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults });
return createDerivativeSelectorWithFilter(args);
};
}
function addAPI(selector, getSelector, SelectorBuilder, customDOMProperties, customMethods) {
const options = { obj: selector, getSelector, SelectorBuilder, customDOMProperties, customMethods };
addFilterMethods(options);
addHierarchicalSelectors(options);
addSnapshotPropertyShorthands(options);
addCustomDOMPropertiesMethod(options);
addCustomMethodsMethod(options);
addCounterProperties(options);
}
exports.addAPI = addAPI;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGllbnQtZnVuY3Rpb25zL3NlbGVjdG9ycy9hZGQtYXBpLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbUNBQWdDO0FBQ2hDLHVFQUE0RDtBQUM1RCwrREFBNEQ7QUFDNUQsNERBQWlFO0FBQ2pFLHlGQUErRDtBQUMvRCw4RkFBb0U7QUFDcEUsMEVBQXNFO0FBQ3RFLDRFQUFrRDtBQUNsRCxrRkFBd0Q7QUFDeEQsNEZBQWtFO0FBQ2xFLDBFQUFrRDtBQUVsRCxNQUFNLFdBQVcsR0FBRyxDQUFDLElBQUksaUNBQXFCLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLGlCQUFpQixFQUFFLFVBQVUsRUFBRSxHQUFHLFVBQVUsRUFBRSxFQUFFO0lBQzNHLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFO1FBQzVCLE1BQU0sWUFBWSxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFL0UsT0FBTyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUM3QztJQUVELE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQztJQUVsQixJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRTtRQUM1QixnRUFBZ0U7UUFDaEUsSUFBSSxpQkFBaUIsQ0FBQyxRQUFRLEtBQUssQ0FBQyxJQUFJLGlCQUFpQixDQUFDLFFBQVEsS0FBSyxDQUFDO1lBQ3BFLE9BQU8sSUFBSSxDQUFDO1FBRWhCLE1BQU0sUUFBUSxHQUFNLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9ELE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQztR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