fix: support async functions as an argument for waitForFunction (#5682)
This commit is contained in:
parent
e6c22dae05
commit
caaf4d2086
16
docs/api.md
16
docs/api.md
@ -2098,6 +2098,22 @@ const selector = '.foo';
|
|||||||
await page.waitForFunction(selector => !!document.querySelector(selector), {}, selector);
|
await page.waitForFunction(selector => !!document.querySelector(selector), {}, selector);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The predicate of `page.waitForFunction` can be asynchronous too:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const username = 'github-username';
|
||||||
|
await page.waitForFunction(async username => {
|
||||||
|
const githubResponse = await fetch(`https://api.github.com/users/${username}`);
|
||||||
|
const githubUser = await githubResponse.json();
|
||||||
|
// show the avatar
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = githubUser.avatar_url;
|
||||||
|
// wait 3 seconds
|
||||||
|
await new Promise((resolve, reject) => setTimeout(resolve, 3000));
|
||||||
|
img.remove();
|
||||||
|
}, {}, username);
|
||||||
|
```
|
||||||
|
|
||||||
Shortcut for [page.mainFrame().waitForFunction(pageFunction[, options[, ...args]])](#framewaitforfunctionpagefunction-options-args).
|
Shortcut for [page.mainFrame().waitForFunction(pageFunction[, options[, ...args]])](#framewaitforfunctionpagefunction-options-args).
|
||||||
|
|
||||||
#### page.waitForNavigation([options])
|
#### page.waitForNavigation([options])
|
||||||
|
@ -692,18 +692,18 @@ async function waitForPredicatePageFunction(
|
|||||||
/**
|
/**
|
||||||
* @return {!Promise<*>}
|
* @return {!Promise<*>}
|
||||||
*/
|
*/
|
||||||
function pollMutation(): Promise<unknown> {
|
async function pollMutation(): Promise<unknown> {
|
||||||
const success = predicate(...args);
|
const success = await predicate(...args);
|
||||||
if (success) return Promise.resolve(success);
|
if (success) return Promise.resolve(success);
|
||||||
|
|
||||||
let fulfill;
|
let fulfill;
|
||||||
const result = new Promise((x) => (fulfill = x));
|
const result = new Promise((x) => (fulfill = x));
|
||||||
const observer = new MutationObserver(() => {
|
const observer = new MutationObserver(async () => {
|
||||||
if (timedOut) {
|
if (timedOut) {
|
||||||
observer.disconnect();
|
observer.disconnect();
|
||||||
fulfill();
|
fulfill();
|
||||||
}
|
}
|
||||||
const success = predicate(...args);
|
const success = await predicate(...args);
|
||||||
if (success) {
|
if (success) {
|
||||||
observer.disconnect();
|
observer.disconnect();
|
||||||
fulfill(success);
|
fulfill(success);
|
||||||
@ -717,35 +717,35 @@ async function waitForPredicatePageFunction(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pollRaf(): Promise<unknown> {
|
async function pollRaf(): Promise<unknown> {
|
||||||
let fulfill;
|
let fulfill;
|
||||||
const result = new Promise((x) => (fulfill = x));
|
const result = new Promise((x) => (fulfill = x));
|
||||||
onRaf();
|
await onRaf();
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
function onRaf(): void {
|
async function onRaf(): Promise<unknown> {
|
||||||
if (timedOut) {
|
if (timedOut) {
|
||||||
fulfill();
|
fulfill();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const success = predicate(...args);
|
const success = await predicate(...args);
|
||||||
if (success) fulfill(success);
|
if (success) fulfill(success);
|
||||||
else requestAnimationFrame(onRaf);
|
else requestAnimationFrame(onRaf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pollInterval(pollInterval: number): Promise<unknown> {
|
async function pollInterval(pollInterval: number): Promise<unknown> {
|
||||||
let fulfill;
|
let fulfill;
|
||||||
const result = new Promise((x) => (fulfill = x));
|
const result = new Promise((x) => (fulfill = x));
|
||||||
onTimeout();
|
await onTimeout();
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
function onTimeout(): void {
|
async function onTimeout(): Promise<unknown> {
|
||||||
if (timedOut) {
|
if (timedOut) {
|
||||||
fulfill();
|
fulfill();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const success = predicate(...args);
|
const success = await predicate(...args);
|
||||||
if (success) fulfill(success);
|
if (success) fulfill(success);
|
||||||
else setTimeout(onTimeout, pollInterval);
|
else setTimeout(onTimeout, pollInterval);
|
||||||
}
|
}
|
||||||
|
@ -138,6 +138,22 @@ describe('waittask specs', function () {
|
|||||||
await watchdog;
|
await watchdog;
|
||||||
expect(Date.now() - startTime).not.toBeLessThan(polling / 2);
|
expect(Date.now() - startTime).not.toBeLessThan(polling / 2);
|
||||||
});
|
});
|
||||||
|
it('should poll on interval async', async () => {
|
||||||
|
const { page } = getTestState();
|
||||||
|
let success = false;
|
||||||
|
const startTime = Date.now();
|
||||||
|
const polling = 100;
|
||||||
|
const watchdog = page
|
||||||
|
.waitForFunction(async () => window.__FOO === 'hit', { polling })
|
||||||
|
.then(() => (success = true));
|
||||||
|
await page.evaluate(async () => (window.__FOO = 'hit'));
|
||||||
|
expect(success).toBe(false);
|
||||||
|
await page.evaluate(async () =>
|
||||||
|
document.body.appendChild(document.createElement('div'))
|
||||||
|
);
|
||||||
|
await watchdog;
|
||||||
|
expect(Date.now() - startTime).not.toBeLessThan(polling / 2);
|
||||||
|
});
|
||||||
it('should poll on mutation', async () => {
|
it('should poll on mutation', async () => {
|
||||||
const { page } = getTestState();
|
const { page } = getTestState();
|
||||||
|
|
||||||
@ -152,6 +168,22 @@ describe('waittask specs', function () {
|
|||||||
);
|
);
|
||||||
await watchdog;
|
await watchdog;
|
||||||
});
|
});
|
||||||
|
it('should poll on mutation async', async () => {
|
||||||
|
const { page } = getTestState();
|
||||||
|
|
||||||
|
let success = false;
|
||||||
|
const watchdog = page
|
||||||
|
.waitForFunction(async () => window.__FOO === 'hit', {
|
||||||
|
polling: 'mutation',
|
||||||
|
})
|
||||||
|
.then(() => (success = true));
|
||||||
|
await page.evaluate(async () => (window.__FOO = 'hit'));
|
||||||
|
expect(success).toBe(false);
|
||||||
|
await page.evaluate(async () =>
|
||||||
|
document.body.appendChild(document.createElement('div'))
|
||||||
|
);
|
||||||
|
await watchdog;
|
||||||
|
});
|
||||||
it('should poll on raf', async () => {
|
it('should poll on raf', async () => {
|
||||||
const { page } = getTestState();
|
const { page } = getTestState();
|
||||||
|
|
||||||
@ -161,6 +193,18 @@ describe('waittask specs', function () {
|
|||||||
await page.evaluate(() => (window.__FOO = 'hit'));
|
await page.evaluate(() => (window.__FOO = 'hit'));
|
||||||
await watchdog;
|
await watchdog;
|
||||||
});
|
});
|
||||||
|
it('should poll on raf async', async () => {
|
||||||
|
const { page } = getTestState();
|
||||||
|
|
||||||
|
const watchdog = page.waitForFunction(
|
||||||
|
async () => window.__FOO === 'hit',
|
||||||
|
{
|
||||||
|
polling: 'raf',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
await page.evaluate(async () => (window.__FOO = 'hit'));
|
||||||
|
await watchdog;
|
||||||
|
});
|
||||||
itFailsFirefox('should work with strict CSP policy', async () => {
|
itFailsFirefox('should work with strict CSP policy', async () => {
|
||||||
const { page, server } = getTestState();
|
const { page, server } = getTestState();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user