Mess with lusha's waitFor for fun. (#133)

This commit is contained in:
Pavel Feldman 2017-07-25 15:57:31 -07:00 committed by Andrey Lushnikov
parent 4adf11427a
commit 49e363c121

View File

@ -422,7 +422,7 @@ class WaitTask {
constructor(frame, pageScript, timeout) {
this._frame = frame;
this._pageScript = pageScript;
this._runningTask = null;
this._runCount = 0;
frame._waitTasks.add(this);
this.promise = new Promise((resolve, reject) => {
this._resolve = resolve;
@ -438,30 +438,34 @@ class WaitTask {
* @param {!Error} error
*/
terminate(error) {
this._terminated = true;
this._reject(error);
this._cleanup();
}
rerun() {
let runningTask = this._frame._evaluateExpression(this._pageScript, true).then(finish.bind(this), finish.bind(this, false));
this._runningTask = runningTask;
/**
* @param {boolean} success
* @param {?Error=} error
*/
function finish(success, error) {
if (runningTask !== this._runningTask)
return;
// Ignore timeouts in pageScript - we track timeouts ourselves.
if (!success && !error)
return;
if (error)
this._reject(error);
else
this._resolve();
this._cleanup();
async rerun() {
const runCount = ++this._runCount;
let success = false;
let error = null;
try {
success = await this._frame._evaluateExpression(this._pageScript, true);
} catch (e) {
error = e;
}
if (this._terminated || runCount !== this._runCount)
return;
// Ignore timeouts in pageScript - we track timeouts ourselves.
if (!success && !error)
return;
if (error)
this._reject(error);
else
this._resolve();
this._cleanup();
}
_cleanup() {
@ -477,30 +481,28 @@ class WaitTask {
* @param {number} timeout
* @return {!Promise<boolean>}
*/
function waitForSelectorPageFunction(selector, visible, timeout) {
const resultPromise = visible ? waitForVisible(selector) : waitInDOM(selector);
const timeoutPromise = new Promise(fulfill => setTimeout(fulfill, timeout));
return Promise.race([
resultPromise.then(() => true),
timeoutPromise.then(() => false)
]);
async function waitForSelectorPageFunction(selector, visible, timeout) {
let timedOut = false;
setTimeout(() => timedOut = true, timeout);
await waitForDOM();
await waitForVisible();
return !timedOut;
/**
* @param {string} selector
* @return {!Promise<!Element>}
*/
function waitInDOM(selector) {
function waitForDOM() {
let node = document.querySelector(selector);
if (node)
return Promise.resolve(node);
return Promise.resolve();
let fulfill;
const result = new Promise(x => fulfill = x);
const observer = new MutationObserver(mutations => {
const node = document.querySelector(selector);
if (node) {
if (node || timedOut) {
observer.disconnect();
fulfill(node);
fulfill();
}
});
observer.observe(document, {
@ -511,23 +513,26 @@ function waitForSelectorPageFunction(selector, visible, timeout) {
}
/**
* @param {string} selector
* @return {!Promise<!Element>}
*/
async function waitForVisible(selector) {
function waitForVisible() {
let fulfill;
const result = new Promise(x => fulfill = x);
onRaf();
return result;
async function onRaf() {
const node = await waitInDOM(selector);
const style = window.getComputedStyle(node);
if (style.display === 'none' || style.visibility === 'hidden') {
function onRaf() {
if (timedOut) {
fulfill();
return;
}
const node = document.querySelector(selector);
const style = node ? window.getComputedStyle(node) : null;
if (!style || style.display === 'none' || style.visibility === 'hidden') {
requestAnimationFrame(onRaf);
return;
}
fulfill(node);
fulfill();
}
}
}