docsify/test/helpers/wait-for.js
2020-10-23 13:07:10 -05:00

127 lines
3.1 KiB
JavaScript

const defaults = {
delay: 100,
timeout: 4000,
};
/**
* Waits for specified function to resolve to a truthy value.
*
* @param {Function} fn function to be evaluated until truthy
* @param {*} arg optional argument to pass to `fn`
* @param {Object} options optional parameters
* @returns {Promise} promise which resolves to function result
*/
export function waitForFunction(fn, arg, options = {}) {
const settings = {
...defaults,
...options,
};
return new Promise((resolve, reject) => {
let timeElapsed = 0;
const int = setInterval(() => {
let result;
try {
result = fn(arg);
} catch (e) {
// Continue...
}
if (result) {
clearInterval(int);
resolve(result);
}
timeElapsed += settings.delay;
if (timeElapsed >= settings.timeout) {
const msg = `waitForFunction did not return a truthy value (${
settings.timeout
} ms): ${fn.toString()}\n`;
reject(msg);
}
}, settings.delay);
});
}
/**
* Waits for specified CSS selector to be located in the DOM
*
* @param {String} cssSelector CSS selector to query for
* @param {Object} options optional parameters
* @returns {Promise} promise which resolves to first matching element
*/
export function waitForSelector(cssSelector, options = {}) {
const settings = {
...defaults,
...options,
};
return new Promise((resolve, reject) => {
let timeElapsed = 0;
const int = setInterval(() => {
const elm = document.querySelector(cssSelector);
if (elm) {
clearInterval(int);
resolve(elm);
}
timeElapsed += settings.delay;
if (timeElapsed >= settings.timeout) {
const msg = `waitForSelector did not match CSS selector '${cssSelector}' (${settings.timeout} ms)`;
reject(msg);
}
}, settings.delay);
});
}
/**
* Waits for specified CSS selector to contain text content
*
* @param {String} cssSelector CSS selector to query for
* @param {String} text text to match
* @param {Object} options optional parameters
* @returns {Promise} promise which resolves to first matching element that contains specified text
*/
export function waitForText(cssSelector, text, options = {}) {
const settings = {
...defaults,
...options,
};
return new Promise((resolve, reject) => {
let timeElapsed = 0;
waitForSelector(cssSelector, settings)
.then(elm => {
const int = setInterval(() => {
const isMatch = elm.textContent.includes(text);
if (isMatch) {
clearInterval(int);
resolve(true);
}
timeElapsed += settings.delay;
if (timeElapsed >= settings.timeout) {
const msg = `waitForText did not find '${text}' in CSS selector '${cssSelector}' (${settings.timeout} ms): '${elm.textContent}'`;
reject(msg);
}
}, settings.delay);
})
.catch(() => {
const msg = `waitForText did not match CSS selector '${cssSelector}' (${settings.timeout} ms)`;
reject(msg);
});
});
}