chore: use Google's TS style guide's format config (#8542)

This commit is contained in:
jrandolf 2022-06-22 15:25:44 +02:00 committed by GitHub
parent 3744c2f584
commit 84712cbc28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
122 changed files with 2891 additions and 2962 deletions

View File

@ -143,7 +143,7 @@ module.exports = {
'no-unused-vars': 0,
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_' },
{argsIgnorePattern: '^_'},
],
'func-call-spacing': 0,
'@typescript-eslint/func-call-spacing': 2,

1
.prettierrc.cjs Normal file
View File

@ -0,0 +1 @@
module.exports = require('gts/.prettierrc.json');

View File

@ -76,7 +76,7 @@ const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'example.png' });
await page.screenshot({path: 'example.png'});
await browser.close();
})();
@ -103,7 +103,7 @@ const puppeteer = require('puppeteer');
await page.goto('https://news.ycombinator.com', {
waitUntil: 'networkidle2',
});
await page.pdf({ path: 'hn.pdf', format: 'a4' });
await page.pdf({path: 'hn.pdf', format: 'a4'});
await browser.close();
})();
@ -163,7 +163,7 @@ See [`Page.evaluate()`](https://github.com/puppeteer/puppeteer/blob/main/docs/ap
Puppeteer launches Chromium in [headless mode](https://developers.google.com/web/updates/2017/04/headless-chrome). To launch a full version of Chromium, set the [`headless` option](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#puppeteerlaunchoptions) when launching a browser:
```js
const browser = await puppeteer.launch({ headless: false }); // default is true
const browser = await puppeteer.launch({headless: false}); // default is true
```
**2. Runs a bundled version of Chromium**
@ -173,7 +173,7 @@ is guaranteed to work out of the box. To use Puppeteer with a different version
pass in the executable's path when creating a `Browser` instance:
```js
const browser = await puppeteer.launch({ executablePath: '/path/to/Chrome' });
const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'});
```
You can also use Puppeteer with Firefox Nightly (experimental support). See [`Puppeteer.launch()`](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#puppeteerlaunchoptions) for more information.
@ -201,7 +201,7 @@ Puppeteer creates its own browser user profile which it **cleans up on every run
the browser using `headless: false`:
```js
const browser = await puppeteer.launch({ headless: false });
const browser = await puppeteer.launch({headless: false});
```
2. Slow it down - the `slowMo` option slows down Puppeteer operations by the
@ -218,7 +218,7 @@ Puppeteer creates its own browser user profile which it **cleans up on every run
This is also handy when debugging code in `page.evaluate()`:
```js
page.on('console', (msg) => console.log('PAGE LOG:', msg.text()));
page.on('console', msg => console.log('PAGE LOG:', msg.text()));
await page.evaluate(() => console.log(`url is ${location.href}`));
```
@ -232,7 +232,7 @@ Puppeteer creates its own browser user profile which it **cleans up on every run
- Use `{devtools: true}` when launching Puppeteer:
```js
const browser = await puppeteer.launch({ devtools: true });
const browser = await puppeteer.launch({devtools: true});
```
- Change default test timeout:

View File

@ -1,4 +1,4 @@
import { dirname } from 'path';
import {dirname} from 'path';
let puppeteerDirname: string;
@ -13,4 +13,4 @@ try {
puppeteerDirname = __dirname;
}
export { puppeteerDirname };
export {puppeteerDirname};

View File

@ -1,6 +1,6 @@
import { createRequire } from 'module';
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import {createRequire} from 'module';
import {dirname} from 'path';
import {fileURLToPath} from 'url';
const require = createRequire(import.meta.url);
@ -16,4 +16,4 @@ try {
puppeteerDirname = dirname(fileURLToPath(import.meta.url));
}
export { puppeteerDirname };
export {puppeteerDirname};

View File

@ -515,7 +515,7 @@ const puppeteer = require('puppeteer');
],
});
const backgroundPageTarget = await browser.waitForTarget(
(target) => target.type() === 'background_page'
target => target.type() === 'background_page'
);
const backgroundPage = await backgroundPageTarget.page();
// Test the background page as you would any other page.
@ -858,7 +858,7 @@ const puppeteer = require('puppeteer');
browser.disconnect();
// Use the endpoint to reestablish a connection
const browser2 = await puppeteer.connect({ browserWSEndpoint });
const browser2 = await puppeteer.connect({browserWSEndpoint});
// Close Chromium
await browser2.close();
})();
@ -1003,7 +1003,7 @@ An example of finding a target for a page opened via `window.open`:
```js
await page.evaluate(() => window.open('https://www.example.com/'));
const newWindowTarget = await browser.waitForTarget(
(target) => target.url() === 'https://www.example.com/'
target => target.url() === 'https://www.example.com/'
);
```
@ -1155,7 +1155,7 @@ An example of finding a target for a page opened via `window.open`:
```js
await page.evaluate(() => window.open('https://www.example.com/'));
const newWindowTarget = await browserContext.waitForTarget(
(target) => target.url() === 'https://www.example.com/'
target => target.url() === 'https://www.example.com/'
);
```
@ -1174,7 +1174,7 @@ const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'screenshot.png' });
await page.screenshot({path: 'screenshot.png'});
await browser.close();
})();
```
@ -1215,11 +1215,11 @@ The arguments passed into `console.log` appear as arguments on the event handler
An example of handling `console` event:
```js
page.on('console', (msg) => {
page.on('console', msg => {
for (let i = 0; i < msg.args().length; ++i)
console.log(`${i}: ${msg.args()[i]}`);
});
page.evaluate(() => console.log('hello', 5, { foo: 'bar' }));
page.evaluate(() => console.log('hello', 5, {foo: 'bar'}));
```
#### event: 'dialog'
@ -1286,14 +1286,14 @@ Emitted when the page opens a new tab or window.
```js
const [popup] = await Promise.all([
new Promise((resolve) => page.once('popup', resolve)),
new Promise(resolve => page.once('popup', resolve)),
page.click('a[target=_blank]'),
]);
```
```js
const [popup] = await Promise.all([
new Promise((resolve) => page.once('popup', resolve)),
new Promise(resolve => page.once('popup', resolve)),
page.evaluate(() => window.open('https://example.com')),
]);
```
@ -1369,12 +1369,12 @@ If `pageFunction` returns a [Promise], then `page.$$eval` would wait for the pro
Examples:
```js
const divCount = await page.$$eval('div', (divs) => divs.length);
const divCount = await page.$$eval('div', divs => divs.length);
```
```js
const options = await page.$$eval('div > span.options', (options) =>
options.map((option) => option.textContent)
const options = await page.$$eval('div > span.options', options =>
options.map(option => option.textContent)
);
```
@ -1392,9 +1392,9 @@ If `pageFunction` returns a [Promise], then `page.$eval` would wait for the prom
Examples:
```js
const searchValue = await page.$eval('#search', (el) => el.value);
const preloadHref = await page.$eval('link[rel=preload]', (el) => el.href);
const html = await page.$eval('.main-container', (e) => e.outerHTML);
const searchValue = await page.$eval('#search', el => el.value);
const preloadHref = await page.$eval('link[rel=preload]', el => el.href);
const html = await page.$eval('.main-container', e => e.outerHTML);
```
Shortcut for [page.mainFrame().$eval(selector, pageFunction)](#frameevalselector-pagefunction-args).
@ -1662,7 +1662,7 @@ const slow3G = puppeteer.networkConditions['Slow 3G'];
```js
await page.emulateMediaFeatures([
{ name: 'prefers-color-scheme', value: 'dark' },
{name: 'prefers-color-scheme', value: 'dark'},
]);
await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches);
// → true
@ -1670,7 +1670,7 @@ await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches);
// → false
await page.emulateMediaFeatures([
{ name: 'prefers-reduced-motion', value: 'reduce' },
{name: 'prefers-reduced-motion', value: 'reduce'},
]);
await page.evaluate(
() => matchMedia('(prefers-reduced-motion: reduce)').matches
@ -1682,8 +1682,8 @@ await page.evaluate(
// → false
await page.emulateMediaFeatures([
{ name: 'prefers-color-scheme', value: 'dark' },
{ name: 'prefers-reduced-motion', value: 'reduce' },
{name: 'prefers-color-scheme', value: 'dark'},
{name: 'prefers-reduced-motion', value: 'reduce'},
]);
await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches);
// → true
@ -1698,7 +1698,7 @@ await page.evaluate(
);
// → false
await page.emulateMediaFeatures([{ name: 'color-gamut', value: 'p3' }]);
await page.emulateMediaFeatures([{name: 'color-gamut', value: 'p3'}]);
await page.evaluate(() => matchMedia('(color-gamut: srgb)').matches);
// → true
await page.evaluate(() => matchMedia('(color-gamut: p3)').matches);
@ -1774,13 +1774,13 @@ const puppeteer = require('puppeteer');
await page.goto('https://v8.dev/blog/10-years');
await page.emulateVisionDeficiency('achromatopsia');
await page.screenshot({ path: 'achromatopsia.png' });
await page.screenshot({path: 'achromatopsia.png'});
await page.emulateVisionDeficiency('deuteranopia');
await page.screenshot({ path: 'deuteranopia.png' });
await page.screenshot({path: 'deuteranopia.png'});
await page.emulateVisionDeficiency('blurredVision');
await page.screenshot({ path: 'blurred-vision.png' });
await page.screenshot({path: 'blurred-vision.png'});
await browser.close();
})();
@ -1799,7 +1799,7 @@ If the function passed to the `page.evaluate` returns a non-[Serializable] value
Passing arguments to `pageFunction`:
```js
const result = await page.evaluate((x) => {
const result = await page.evaluate(x => {
return Promise.resolve(8 * x);
}, 7);
console.log(result); // prints "56"
@ -1817,7 +1817,7 @@ console.log(await page.evaluate(`1 + ${x}`)); // prints "11"
```js
const bodyHandle = await page.$('body');
const html = await page.evaluate((body) => body.innerHTML, bodyHandle);
const html = await page.evaluate(body => body.innerHTML, bodyHandle);
await bodyHandle.dispose();
```
@ -1843,10 +1843,7 @@ const aHandle = await page.evaluateHandle('document'); // Handle for the 'docume
```js
const aHandle = await page.evaluateHandle(() => document.body);
const resultHandle = await page.evaluateHandle(
(body) => body.innerHTML,
aHandle
);
const resultHandle = await page.evaluateHandle(body => body.innerHTML, aHandle);
console.log(await resultHandle.jsonValue());
await resultHandle.dispose();
```
@ -1915,8 +1912,8 @@ const crypto = require('crypto');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('console', (msg) => console.log(msg.text()));
await page.exposeFunction('md5', (text) =>
page.on('console', msg => console.log(msg.text()));
await page.exposeFunction('md5', text =>
crypto.createHash('md5').update(text).digest('hex')
);
await page.evaluate(async () => {
@ -1938,8 +1935,8 @@ const fs = require('fs');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('console', (msg) => console.log(msg.text()));
await page.exposeFunction('readfile', async (filePath) => {
page.on('console', msg => console.log(msg.text()));
await page.exposeFunction('readfile', async filePath => {
return new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf8', (err, text) => {
if (err) reject(err);
@ -2128,7 +2125,7 @@ Page is guaranteed to have a main frame which persists during navigations.
```js
// Generates a PDF with 'screen' media type.
await page.emulateMediaType('screen');
await page.pdf({ path: 'page.pdf' });
await page.pdf({path: 'page.pdf'});
```
The `width`, `height`, and `margin` options accept values labeled with units. Unlabeled values are treated as pixels.
@ -2180,7 +2177,7 @@ const mapPrototype = await page.evaluateHandle(() => Map.prototype);
// Query all map instances into an array
const mapInstances = await page.queryObjects(mapPrototype);
// Count amount of map objects in heap
const count = await page.evaluate((maps) => maps.length, mapInstances);
const count = await page.evaluate(maps => maps.length, mapInstances);
await mapInstances.dispose();
await mapPrototype.dispose();
```
@ -2343,7 +2340,7 @@ The extra HTTP headers will be sent with every request the page initiates.
Sets the page's geolocation.
```js
await page.setGeolocation({ latitude: 59.95, longitude: 30.31667 });
await page.setGeolocation({latitude: 59.95, longitude: 30.31667});
```
> **NOTE** Consider using [browserContext.overridePermissions](#browsercontextoverridepermissionsorigin-permissions) to grant permissions for the page to read its geolocation.
@ -2380,7 +2377,7 @@ const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', (interceptedRequest) => {
page.on('request', interceptedRequest => {
if (interceptedRequest.isInterceptResolutionHandled()) return;
if (
interceptedRequest.url().endsWith('.png') ||
@ -2411,7 +2408,7 @@ This example demonstrates two synchronous handlers working together:
/*
This first handler will succeed in calling request.continue because the request interception has never been resolved.
*/
page.on('request', (interceptedRequest) => {
page.on('request', interceptedRequest => {
if (interceptedRequest.isInterceptResolutionHandled()) return;
interceptedRequest.continue();
});
@ -2420,7 +2417,7 @@ page.on('request', (interceptedRequest) => {
This second handler will return before calling request.abort because request.continue was already
called by the first handler.
*/
page.on('request', (interceptedRequest) => {
page.on('request', interceptedRequest => {
if (interceptedRequest.isInterceptResolutionHandled()) return;
interceptedRequest.abort();
});
@ -2432,12 +2429,12 @@ This example demonstrates asynchronous handlers working together:
/*
This first handler will succeed in calling request.continue because the request interception has never been resolved.
*/
page.on('request', (interceptedRequest) => {
page.on('request', interceptedRequest => {
// The interception has not been handled yet. Control will pass through this guard.
if (interceptedRequest.isInterceptResolutionHandled()) return;
// It is not strictly necessary to return a promise, but doing so will allow Puppeteer to await this handler.
return new Promise((resolve) => {
return new Promise(resolve => {
// Continue after 500ms
setTimeout(() => {
// Inside, check synchronously to verify that the intercept wasn't handled already.
@ -2451,7 +2448,7 @@ page.on('request', (interceptedRequest) => {
}, 500);
});
});
page.on('request', async (interceptedRequest) => {
page.on('request', async interceptedRequest => {
// The interception has not been handled yet. Control will pass through this guard.
if (interceptedRequest.isInterceptResolutionHandled()) return;
@ -2471,18 +2468,18 @@ Here is the example above rewritten using `request.interceptResolutionState`
/*
This first handler will succeed in calling request.continue because the request interception has never been resolved.
*/
page.on('request', (interceptedRequest) => {
page.on('request', interceptedRequest => {
// The interception has not been handled yet. Control will pass through this guard.
const { action } = interceptedRequest.interceptResolutionState();
const {action} = interceptedRequest.interceptResolutionState();
if (action === InterceptResolutionAction.AlreadyHandled) return;
// It is not strictly necessary to return a promise, but doing so will allow Puppeteer to await this handler.
return new Promise((resolve) => {
return new Promise(resolve => {
// Continue after 500ms
setTimeout(() => {
// Inside, check synchronously to verify that the intercept wasn't handled already.
// It might have been handled during the 500ms while the other handler awaited an async op of its own.
const { action } = interceptedRequest.interceptResolutionState();
const {action} = interceptedRequest.interceptResolutionState();
if (action === InterceptResolutionAction.AlreadyHandled) {
resolve();
return;
@ -2492,7 +2489,7 @@ page.on('request', (interceptedRequest) => {
}, 500);
});
});
page.on('request', async (interceptedRequest) => {
page.on('request', async interceptedRequest => {
// The interception has not been handled yet. Control will pass through this guard.
if (
interceptedRequest.interceptResolutionState().action ===
@ -2534,13 +2531,13 @@ In this example, Legacy Mode prevails and the request is aborted immediately bec
```ts
// Final outcome: immediate abort()
page.setRequestInterception(true);
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
// Legacy Mode: interception is aborted immediately.
request.abort('failed');
});
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
// Control will never reach this point because the request was already aborted in Legacy Mode
@ -2554,13 +2551,13 @@ In this example, Legacy Mode prevails and the request is continued because at le
```ts
// Final outcome: immediate continue()
page.setRequestInterception(true);
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
// Cooperative Intercept Mode: votes to abort at priority 0.
request.abort('failed', 0);
});
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
// Control reaches this point because the request was cooperatively aborted which postpones resolution.
@ -2571,7 +2568,7 @@ page.on('request', (request) => {
// Legacy Mode: intercept continues immediately.
request.continue({});
});
page.on('request', (request) => {
page.on('request', request => {
// { action: InterceptResolutionAction.AlreadyHandled }, because continue in Legacy Mode was called
console.log(request.interceptResolutionState());
});
@ -2582,19 +2579,19 @@ In this example, Cooperative Intercept Mode is active because all handlers speci
```ts
// Final outcome: cooperative continue() @ 5
page.setRequestInterception(true);
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
// Cooperative Intercept Mode: votes to abort at priority 10
request.abort('failed', 0);
});
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
// Cooperative Intercept Mode: votes to continue at priority 5
request.continue(request.continueRequestOverrides(), 5);
});
page.on('request', (request) => {
page.on('request', request => {
// { action: InterceptResolutionAction.Continue, priority: 5 }, because continue @ 5 > abort @ 0
console.log(request.interceptResolutionState());
});
@ -2605,31 +2602,31 @@ In this example, Cooperative Intercept Mode is active because all handlers speci
```ts
// Final outcome: cooperative respond() @ 15
page.setRequestInterception(true);
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
// Cooperative Intercept Mode: votes to abort at priority 10
request.abort('failed', 10);
});
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
// Cooperative Intercept Mode: votes to continue at priority 15
request.continue(request.continueRequestOverrides(), 15);
});
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
// Cooperative Intercept Mode: votes to respond at priority 15
request.respond(request.responseForRequest(), 15);
});
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
// Cooperative Intercept Mode: votes to respond at priority 12
request.respond(request.responseForRequest(), 12);
});
page.on('request', (request) => {
page.on('request', request => {
// { action: InterceptResolutionAction.Respond, priority: 15 }, because respond @ 15 > continue @ 15 > respond @ 12 > abort @ 10
console.log(request.interceptResolutionState());
});
@ -2656,7 +2653,7 @@ To summarize, reason through whether your use of `request.continue` is just mean
If you are package maintainer and your package uses intercept handlers, you can update your intercept handlers to use Cooperative Intercept Mode. Suppose you have the following existing handler:
```ts
page.on('request', (interceptedRequest) => {
page.on('request', interceptedRequest => {
if (request.isInterceptResolutionHandled()) return;
if (
interceptedRequest.url().endsWith('.png') ||
@ -2670,7 +2667,7 @@ page.on('request', (interceptedRequest) => {
To use Cooperative Intercept Mode, upgrade `continue()` and `abort()`:
```ts
page.on('request', (interceptedRequest) => {
page.on('request', interceptedRequest => {
if (request.isInterceptResolutionHandled()) return;
if (
interceptedRequest.url().endsWith('.png') ||
@ -2706,7 +2703,7 @@ export const setInterceptResolutionConfig = (priority = 0) =>
* Note that this handler uses `DEFAULT_INTERCEPT_RESOLUTION_PRIORITY` to "pass" on this request. It is important to use
* the default priority when your handler has no opinion on the request and the intent is to continue() by default.
*/
page.on('request', (interceptedRequest) => {
page.on('request', interceptedRequest => {
if (request.isInterceptResolutionHandled()) return;
if (
interceptedRequest.url().endsWith('.png') ||
@ -2742,9 +2739,9 @@ let _config: Partial<InterceptResolutionConfig> = {};
export const setInterceptResolutionConfig = (
config: InterceptResolutionConfig
) => (_config = { ...DEFAULT_CONFIG, ...config });
) => (_config = {...DEFAULT_CONFIG, ...config});
page.on('request', (interceptedRequest) => {
page.on('request', interceptedRequest => {
if (request.isInterceptResolutionHandled()) return;
if (
interceptedRequest.url().endsWith('.png') ||
@ -2868,7 +2865,7 @@ To press a special key, like `Control` or `ArrowDown`, use [`keyboard.press`](#k
```js
await page.type('#mytextarea', 'Hello'); // Types instantly
await page.type('#mytextarea', 'World', { delay: 100 }); // Types slower, like a user
await page.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
```
Shortcut for [page.mainFrame().type(selector, text[, options])](#frametypeselector-text-options).
@ -2931,7 +2928,7 @@ To pass arguments from node.js to the predicate of `page.waitFor` function:
```js
const selector = '.foo';
await page.waitFor(
(selector) => !!document.querySelector(selector),
selector => !!document.querySelector(selector),
{},
selector
);
@ -2970,7 +2967,7 @@ await fileChooser.accept(['/tmp/myfile.pdf']);
- returns: <[Promise]<[Frame]>> Promise which resolves to the matched frame.
```js
const frame = await page.waitForFrame(async (frame) => {
const frame = await page.waitForFrame(async frame => {
return frame.name() === 'Test';
});
```
@ -2995,7 +2992,7 @@ const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
const watchDog = page.waitForFunction('window.innerWidth < 100');
await page.setViewport({ width: 50, height: 50 });
await page.setViewport({width: 50, height: 50});
await watchDog;
await browser.close();
})();
@ -3006,7 +3003,7 @@ To pass arguments from node.js to the predicate of `page.waitForFunction` functi
```js
const selector = '.foo';
await page.waitForFunction(
(selector) => !!document.querySelector(selector),
selector => !!document.querySelector(selector),
{},
selector
);
@ -3017,7 +3014,7 @@ The predicate of `page.waitForFunction` can be asynchronous too:
```js
const username = 'github-username';
await page.waitForFunction(
async (username) => {
async username => {
const githubResponse = await fetch(
`https://api.github.com/users/${username}`
);
@ -3083,7 +3080,7 @@ page.waitForNetworkIdle(); // The promise resolves after fetch above finishes
```js
const firstRequest = await page.waitForRequest('http://example.com/resource');
const finalRequest = await page.waitForRequest(
(request) =>
request =>
request.url() === 'http://example.com' && request.method() === 'GET'
);
return firstRequest.url();
@ -3101,10 +3098,10 @@ const firstResponse = await page.waitForResponse(
'https://example.com/resource'
);
const finalResponse = await page.waitForResponse(
(response) =>
response =>
response.url() === 'https://example.com' && response.status() === 200
);
const finalResponse = await page.waitForResponse(async (response) => {
const finalResponse = await page.waitForResponse(async response => {
return (await response.text()).includes('<html>');
});
return finalResponse.ok();
@ -3228,10 +3225,10 @@ The WebWorker class represents a [WebWorker](https://developer.mozilla.org/en-US
The events `workercreated` and `workerdestroyed` are emitted on the page object to signal the worker lifecycle.
```js
page.on('workercreated', (worker) =>
page.on('workercreated', worker =>
console.log('Worker created: ' + worker.url())
);
page.on('workerdestroyed', (worker) =>
page.on('workerdestroyed', worker =>
console.log('Worker destroyed: ' + worker.url())
);
@ -3435,7 +3432,7 @@ To press a special key, like `Control` or `ArrowDown`, use [`keyboard.press`](#k
```js
await page.keyboard.type('Hello'); // Types instantly
await page.keyboard.type('World', { delay: 100 }); // Types slower, like a user
await page.keyboard.type('World', {delay: 100}); // Types slower, like a user
```
> **NOTE** Modifier keys DO NOT affect `keyboard.type`. Holding down `Shift` will not type the text in upper case.
@ -3627,7 +3624,7 @@ await page.mouse.move(
boundingBox.y + boundingBox.height / 2
);
await page.mouse.wheel({ deltaY: -100 });
await page.mouse.wheel({deltaY: -100});
```
### class: Touchscreen
@ -3645,7 +3642,7 @@ Dispatches a `touchstart` and `touchend` event.
You can use [`tracing.start`](#tracingstartoptions) and [`tracing.stop`](#tracingstop) to create a trace file which can be opened in Chrome DevTools or [timeline viewer](https://chromedevtools.github.io/timeline-viewer/).
```js
await page.tracing.start({ path: 'trace.json' });
await page.tracing.start({path: 'trace.json'});
await page.goto('https://www.google.com');
await page.tracing.stop();
```
@ -3708,7 +3705,7 @@ const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('dialog', async (dialog) => {
page.on('dialog', async dialog => {
console.log(dialog.message());
await dialog.dismiss();
await browser.close();
@ -3804,8 +3801,8 @@ const puppeteer = require('puppeteer');
An example of getting text from an iframe element:
```js
const frame = page.frames().find((frame) => frame.name() === 'myframe');
const text = await frame.$eval('.selector', (element) => element.textContent);
const frame = page.frames().find(frame => frame.name() === 'myframe');
const text = await frame.$eval('.selector', element => element.textContent);
console.log(text);
```
@ -3837,7 +3834,7 @@ If `pageFunction` returns a [Promise], then `frame.$$eval` would wait for the pr
Examples:
```js
const divsCounts = await frame.$$eval('div', (divs) => divs.length);
const divsCounts = await frame.$$eval('div', divs => divs.length);
```
#### frame.$eval(selector, pageFunction[, ...args])
@ -3854,9 +3851,9 @@ If `pageFunction` returns a [Promise], then `frame.$eval` would wait for the pro
Examples:
```js
const searchValue = await frame.$eval('#search', (el) => el.value);
const preloadHref = await frame.$eval('link[rel=preload]', (el) => el.href);
const html = await frame.$eval('.main-container', (e) => e.outerHTML);
const searchValue = await frame.$eval('#search', el => el.value);
const preloadHref = await frame.$eval('link[rel=preload]', el => el.href);
const html = await frame.$eval('.main-container', e => e.outerHTML);
```
#### frame.$x(expression)
@ -3946,7 +3943,7 @@ console.log(await frame.evaluate('1 + 2')); // prints "3"
```js
const bodyHandle = await frame.$('body');
const html = await frame.evaluate((body) => body.innerHTML, bodyHandle);
const html = await frame.evaluate(body => body.innerHTML, bodyHandle);
await bodyHandle.dispose();
```
@ -3978,7 +3975,7 @@ const aHandle = await frame.evaluateHandle('document'); // Handle for the 'docum
```js
const aHandle = await frame.evaluateHandle(() => document.body);
const resultHandle = await frame.evaluateHandle(
(body) => body.innerHTML,
body => body.innerHTML,
aHandle
);
console.log(await resultHandle.jsonValue());
@ -4112,7 +4109,7 @@ To press a special key, like `Control` or `ArrowDown`, use [`keyboard.press`](#k
```js
await frame.type('#mytextarea', 'Hello'); // Types instantly
await frame.type('#mytextarea', 'World', { delay: 100 }); // Types slower, like a user
await frame.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
```
#### frame.url()
@ -4157,7 +4154,7 @@ To pass arguments from node.js to the predicate of `page.waitFor` function:
```js
const selector = '.foo';
await page.waitFor(
(selector) => !!document.querySelector(selector),
selector => !!document.querySelector(selector),
{},
selector
);
@ -4183,7 +4180,7 @@ const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
const watchDog = page.mainFrame().waitForFunction('window.innerWidth < 100');
page.setViewport({ width: 50, height: 50 });
page.setViewport({width: 50, height: 50});
await watchDog;
await browser.close();
})();
@ -4194,7 +4191,7 @@ To pass arguments from node.js to the predicate of `page.waitForFunction` functi
```js
const selector = '.foo';
await page.waitForFunction(
(selector) => !!document.querySelector(selector),
selector => !!document.querySelector(selector),
{},
selector
);
@ -4395,7 +4392,7 @@ const aHandle = await context.evaluateHandle('1 + 2'); // Handle for the '3' obj
```js
const aHandle = await context.evaluateHandle(() => document.body);
const resultHandle = await context.evaluateHandle(
(body) => body.innerHTML,
body => body.innerHTML,
aHandle
);
console.log(await resultHandle.jsonValue()); // prints body's innerHTML
@ -4424,7 +4421,7 @@ const mapPrototype = await page.evaluateHandle(() => Map.prototype);
// Query all map instances into an array
const mapInstances = await page.queryObjects(mapPrototype);
// Count amount of map objects in heap
const count = await page.evaluate((maps) => maps.length, mapInstances);
const count = await page.evaluate(maps => maps.length, mapInstances);
await mapInstances.dispose();
await mapPrototype.dispose();
```
@ -4468,7 +4465,7 @@ Examples:
```js
const tweetHandle = await page.$('.tweet .retweets');
expect(await tweetHandle.evaluate((node) => node.innerText)).toBe('10');
expect(await tweetHandle.evaluate(node => node.innerText)).toBe('10');
```
#### jsHandle.evaluateHandle(pageFunction[, ...args])
@ -4500,7 +4497,7 @@ Returns execution context the handle belongs to.
The method returns a map with property names as keys and JSHandle instances for the property values.
```js
const handle = await page.evaluateHandle(() => ({ window, document }));
const handle = await page.evaluateHandle(() => ({window, document}));
const properties = await handle.getProperties();
const windowHandle = properties.get('window');
const documentHandle = properties.get('document');
@ -4584,7 +4581,7 @@ Examples:
```js
const feedHandle = await page.$('.feed');
expect(
await feedHandle.$$eval('.tweet', (nodes) => nodes.map((n) => n.innerText))
await feedHandle.$$eval('.tweet', nodes => nodes.map(n => n.innerText))
).toEqual(['Hello!', 'Hi!']);
```
@ -4603,10 +4600,8 @@ Examples:
```js
const tweetHandle = await page.$('.tweet');
expect(await tweetHandle.$eval('.like', (node) => node.innerText)).toBe('100');
expect(await tweetHandle.$eval('.retweets', (node) => node.innerText)).toBe(
'10'
);
expect(await tweetHandle.$eval('.like', node => node.innerText)).toBe('100');
expect(await tweetHandle.$eval('.retweets', node => node.innerText)).toBe('10');
```
#### elementHandle.$x(expression)
@ -4740,7 +4735,7 @@ Examples:
```js
const tweetHandle = await page.$('.tweet .retweets');
expect(await tweetHandle.evaluate((node) => node.innerText)).toBe('10');
expect(await tweetHandle.evaluate(node => node.innerText)).toBe('10');
```
#### elementHandle.evaluateHandle(pageFunction[, ...args])
@ -4873,7 +4868,7 @@ To press a special key, like `Control` or `ArrowDown`, use [`elementHandle.press
```js
await elementHandle.type('Hello'); // Types instantly
await elementHandle.type('World', { delay: 100 }); // Types slower, like a user
await elementHandle.type('World', {delay: 100}); // Types slower, like a user
```
An example of typing into a text field and then submitting the form:
@ -5005,7 +5000,7 @@ your handler has no opinion about it.
```js
await page.setRequestInterception(true);
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
// Override headers
@ -5013,7 +5008,7 @@ page.on('request', (request) => {
foo: 'bar', // set "foo" header
origin: undefined, // remove "origin" header
});
request.continue({ headers });
request.continue({headers});
});
```
@ -5044,7 +5039,7 @@ The method returns `null` unless this request was failed, as reported by
Example of logging all failed requests:
```js
page.on('requestfailed', (request) => {
page.on('requestfailed', request => {
console.log(request.url() + ' ' + request.failure().errorText);
});
```
@ -5091,8 +5086,8 @@ This example will `continue()` a request at a slightly higher priority than the
already handled and is not already being continued.
```js
page.on('request', (interceptedRequest) => {
const { action, priority } = interceptedRequest.interceptResolutionState();
page.on('request', interceptedRequest => {
const {action, priority} = interceptedRequest.interceptResolutionState();
if (action === InterceptResolutionAction.AlreadyHandled) return;
if (action === InterceptResolutionAction.Continue) return;
@ -5180,7 +5175,7 @@ An example of fulfilling all requests with 404 responses:
```js
await page.setRequestInterception(true);
page.on('request', (request) => {
page.on('request', request => {
if (request.isInterceptResolutionHandled()) return;
request.respond({

View File

@ -22,7 +22,7 @@ const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', (request) => {
page.on('request', request => {
if (request.resourceType() === 'image') {
request.abort();
} else {
@ -30,7 +30,7 @@ const puppeteer = require('puppeteer');
}
});
await page.goto('https://news.google.com/news/');
await page.screenshot({ path: 'news.png', fullPage: true });
await page.screenshot({path: 'news.png', fullPage: true});
await browser.close();
})();

View File

@ -35,9 +35,9 @@ const firefoxOptions = {
// Extract articles from the page.
const resultsSelector = '.titlelink';
const links = await page.evaluate((resultsSelector) => {
const links = await page.evaluate(resultsSelector => {
const anchors = Array.from(document.querySelectorAll(resultsSelector));
return anchors.map((anchor) => {
return anchors.map(anchor => {
const title = anchor.textContent.trim();
return `${title} - ${anchor.href}`;
});

View File

@ -23,7 +23,7 @@ const puppeteer = require('puppeteer');
const page = await browser.newPage();
// Define a window.onCustomEvent function on the page.
await page.exposeFunction('onCustomEvent', (e) => {
await page.exposeFunction('onCustomEvent', e => {
console.log(`${e.type} fired`, e.detail || '');
});
@ -33,9 +33,9 @@ const puppeteer = require('puppeteer');
* @returns {!Promise}
*/
function listenFor(type) {
return page.evaluateOnNewDocument((type) => {
document.addEventListener(type, (e) => {
window.onCustomEvent({ type, detail: e.detail });
return page.evaluateOnNewDocument(type => {
document.addEventListener(type, e => {
window.onCustomEvent({type, detail: e.detail});
});
}, type);
}

View File

@ -37,7 +37,7 @@ function sniffDetector() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.evaluateOnNewDocument(sniffDetector);
await page.goto('https://www.google.com', { waitUntil: 'networkidle2' });
await page.goto('https://www.google.com', {waitUntil: 'networkidle2'});
console.log(
'Sniffed: ' +
(await page.evaluate(() => {

View File

@ -23,7 +23,7 @@ async function attachFrame(frameId, url) {
frame.src = url;
frame.id = frameId;
document.body.appendChild(frame);
await new Promise((x) => {
await new Promise(x => {
return (frame.onload = x);
});
return frame;
@ -31,7 +31,7 @@ async function attachFrame(frameId, url) {
(async () => {
// Launch browser in non-headless mode.
const browser = await puppeteer.launch({ headless: false });
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
// Load a page from one origin:

View File

@ -23,6 +23,6 @@ const puppeteer = require('puppeteer');
const page = await browser.newPage();
await page.emulate(puppeteer.devices['iPhone 6']);
await page.goto('https://www.nytimes.com/');
await page.screenshot({ path: 'full.png', fullPage: true });
await page.screenshot({path: 'full.png', fullPage: true});
await browser.close();
})();

View File

@ -22,6 +22,6 @@ const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('http://example.com');
await page.screenshot({ path: 'example.png' });
await page.screenshot({path: 'example.png'});
await browser.close();
})();

View File

@ -42,9 +42,9 @@ const puppeteer = require('puppeteer');
await page.waitForSelector(resultsSelector);
// Extract the results from the page.
const links = await page.evaluate((resultsSelector) => {
const links = await page.evaluate(resultsSelector => {
const anchors = Array.from(document.querySelectorAll(resultsSelector));
return anchors.map((anchor) => {
return anchors.map(anchor => {
const title = anchor.textContent.split('|')[0].trim();
return `${title} - ${anchor.href}`;
});

View File

@ -114,8 +114,9 @@
"eslint-plugin-tsdoc": "0.2.16",
"esprima": "4.0.1",
"expect": "25.2.7",
"gts": "3.1.0",
"husky": "8.0.1",
"jpeg-js": "0.4.3",
"jpeg-js": "0.4.4",
"mime": "3.0.0",
"minimist": "1.2.6",
"mocha": "10.0.0",

View File

@ -1,5 +0,0 @@
module.exports = {
semi: true,
trailingComma: 'es5',
singleQuote: true,
};

View File

@ -34,8 +34,8 @@
*/
// eslint-disable-next-line import/extensions
import { PUPPETEER_REVISIONS } from '../src/revisions';
import { execSync } from 'child_process';
import {PUPPETEER_REVISIONS} from '../src/revisions';
import {execSync} from 'child_process';
import packageJson from '../package.json';

View File

@ -16,7 +16,7 @@
import packageJson from '../package.json';
const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies };
const allDeps = {...packageJson.dependencies, ...packageJson.devDependencies};
const invalidDeps = new Map<string, string>();
@ -32,7 +32,7 @@ if (invalidDeps.size > 0) {
console.error('Found non-pinned dependencies in package.json:');
console.log(
[...invalidDeps.keys()]
.map((k) => {
.map(k => {
return ` ${k}`;
})
.join('\n')

View File

@ -1,5 +1,5 @@
import { spawnSync } from 'child_process';
import { version } from '../package.json';
import {spawnSync} from 'child_process';
import {version} from '../package.json';
import path from 'path';
import fs from 'fs';
const PROJECT_FOLDERS_ROOT = 'test-ts-types';
@ -108,7 +108,7 @@ const tar = packPuppeteer();
const tarPath = path.join(process.cwd(), tar);
function compileAndCatchErrors(projectLocation: string) {
const { status, stdout, stderr } = spawnSync('npm', ['run', 'compile'], {
const {status, stdout, stderr} = spawnSync('npm', ['run', 'compile'], {
cwd: projectLocation,
encoding: 'utf-8',
});
@ -146,18 +146,14 @@ function testProject(folder: string) {
// there was no node_modules folder, which is fine.
}
console.log('===> Installing Puppeteer from tar file', tarLocation);
const { status, stderr, stdout } = spawnSync(
'npm',
['install', tarLocation],
{
env: {
...process.env,
PUPPETEER_SKIP_DOWNLOAD: '1',
},
cwd: projectLocation,
encoding: 'utf-8',
}
);
const {status, stderr, stdout} = spawnSync('npm', ['install', tarLocation], {
env: {
...process.env,
PUPPETEER_SKIP_DOWNLOAD: '1',
},
cwd: projectLocation,
encoding: 'utf-8',
});
if (status) {
console.error(
@ -171,7 +167,7 @@ function testProject(folder: string) {
const result = compileAndCatchErrors(projectLocation);
const expectedErrors = EXPECTED_ERRORS.get(folder) || [];
if (
result.tsErrorMesssage.find((line) => {
result.tsErrorMesssage.find(line => {
return line.includes('good.ts') || line.includes('good.js');
})
) {
@ -182,12 +178,12 @@ function testProject(folder: string) {
);
process.exit(1);
}
const errorsInTsMessage = result.tsErrorMesssage.filter((line) => {
const errorsInTsMessage = result.tsErrorMesssage.filter(line => {
return line.includes('bad.ts') || line.includes('bad.js');
});
const expectedErrorsThatHaveOccurred = new Set<string>();
const unexpectedErrors = errorsInTsMessage.filter((message) => {
const isExpected = expectedErrors.some((expectedError) => {
const unexpectedErrors = errorsInTsMessage.filter(message => {
const isExpected = expectedErrors.some(expectedError => {
const isExpected = message.startsWith(expectedError);
if (isExpected) {
expectedErrorsThatHaveOccurred.add(expectedError);
@ -205,7 +201,7 @@ function testProject(folder: string) {
);
process.exit(1);
}
expectedErrors.forEach((expected) => {
expectedErrors.forEach(expected => {
if (!expectedErrorsThatHaveOccurred.has(expected)) {
console.error(
`${projectLocation} expected error that was not thrown: ${expected}`
@ -216,6 +212,6 @@ function testProject(folder: string) {
console.log('===> ✅ Type-checked correctly.');
}
PROJECT_FOLDERS.forEach((folder) => {
PROJECT_FOLDERS.forEach(folder => {
testProject(folder);
});

View File

@ -18,14 +18,14 @@ import {
LaunchOptions,
BrowserLaunchArgumentOptions,
} from './node/LaunchOptions.js';
import { BrowserConnectOptions } from './common/BrowserConnector.js';
import { Product } from './common/Product.js';
import { Browser } from './common/Browser.js';
import { ConnectOptions } from './common/Puppeteer.js';
import { DevicesMap } from './common/DeviceDescriptors.js';
import { PuppeteerErrors } from './common/Errors.js';
import { PredefinedNetworkConditions } from './common/NetworkConditions.js';
import { CustomQueryHandler } from './common/QueryHandler.js';
import {BrowserConnectOptions} from './common/BrowserConnector.js';
import {Product} from './common/Product.js';
import {Browser} from './common/Browser.js';
import {ConnectOptions} from './common/Puppeteer.js';
import {DevicesMap} from './common/DeviceDescriptors.js';
import {PuppeteerErrors} from './common/Errors.js';
import {PredefinedNetworkConditions} from './common/NetworkConditions.js';
import {CustomQueryHandler} from './common/QueryHandler.js';
/*
* This file re-exports any APIs that we want to have documentation generated

View File

@ -14,9 +14,9 @@
* limitations under the License.
*/
import { CDPSession } from './Connection.js';
import { ElementHandle } from './JSHandle.js';
import { Protocol } from 'devtools-protocol';
import {CDPSession} from './Connection.js';
import {ElementHandle} from './JSHandle.js';
import {Protocol} from 'devtools-protocol';
/**
* Represents a Node and the properties of it that are relevant to Accessibility.
@ -181,11 +181,11 @@ export class Accessibility {
public async snapshot(
options: SnapshotOptions = {}
): Promise<SerializedAXNode | null> {
const { interestingOnly = true, root = null } = options;
const { nodes } = await this.#client.send('Accessibility.getFullAXTree');
const {interestingOnly = true, root = null} = options;
const {nodes} = await this.#client.send('Accessibility.getFullAXTree');
let backendNodeId: number | undefined;
if (root) {
const { node } = await this.#client.send('DOM.describeNode', {
const {node} = await this.#client.send('DOM.describeNode', {
objectId: root._remoteObject.objectId,
});
backendNodeId = node.backendNodeId;
@ -193,7 +193,7 @@ export class Accessibility {
const defaultRoot = AXNode.createTree(nodes);
let needle: AXNode | null = defaultRoot;
if (backendNodeId) {
needle = defaultRoot.find((node) => {
needle = defaultRoot.find(node => {
return node.payload.backendDOMNodeId === backendNodeId;
});
if (!needle) {

View File

@ -14,12 +14,12 @@
* limitations under the License.
*/
import { InternalQueryHandler } from './QueryHandler.js';
import { ElementHandle, JSHandle } from './JSHandle.js';
import { Protocol } from 'devtools-protocol';
import { CDPSession } from './Connection.js';
import { DOMWorld, PageBinding, WaitForSelectorOptions } from './DOMWorld.js';
import { assert } from './assert.js';
import {InternalQueryHandler} from './QueryHandler.js';
import {ElementHandle, JSHandle} from './JSHandle.js';
import {Protocol} from 'devtools-protocol';
import {CDPSession} from './Connection.js';
import {DOMWorld, PageBinding, WaitForSelectorOptions} from './DOMWorld.js';
import {assert} from './assert.js';
async function queryAXTree(
client: CDPSession,
@ -27,7 +27,7 @@ async function queryAXTree(
accessibleName?: string,
role?: string
): Promise<Protocol.Accessibility.AXNode[]> {
const { nodes } = await client.send('Accessibility.queryAXTree', {
const {nodes} = await client.send('Accessibility.queryAXTree', {
objectId: element._remoteObject.objectId,
accessibleName,
role,
@ -47,7 +47,7 @@ const knownAttributes = new Set(['name', 'role']);
const attributeRegexp =
/\[\s*(?<attribute>\w+)\s*=\s*(?<quote>"|')(?<value>\\.|.*?(?=\k<quote>))\k<quote>\s*\]/g;
type ARIAQueryOption = { name?: string; role?: string };
type ARIAQueryOption = {name?: string; role?: string};
function isKnownAttribute(
attribute: string
): attribute is keyof ARIAQueryOption {
@ -89,7 +89,7 @@ const queryOne = async (
selector: string
): Promise<ElementHandle | null> => {
const exeCtx = element.executionContext();
const { name, role } = parseAriaSelector(selector);
const {name, role} = parseAriaSelector(selector);
const res = await queryAXTree(exeCtx._client, element, name, role);
if (!res[0] || !res[0].backendDOMNodeId) {
return null;
@ -129,10 +129,10 @@ const queryAll = async (
selector: string
): Promise<ElementHandle[]> => {
const exeCtx = element.executionContext();
const { name, role } = parseAriaSelector(selector);
const {name, role} = parseAriaSelector(selector);
const res = await queryAXTree(exeCtx._client, element, name, role);
return Promise.all(
res.map((axNode) => {
res.map(axNode => {
return exeCtx._adoptBackendNodeId(axNode.backendDOMNodeId);
})
);

View File

@ -14,16 +14,16 @@
* limitations under the License.
*/
import { ChildProcess } from 'child_process';
import { Protocol } from 'devtools-protocol';
import { assert } from './assert.js';
import { Connection, ConnectionEmittedEvents } from './Connection.js';
import { EventEmitter } from './EventEmitter.js';
import { waitWithTimeout } from './util.js';
import { Page } from './Page.js';
import { Viewport } from './PuppeteerViewport.js';
import { Target } from './Target.js';
import { TaskQueue } from './TaskQueue.js';
import {ChildProcess} from 'child_process';
import {Protocol} from 'devtools-protocol';
import {assert} from './assert.js';
import {Connection, ConnectionEmittedEvents} from './Connection.js';
import {EventEmitter} from './EventEmitter.js';
import {waitWithTimeout} from './util.js';
import {Page} from './Page.js';
import {Viewport} from './PuppeteerViewport.js';
import {Target} from './Target.js';
import {TaskQueue} from './TaskQueue.js';
/**
* BrowserContext options.
@ -237,7 +237,7 @@ export class Browser extends EventEmitter {
targetFilterCallback,
isPageTargetCallback
);
await connection.send('Target.setDiscoverTargets', { discover: true });
await connection.send('Target.setDiscoverTargets', {discover: true});
return browser;
}
#ignoreHTTPSErrors: boolean;
@ -358,9 +358,9 @@ export class Browser extends EventEmitter {
async createIncognitoBrowserContext(
options: BrowserContextOptions = {}
): Promise<BrowserContext> {
const { proxyServer, proxyBypassList } = options;
const {proxyServer, proxyBypassList} = options;
const { browserContextId } = await this.#connection.send(
const {browserContextId} = await this.#connection.send(
'Target.createBrowserContext',
{
proxyServer,
@ -408,7 +408,7 @@ export class Browser extends EventEmitter {
event: Protocol.Target.TargetCreatedEvent
): Promise<void> {
const targetInfo = event.targetInfo;
const { browserContextId } = targetInfo;
const {browserContextId} = targetInfo;
const context =
browserContextId && this.#contexts.has(browserContextId)
? this.#contexts.get(browserContextId)
@ -447,7 +447,7 @@ export class Browser extends EventEmitter {
}
}
async #targetDestroyed(event: { targetId: string }): Promise<void> {
async #targetDestroyed(event: {targetId: string}): Promise<void> {
if (this.#ignoredTargets.has(event.targetId)) {
return;
}
@ -522,7 +522,7 @@ export class Browser extends EventEmitter {
* @internal
*/
async _createPageInContext(contextId?: string): Promise<Page> {
const { targetId } = await this.#connection.send('Target.createTarget', {
const {targetId} = await this.#connection.send('Target.createTarget', {
url: 'about:blank',
browserContextId: contextId || undefined,
});
@ -548,7 +548,7 @@ export class Browser extends EventEmitter {
* an array with all the targets in all browser contexts.
*/
targets(): Target[] {
return Array.from(this.#targets.values()).filter((target) => {
return Array.from(this.#targets.values()).filter(target => {
return target._isInitialized;
});
}
@ -557,7 +557,7 @@ export class Browser extends EventEmitter {
* The target associated with the browser.
*/
target(): Target {
const browserTarget = this.targets().find((target) => {
const browserTarget = this.targets().find(target => {
return target.type() === 'browser';
});
if (!browserTarget) {
@ -584,10 +584,10 @@ export class Browser extends EventEmitter {
predicate: (x: Target) => boolean | Promise<boolean>,
options: WaitForTargetOptions = {}
): Promise<Target> {
const { timeout = 30000 } = options;
const {timeout = 30000} = options;
let resolve: (value: Target | PromiseLike<Target>) => void;
let isResolved = false;
const targetPromise = new Promise<Target>((x) => {
const targetPromise = new Promise<Target>(x => {
return (resolve = x);
});
this.on(BrowserEmittedEvents.TargetCreated, check);
@ -622,7 +622,7 @@ export class Browser extends EventEmitter {
*/
async pages(): Promise<Page[]> {
const contextPages = await Promise.all(
this.browserContexts().map((context) => {
this.browserContexts().map(context => {
return context.pages();
})
);
@ -762,7 +762,7 @@ export class BrowserContext extends EventEmitter {
* An array of all active targets inside the browser context.
*/
targets(): Target[] {
return this.#browser.targets().filter((target) => {
return this.#browser.targets().filter(target => {
return target.browserContext() === this;
});
}
@ -786,9 +786,9 @@ export class BrowserContext extends EventEmitter {
*/
waitForTarget(
predicate: (x: Target) => boolean | Promise<boolean>,
options: { timeout?: number } = {}
options: {timeout?: number} = {}
): Promise<Target> {
return this.#browser.waitForTarget((target) => {
return this.#browser.waitForTarget(target => {
return target.browserContext() === this && predicate(target);
}, options);
}
@ -803,7 +803,7 @@ export class BrowserContext extends EventEmitter {
async pages(): Promise<Page[]> {
const pages = await Promise.all(
this.targets()
.filter((target) => {
.filter(target => {
return (
target.type() === 'page' ||
(target.type() === 'other' &&
@ -812,7 +812,7 @@ export class BrowserContext extends EventEmitter {
))
);
})
.map((target) => {
.map(target => {
return target.page();
})
);
@ -847,7 +847,7 @@ export class BrowserContext extends EventEmitter {
origin: string,
permissions: Permission[]
): Promise<void> {
const protocolPermissions = permissions.map((permission) => {
const protocolPermissions = permissions.map(permission => {
const protocolPermission =
WEB_PERMISSION_TO_PROTOCOL_PERMISSION.get(permission);
if (!protocolPermission) {

View File

@ -14,18 +14,18 @@
* limitations under the License.
*/
import { debugError, isErrorLike } from './util.js';
import { isNode } from '../environment.js';
import { assert } from './assert.js';
import {debugError, isErrorLike} from './util.js';
import {isNode} from '../environment.js';
import {assert} from './assert.js';
import {
Browser,
IsPageTargetCallback,
TargetFilterCallback,
} from './Browser.js';
import { Connection } from './Connection.js';
import { ConnectionTransport } from './ConnectionTransport.js';
import { getFetch } from './fetch.js';
import { Viewport } from './PuppeteerViewport.js';
import {Connection} from './Connection.js';
import {ConnectionTransport} from './ConnectionTransport.js';
import {getFetch} from './fetch.js';
import {Viewport} from './PuppeteerViewport.js';
/**
* Generic browser options that can be passed when launching any browser or when
@ -81,7 +81,7 @@ export async function _connectToBrowser(
browserWSEndpoint,
browserURL,
ignoreHTTPSErrors = false,
defaultViewport = { width: 800, height: 600 },
defaultViewport = {width: 800, height: 600},
transport,
slowMo = 0,
targetFilter,
@ -110,7 +110,7 @@ export async function _connectToBrowser(
connection = new Connection(connectionURL, connectionTransport, slowMo);
}
const { browserContextIds } = await connection.send(
const {browserContextIds} = await connection.send(
'Target.getBrowserContexts'
);
return Browser._create(

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ConnectionTransport } from './ConnectionTransport.js';
import {ConnectionTransport} from './ConnectionTransport.js';
export class BrowserWebSocketTransport implements ConnectionTransport {
static create(url: string): Promise<BrowserWebSocketTransport> {
@ -33,7 +33,7 @@ export class BrowserWebSocketTransport implements ConnectionTransport {
constructor(ws: WebSocket) {
this.#ws = ws;
this.#ws.addEventListener('message', (event) => {
this.#ws.addEventListener('message', event => {
if (this.onmessage) {
this.onmessage.call(null, event.data);
}

View File

@ -13,21 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { assert } from './assert.js';
import { debug } from './Debug.js';
import {assert} from './assert.js';
import {debug} from './Debug.js';
const debugProtocolSend = debug('puppeteer:protocol:SEND ►');
const debugProtocolReceive = debug('puppeteer:protocol:RECV ◀');
import { Protocol } from 'devtools-protocol';
import { ProtocolMapping } from 'devtools-protocol/types/protocol-mapping.js';
import { ConnectionTransport } from './ConnectionTransport.js';
import { EventEmitter } from './EventEmitter.js';
import { ProtocolError } from './Errors.js';
import {Protocol} from 'devtools-protocol';
import {ProtocolMapping} from 'devtools-protocol/types/protocol-mapping.js';
import {ConnectionTransport} from './ConnectionTransport.js';
import {EventEmitter} from './EventEmitter.js';
import {ProtocolError} from './Errors.js';
/**
* @public
*/
export { ConnectionTransport, ProtocolMapping };
export {ConnectionTransport, ProtocolMapping};
/**
* @public
@ -104,7 +104,7 @@ export class Connection extends EventEmitter {
// type-inference.
// So now we check if there are any params or not and deal with them accordingly.
const params = paramArgs.length ? paramArgs[0] : undefined;
const id = this._rawSend({ method, params });
const id = this._rawSend({method, params});
return new Promise((resolve, reject) => {
this.#callbacks.set(id, {
resolve,
@ -120,9 +120,7 @@ export class Connection extends EventEmitter {
*/
_rawSend(message: Record<string, unknown>): number {
const id = ++this.#lastId;
const stringifiedMessage = JSON.stringify(
Object.assign({}, message, { id })
);
const stringifiedMessage = JSON.stringify(Object.assign({}, message, {id}));
debugProtocolSend(stringifiedMessage);
this.#transport.send(stringifiedMessage);
return id;
@ -130,7 +128,7 @@ export class Connection extends EventEmitter {
async #onMessage(message: string): Promise<void> {
if (this.#delay) {
await new Promise((f) => {
await new Promise(f => {
return setTimeout(f, this.#delay);
});
}
@ -219,7 +217,7 @@ export class Connection extends EventEmitter {
async createSession(
targetInfo: Protocol.Target.TargetInfo
): Promise<CDPSession> {
const { sessionId } = await this.send('Target.attachToTarget', {
const {sessionId} = await this.send('Target.attachToTarget', {
targetId: targetInfo.targetId,
flatten: true,
});
@ -238,7 +236,7 @@ export interface CDPSessionOnMessageObject {
id?: number;
method: string;
params: Record<string, unknown>;
error: { message: string; data: any; code: number };
error: {message: string; data: any; code: number};
result?: any;
}
@ -394,7 +392,7 @@ export class CDPSession extends EventEmitter {
function createProtocolError(
error: ProtocolError,
method: string,
object: { error: { message: string; data: any; code: number } }
object: {error: {message: string; data: any; code: number}}
): Error {
let message = `Protocol error (${method}): ${object.error.message}`;
if ('data' in object.error) {

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { JSHandle } from './JSHandle.js';
import {JSHandle} from './JSHandle.js';
/**
* @public

View File

@ -14,22 +14,18 @@
* limitations under the License.
*/
import { assert } from './assert.js';
import {
addEventListener,
debugError,
PuppeteerEventListener,
} from './util.js';
import { Protocol } from 'devtools-protocol';
import { CDPSession } from './Connection.js';
import {assert} from './assert.js';
import {addEventListener, debugError, PuppeteerEventListener} from './util.js';
import {Protocol} from 'devtools-protocol';
import {CDPSession} from './Connection.js';
import { EVALUATION_SCRIPT_URL } from './ExecutionContext.js';
import { removeEventListeners } from './util.js';
import {EVALUATION_SCRIPT_URL} from './ExecutionContext.js';
import {removeEventListeners} from './util.js';
/**
* @internal
*/
export { PuppeteerEventListener };
export {PuppeteerEventListener};
/**
* The CoverageEntry class represents one entry of the coverage report.
@ -47,7 +43,7 @@ export interface CoverageEntry {
/**
* The covered range as start and end positions.
*/
ranges: Array<{ start: number; end: number }>;
ranges: Array<{start: number; end: number}>;
}
/**
@ -239,7 +235,7 @@ export class JSCoverage {
detailed: true,
}),
this.#client.send('Debugger.enable'),
this.#client.send('Debugger.setSkipAllPauses', { skip: true }),
this.#client.send('Debugger.setSkipAllPauses', {skip: true}),
]);
}
@ -305,9 +301,9 @@ export class JSCoverage {
}
const ranges = convertToDisjointRanges(flattenRanges);
if (!this.#includeRawScriptCoverage) {
coverage.push({ url, ranges, text });
coverage.push({url, ranges, text});
} else {
coverage.push({ url, ranges, text, rawScriptCoverage: entry });
coverage.push({url, ranges, text, rawScriptCoverage: entry});
}
}
return coverage;
@ -329,9 +325,9 @@ export class CSSCoverage {
this.#client = client;
}
async start(options: { resetOnNavigation?: boolean } = {}): Promise<void> {
async start(options: {resetOnNavigation?: boolean} = {}): Promise<void> {
assert(!this.#enabled, 'CSSCoverage is already enabled');
const { resetOnNavigation = true } = options;
const {resetOnNavigation = true} = options;
this.#resetOnNavigation = resetOnNavigation;
this.#enabled = true;
this.#stylesheetURLs.clear();
@ -417,7 +413,7 @@ export class CSSCoverage {
const ranges = convertToDisjointRanges(
styleSheetIdToCoverage.get(styleSheetId) || []
);
coverage.push({ url, ranges, text });
coverage.push({url, ranges, text});
}
return coverage;
@ -425,12 +421,12 @@ export class CSSCoverage {
}
function convertToDisjointRanges(
nestedRanges: Array<{ startOffset: number; endOffset: number; count: number }>
): Array<{ start: number; end: number }> {
nestedRanges: Array<{startOffset: number; endOffset: number; count: number}>
): Array<{start: number; end: number}> {
const points = [];
for (const range of nestedRanges) {
points.push({ offset: range.startOffset, type: 0, range });
points.push({ offset: range.endOffset, type: 1, range });
points.push({offset: range.startOffset, type: 0, range});
points.push({offset: range.endOffset, type: 1, range});
}
// Sort points to form a valid parenthesis sequence.
points.sort((a, b) => {
@ -469,7 +465,7 @@ function convertToDisjointRanges(
if (lastResult && lastResult.end === lastOffset) {
lastResult.end = point.offset;
} else {
results.push({ start: lastOffset, end: point.offset });
results.push({start: lastOffset, end: point.offset});
}
}
lastOffset = point.offset;
@ -480,7 +476,7 @@ function convertToDisjointRanges(
}
}
// Filter out empty ranges.
return results.filter((range) => {
return results.filter(range => {
return range.end - range.start > 1;
});
}

View File

@ -14,10 +14,10 @@
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import { assert } from './assert.js';
import { CDPSession } from './Connection.js';
import { TimeoutError } from './Errors.js';
import {Protocol} from 'devtools-protocol';
import {assert} from './assert.js';
import {CDPSession} from './Connection.js';
import {TimeoutError} from './Errors.js';
import {
EvaluateFn,
EvaluateFnReturnType,
@ -26,8 +26,8 @@ import {
UnwrapPromiseLike,
WrapElementHandle,
} from './EvalTypes.js';
import { ExecutionContext } from './ExecutionContext.js';
import { Frame, FrameManager } from './FrameManager.js';
import {ExecutionContext} from './ExecutionContext.js';
import {Frame, FrameManager} from './FrameManager.js';
import {
debugError,
isNumber,
@ -35,14 +35,11 @@ import {
makePredicateString,
pageBindingInitString,
} from './util.js';
import { MouseButton } from './Input.js';
import { ElementHandle, JSHandle } from './JSHandle.js';
import {
LifecycleWatcher,
PuppeteerLifeCycleEvent,
} from './LifecycleWatcher.js';
import { _getQueryHandlerAndSelector } from './QueryHandler.js';
import { TimeoutSettings } from './TimeoutSettings.js';
import {MouseButton} from './Input.js';
import {ElementHandle, JSHandle} from './JSHandle.js';
import {LifecycleWatcher, PuppeteerLifeCycleEvent} from './LifecycleWatcher.js';
import {_getQueryHandlerAndSelector} from './QueryHandler.js';
import {TimeoutSettings} from './TimeoutSettings.js';
// predicateQueryHandler and checkWaitForOptions are declared here so that
// TypeScript knows about them when used in the predicate function below.
@ -149,7 +146,7 @@ export class DOMWorld {
}
} else {
this.#documentPromise = null;
this.#contextPromise = new Promise((fulfill) => {
this.#contextPromise = new Promise(fulfill => {
this.#contextResolveCallback = fulfill;
});
}
@ -221,7 +218,7 @@ export class DOMWorld {
if (this.#documentPromise) {
return this.#documentPromise;
}
this.#documentPromise = this.executionContext().then(async (context) => {
this.#documentPromise = this.executionContext().then(async context => {
const document = await context.evaluateHandle('document');
const element = document.asElement();
if (element === null) {
@ -301,7 +298,7 @@ export class DOMWorld {
} = options;
// We rely upon the fact that document.open() will reset frame lifecycle with "init"
// lifecycle event. @see https://crrev.com/608658
await this.evaluate<(x: string) => void>((html) => {
await this.evaluate<(x: string) => void>(html => {
document.open();
document.write(html);
document.close();
@ -445,7 +442,7 @@ export class DOMWorld {
script.id = id;
}
let error = null;
script.onerror = (e) => {
script.onerror = e => {
return (error = e);
};
document.head.appendChild(script);
@ -471,7 +468,7 @@ export class DOMWorld {
path?: string;
content?: string;
}): Promise<ElementHandle> {
const { url = null, path = null, content = null } = options;
const {url = null, path = null, content = null} = options;
if (url !== null) {
try {
const context = await this.executionContext();
@ -553,7 +550,7 @@ export class DOMWorld {
async click(
selector: string,
options: { delay?: number; button?: MouseButton; clickCount?: number }
options: {delay?: number; button?: MouseButton; clickCount?: number}
): Promise<void> {
const handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`);
@ -593,7 +590,7 @@ export class DOMWorld {
async type(
selector: string,
text: string,
options?: { delay: number }
options?: {delay: number}
): Promise<void> {
const handle = await this.$(selector);
assert(handle, `No element found for selector: ${selector}`);
@ -605,7 +602,7 @@ export class DOMWorld {
selector: string,
options: WaitForSelectorOptions
): Promise<ElementHandle | null> {
const { updatedSelector, queryHandler } =
const {updatedSelector, queryHandler} =
_getQueryHandlerAndSelector(selector);
assert(queryHandler.waitFor, 'Query handler does not support waiting');
return queryHandler.waitFor(this, updatedSelector, options);
@ -677,7 +674,7 @@ export class DOMWorld {
#onBindingCalled = async (
event: Protocol.Runtime.BindingCalledEvent
): Promise<void> => {
let payload: { type: string; name: string; seq: number; args: unknown[] };
let payload: {type: string; name: string; seq: number; args: unknown[]};
if (!this._hasContext()) {
return;
}
@ -689,7 +686,7 @@ export class DOMWorld {
// called before our wrapper was initialized.
return;
}
const { type, name, seq, args } = payload;
const {type, name, seq, args} = payload;
if (
type !== 'internal' ||
!this.#ctxBindings.has(
@ -827,10 +824,10 @@ export class DOMWorld {
waitForFunction(
pageFunction: Function | string,
options: { polling?: string | number; timeout?: number } = {},
options: {polling?: string | number; timeout?: number} = {},
...args: SerializableOrJSHandle[]
): Promise<JSHandle> {
const { polling = 'raf', timeout = this.#timeoutSettings.timeout() } =
const {polling = 'raf', timeout = this.#timeoutSettings.timeout()} =
options;
const waitTaskOptions: WaitTaskOptions = {
domWorld: this,
@ -992,7 +989,7 @@ export class WaitTask {
if (
!error &&
(await this.#domWorld
.evaluate((s) => {
.evaluate(s => {
return !s;
}, success)
.catch(() => {
@ -1085,7 +1082,7 @@ async function waitForPredicatePageFunction(
}
let fulfill = (_?: unknown) => {};
const result = new Promise((x) => {
const result = new Promise(x => {
return (fulfill = x);
});
const observer = new MutationObserver(async () => {
@ -1114,7 +1111,7 @@ async function waitForPredicatePageFunction(
async function pollRaf(): Promise<unknown> {
let fulfill = (_?: unknown): void => {};
const result = new Promise((x) => {
const result = new Promise(x => {
return (fulfill = x);
});
await onRaf();
@ -1138,7 +1135,7 @@ async function waitForPredicatePageFunction(
async function pollInterval(pollInterval: number): Promise<unknown> {
let fulfill = (_?: unknown): void => {};
const result = new Promise((x) => {
const result = new Promise(x => {
return (fulfill = x);
});
await onTimeout();

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { isNode } from '../environment.js';
import {isNode} from '../environment.js';
declare global {
// eslint-disable-next-line no-var

View File

@ -14,9 +14,9 @@
* limitations under the License.
*/
import { assert } from './assert.js';
import { CDPSession } from './Connection.js';
import { Protocol } from 'devtools-protocol';
import {assert} from './assert.js';
import {CDPSession} from './Connection.js';
import {Protocol} from 'devtools-protocol';
/**
* Dialog instances are dispatched by the {@link Page} via the `dialog` event.

View File

@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CDPSession } from './Connection.js';
import { Viewport } from './PuppeteerViewport.js';
import { Protocol } from 'devtools-protocol';
import {CDPSession} from './Connection.js';
import {Viewport} from './PuppeteerViewport.js';
import {Protocol} from 'devtools-protocol';
export class EmulationManager {
#client: CDPSession;
@ -33,8 +33,8 @@ export class EmulationManager {
const deviceScaleFactor = viewport.deviceScaleFactor || 1;
const screenOrientation: Protocol.Emulation.ScreenOrientation =
viewport.isLandscape
? { angle: 90, type: 'landscapePrimary' }
: { angle: 0, type: 'portraitPrimary' };
? {angle: 90, type: 'landscapePrimary'}
: {angle: 0, type: 'portraitPrimary'};
const hasTouch = viewport.hasTouch || false;
await Promise.all([

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { JSHandle, ElementHandle } from './JSHandle.js';
import {JSHandle, ElementHandle} from './JSHandle.js';
/**
* @public

View File

@ -7,7 +7,7 @@ import mitt, {
/**
* @public
*/
export { EventType, Handler };
export {EventType, Handler};
/**
* @public
@ -110,7 +110,7 @@ export class EventEmitter implements CommonEventEmitter {
* @returns `this` to enable you to chain method calls.
*/
once(event: EventType, handler: Handler): EventEmitter {
const onceHandler: Handler = (eventData) => {
const onceHandler: Handler = eventData => {
handler(eventData);
this.off(event, onceHandler);
};

View File

@ -14,18 +14,14 @@
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import { assert } from './assert.js';
import { CDPSession } from './Connection.js';
import { DOMWorld } from './DOMWorld.js';
import { EvaluateHandleFn, SerializableOrJSHandle } from './EvalTypes.js';
import { Frame } from './FrameManager.js';
import {
getExceptionMessage,
isString,
valueFromRemoteObject,
} from './util.js';
import { ElementHandle, JSHandle, _createJSHandle } from './JSHandle.js';
import {Protocol} from 'devtools-protocol';
import {assert} from './assert.js';
import {CDPSession} from './Connection.js';
import {DOMWorld} from './DOMWorld.js';
import {EvaluateHandleFn, SerializableOrJSHandle} from './EvalTypes.js';
import {Frame} from './FrameManager.js';
import {getExceptionMessage, isString, valueFromRemoteObject} from './util.js';
import {ElementHandle, JSHandle, _createJSHandle} from './JSHandle.js';
/**
* @public
@ -208,7 +204,7 @@ export class ExecutionContext {
? expression
: expression + '\n' + suffix;
const { exceptionDetails, result: remoteObject } = await this._client
const {exceptionDetails, result: remoteObject} = await this._client
.send('Runtime.evaluate', {
expression: expressionWithSourceUrl,
contextId,
@ -273,7 +269,7 @@ export class ExecutionContext {
}
throw error;
}
const { exceptionDetails, result: remoteObject } =
const {exceptionDetails, result: remoteObject} =
await callFunctionOnPromise.catch(rewriteError);
if (exceptionDetails) {
throw new Error(
@ -290,19 +286,19 @@ export class ExecutionContext {
): Protocol.Runtime.CallArgument {
if (typeof arg === 'bigint') {
// eslint-disable-line valid-typeof
return { unserializableValue: `${arg.toString()}n` };
return {unserializableValue: `${arg.toString()}n`};
}
if (Object.is(arg, -0)) {
return { unserializableValue: '-0' };
return {unserializableValue: '-0'};
}
if (Object.is(arg, Infinity)) {
return { unserializableValue: 'Infinity' };
return {unserializableValue: 'Infinity'};
}
if (Object.is(arg, -Infinity)) {
return { unserializableValue: '-Infinity' };
return {unserializableValue: '-Infinity'};
}
if (Object.is(arg, NaN)) {
return { unserializableValue: 'NaN' };
return {unserializableValue: 'NaN'};
}
const objectHandle = arg && arg instanceof JSHandle ? arg : null;
if (objectHandle) {
@ -320,19 +316,19 @@ export class ExecutionContext {
};
}
if (!objectHandle._remoteObject.objectId) {
return { value: objectHandle._remoteObject.value };
return {value: objectHandle._remoteObject.value};
}
return { objectId: objectHandle._remoteObject.objectId };
return {objectId: objectHandle._remoteObject.objectId};
}
return { value: arg };
return {value: arg};
}
function rewriteError(error: Error): Protocol.Runtime.EvaluateResponse {
if (error.message.includes('Object reference chain is too long')) {
return { result: { type: 'undefined' } };
return {result: {type: 'undefined'}};
}
if (error.message.includes("Object couldn't be returned by value")) {
return { result: { type: 'undefined' } };
return {result: {type: 'undefined'}};
}
if (
@ -387,7 +383,7 @@ export class ExecutionContext {
async _adoptBackendNodeId(
backendNodeId?: Protocol.DOM.BackendNodeId
): Promise<ElementHandle> {
const { object } = await this._client.send('DOM.resolveNode', {
const {object} = await this._client.send('DOM.resolveNode', {
backendNodeId: backendNodeId,
executionContextId: this._contextId,
});

View File

@ -14,9 +14,9 @@
* limitations under the License.
*/
import { ElementHandle } from './JSHandle.js';
import { Protocol } from 'devtools-protocol';
import { assert } from './assert.js';
import {ElementHandle} from './JSHandle.js';
import {Protocol} from 'devtools-protocol';
import {assert} from './assert.js';
/**
* File choosers let you react to the page requesting for a file.

View File

@ -14,10 +14,10 @@
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import { assert } from './assert.js';
import { CDPSession, Connection } from './Connection.js';
import { DOMWorld, WaitForSelectorOptions } from './DOMWorld.js';
import {Protocol} from 'devtools-protocol';
import {assert} from './assert.js';
import {CDPSession, Connection} from './Connection.js';
import {DOMWorld, WaitForSelectorOptions} from './DOMWorld.js';
import {
EvaluateFn,
EvaluateFnReturnType,
@ -26,19 +26,16 @@ import {
UnwrapPromiseLike,
WrapElementHandle,
} from './EvalTypes.js';
import { EventEmitter } from './EventEmitter.js';
import { EVALUATION_SCRIPT_URL, ExecutionContext } from './ExecutionContext.js';
import { HTTPResponse } from './HTTPResponse.js';
import { MouseButton } from './Input.js';
import { ElementHandle, JSHandle } from './JSHandle.js';
import {
LifecycleWatcher,
PuppeteerLifeCycleEvent,
} from './LifecycleWatcher.js';
import { NetworkManager } from './NetworkManager.js';
import { Page } from './Page.js';
import { TimeoutSettings } from './TimeoutSettings.js';
import { debugError, isErrorLike, isNumber, isString } from './util.js';
import {EventEmitter} from './EventEmitter.js';
import {EVALUATION_SCRIPT_URL, ExecutionContext} from './ExecutionContext.js';
import {HTTPResponse} from './HTTPResponse.js';
import {MouseButton} from './Input.js';
import {ElementHandle, JSHandle} from './JSHandle.js';
import {LifecycleWatcher, PuppeteerLifeCycleEvent} from './LifecycleWatcher.js';
import {NetworkManager} from './NetworkManager.js';
import {Page} from './Page.js';
import {TimeoutSettings} from './TimeoutSettings.js';
import {debugError, isErrorLike, isNumber, isString} from './util.js';
const UTILITY_WORLD_NAME = '__puppeteer_utility_world__';
const xPathPattern = /^\(\/\/[^\)]+\)|^\/\//;
@ -104,13 +101,13 @@ export class FrameManager extends EventEmitter {
}
private setupEventListeners(session: CDPSession) {
session.on('Page.frameAttached', (event) => {
session.on('Page.frameAttached', event => {
this.#onFrameAttached(session, event.frameId, event.parentFrameId);
});
session.on('Page.frameNavigated', (event) => {
session.on('Page.frameNavigated', event => {
this.#onFrameNavigated(event.frame);
});
session.on('Page.navigatedWithinDocument', (event) => {
session.on('Page.navigatedWithinDocument', event => {
this.#onFrameNavigatedWithinDocument(event.frameId, event.url);
});
session.on(
@ -122,28 +119,28 @@ export class FrameManager extends EventEmitter {
);
}
);
session.on('Page.frameStartedLoading', (event) => {
session.on('Page.frameStartedLoading', event => {
this.#onFrameStartedLoading(event.frameId);
});
session.on('Page.frameStoppedLoading', (event) => {
session.on('Page.frameStoppedLoading', event => {
this.#onFrameStoppedLoading(event.frameId);
});
session.on('Runtime.executionContextCreated', (event) => {
session.on('Runtime.executionContextCreated', event => {
this.#onExecutionContextCreated(event.context, session);
});
session.on('Runtime.executionContextDestroyed', (event) => {
session.on('Runtime.executionContextDestroyed', event => {
this.#onExecutionContextDestroyed(event.executionContextId, session);
});
session.on('Runtime.executionContextsCleared', () => {
this.#onExecutionContextsCleared(session);
});
session.on('Page.lifecycleEvent', (event) => {
session.on('Page.lifecycleEvent', event => {
this.#onLifecycleEvent(event);
});
session.on('Target.attachedToTarget', async (event) => {
session.on('Target.attachedToTarget', async event => {
this.#onAttachedToTarget(event);
});
session.on('Target.detachedFromTarget', async (event) => {
session.on('Target.detachedFromTarget', async event => {
this.#onDetachedFromTarget(event);
});
}
@ -162,10 +159,10 @@ export class FrameManager extends EventEmitter {
: Promise.resolve(),
]);
const { frameTree } = result[1];
const {frameTree} = result[1];
this.#handleFrameTree(client, frameTree);
await Promise.all([
client.send('Page.setLifecycleEventsEnabled', { enabled: true }),
client.send('Page.setLifecycleEventsEnabled', {enabled: true}),
client.send('Runtime.enable').then(() => {
return this._ensureIsolatedWorld(client, UTILITY_WORLD_NAME);
}),
@ -443,10 +440,10 @@ export class FrameManager extends EventEmitter {
// Frames might be removed before we send this.
await Promise.all(
this.frames()
.filter((frame) => {
.filter(frame => {
return frame._client() === session;
})
.map((frame) => {
.map(frame => {
return session
.send('Page.createIsolatedWorld', {
frameId: frame._id,
@ -489,7 +486,7 @@ export class FrameManager extends EventEmitter {
contextPayload: Protocol.Runtime.ExecutionContextDescription,
session: CDPSession
): void {
const auxData = contextPayload.auxData as { frameId?: string } | undefined;
const auxData = contextPayload.auxData as {frameId?: string} | undefined;
const frameId = auxData && auxData.frameId;
const frame =
typeof frameId === 'string' ? this.#frames.get(frameId) : undefined;
@ -1236,7 +1233,7 @@ export class Frame {
async type(
selector: string,
text: string,
options?: { delay: number }
options?: {delay: number}
): Promise<void> {
return this._mainWorld.type(selector, text, options);
}
@ -1283,7 +1280,7 @@ export class Frame {
return this.waitForSelector(string, options);
}
if (isNumber(selectorOrFunctionOrTimeout)) {
return new Promise((fulfill) => {
return new Promise(fulfill => {
return setTimeout(fulfill, selectorOrFunctionOrTimeout);
});
}
@ -1320,7 +1317,7 @@ export class Frame {
* @param milliseconds - the number of milliseconds to wait.
*/
waitForTimeout(milliseconds: number): Promise<void> {
return new Promise((resolve) => {
return new Promise(resolve => {
setTimeout(resolve, milliseconds);
});
}

View File

@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import { ProtocolMapping } from 'devtools-protocol/types/protocol-mapping.js';
import { assert } from './assert.js';
import { ProtocolError } from './Errors.js';
import { EventEmitter } from './EventEmitter.js';
import { Frame } from './FrameManager.js';
import { debugError, isString } from './util.js';
import { HTTPResponse } from './HTTPResponse.js';
import {Protocol} from 'devtools-protocol';
import {ProtocolMapping} from 'devtools-protocol/types/protocol-mapping.js';
import {assert} from './assert.js';
import {ProtocolError} from './Errors.js';
import {EventEmitter} from './EventEmitter.js';
import {Frame} from './FrameManager.js';
import {debugError, isString} from './util.js';
import {HTTPResponse} from './HTTPResponse.js';
/**
* @public
@ -236,12 +236,12 @@ export class HTTPRequest {
*/
interceptResolutionState(): InterceptResolutionState {
if (!this.#allowInterception) {
return { action: InterceptResolutionAction.Disabled };
return {action: InterceptResolutionAction.Disabled};
}
if (this.#interceptionHandled) {
return { action: InterceptResolutionAction.AlreadyHandled };
return {action: InterceptResolutionAction.AlreadyHandled};
}
return { ...this.#interceptResolutionState };
return {...this.#interceptResolutionState};
}
/**
@ -272,7 +272,7 @@ export class HTTPRequest {
await this.#interceptHandlers.reduce((promiseChain, interceptAction) => {
return promiseChain.then(interceptAction);
}, Promise.resolve());
const { action } = this.interceptResolutionState();
const {action} = this.interceptResolutionState();
switch (action) {
case 'abort':
return this.#abort(this.#abortErrorReason);
@ -397,7 +397,7 @@ export class HTTPRequest {
* message, e.g. `net::ERR_FAILED`. It is not guaranteed that there will be
* failure text if the request fails.
*/
failure(): { errorText: string } | null {
failure(): {errorText: string} | null {
if (!this._failureText) {
return null;
}
@ -472,7 +472,7 @@ export class HTTPRequest {
}
async #continue(overrides: ContinueRequestOverrides = {}): Promise<void> {
const { url, method, postData, headers } = overrides;
const {url, method, postData, headers} = overrides;
this.#interceptionHandled = true;
const postDataBinaryBase64 = postData
@ -492,7 +492,7 @@ export class HTTPRequest {
postData: postDataBinaryBase64,
headers: headers ? headersArray(headers) : undefined,
})
.catch((error) => {
.catch(error => {
this.#interceptionHandled = false;
return handleError(error);
});
@ -575,7 +575,7 @@ export class HTTPRequest {
const value = response.headers[header];
responseHeaders[header.toLowerCase()] = Array.isArray(value)
? value.map((item) => {
? value.map(item => {
return String(item);
})
: String(value);
@ -604,7 +604,7 @@ export class HTTPRequest {
responseHeaders: headersArray(responseHeaders),
body: responseBody ? responseBody.toString('base64') : undefined,
})
.catch((error) => {
.catch(error => {
this.#interceptionHandled = false;
return handleError(error);
});
@ -731,7 +731,7 @@ export type ActionResult = 'continue' | 'abort' | 'respond';
function headersArray(
headers: Record<string, string | string[]>
): Array<{ name: string; value: string }> {
): Array<{name: string; value: string}> {
const result = [];
for (const name in headers) {
const value = headers[name];
@ -740,8 +740,8 @@ function headersArray(
const values = Array.isArray(value) ? value : [value];
result.push(
...values.map((value) => {
return { name, value: value + '' };
...values.map(value => {
return {name, value: value + ''};
})
);
}
@ -762,7 +762,7 @@ async function handleError(error: ProtocolError) {
// List taken from
// https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
// with extra 306 and 418 codes.
const STATUS_TEXTS: { [key: string]: string | undefined } = {
const STATUS_TEXTS: {[key: string]: string | undefined} = {
'100': 'Continue',
'101': 'Switching Protocols',
'102': 'Processing',

View File

@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ProtocolMapping } from 'devtools-protocol/types/protocol-mapping.js';
import {ProtocolMapping} from 'devtools-protocol/types/protocol-mapping.js';
import { EventEmitter } from './EventEmitter.js';
import { Frame } from './FrameManager.js';
import { HTTPRequest } from './HTTPRequest.js';
import { SecurityDetails } from './SecurityDetails.js';
import { Protocol } from 'devtools-protocol';
import { ProtocolError } from './Errors.js';
import {EventEmitter} from './EventEmitter.js';
import {Frame} from './FrameManager.js';
import {HTTPRequest} from './HTTPRequest.js';
import {SecurityDetails} from './SecurityDetails.js';
import {Protocol} from 'devtools-protocol';
import {ProtocolError} from './Errors.js';
/**
* @public
@ -71,7 +71,7 @@ export class HTTPResponse {
this.#client = client;
this.#request = request;
this.#bodyLoadedPromise = new Promise((fulfill) => {
this.#bodyLoadedPromise = new Promise(fulfill => {
this.#bodyLoadedPromiseFulfill = fulfill;
});
@ -195,7 +195,7 @@ export class HTTPResponse {
*/
buffer(): Promise<Buffer> {
if (!this.#contentPromise) {
this.#contentPromise = this.#bodyLoadedPromise.then(async (error) => {
this.#contentPromise = this.#bodyLoadedPromise.then(async error => {
if (error) {
throw error;
}

View File

@ -14,15 +14,11 @@
* limitations under the License.
*/
import { assert } from './assert.js';
import { CDPSession } from './Connection.js';
import {
_keyDefinitions,
KeyDefinition,
KeyInput,
} from './USKeyboardLayout.js';
import { Protocol } from 'devtools-protocol';
import { Point } from './JSHandle.js';
import {assert} from './assert.js';
import {CDPSession} from './Connection.js';
import {_keyDefinitions, KeyDefinition, KeyInput} from './USKeyboardLayout.js';
import {Protocol} from 'devtools-protocol';
import {Point} from './JSHandle.js';
type KeyDescription = Required<
Pick<KeyDefinition, 'keyCode' | 'key' | 'text' | 'code' | 'location'>
@ -110,7 +106,7 @@ export class Keyboard {
*/
async down(
key: KeyInput,
options: { text?: string } = { text: undefined }
options: {text?: string} = {text: undefined}
): Promise<void> {
const description = this.#keyDescriptionForString(key);
@ -241,7 +237,7 @@ export class Keyboard {
* @param char - Character to send into the page.
*/
async sendCharacter(char: string): Promise<void> {
await this.#client.send('Input.insertText', { text: char });
await this.#client.send('Input.insertText', {text: char});
}
private charIsKey(char: string): char is KeyInput {
@ -270,14 +266,14 @@ export class Keyboard {
* if specified, is the time to wait between `keydown` and `keyup` in milliseconds.
* Defaults to 0.
*/
async type(text: string, options: { delay?: number } = {}): Promise<void> {
async type(text: string, options: {delay?: number} = {}): Promise<void> {
const delay = options.delay || undefined;
for (const char of text) {
if (this.charIsKey(char)) {
await this.press(char, { delay });
await this.press(char, {delay});
} else {
if (delay) {
await new Promise((f) => {
await new Promise(f => {
return setTimeout(f, delay);
});
}
@ -308,12 +304,12 @@ export class Keyboard {
*/
async press(
key: KeyInput,
options: { delay?: number; text?: string } = {}
options: {delay?: number; text?: string} = {}
): Promise<void> {
const { delay = null } = options;
const {delay = null} = options;
await this.down(key, options);
if (delay) {
await new Promise((f) => {
await new Promise(f => {
return setTimeout(f, options.delay);
});
}
@ -424,9 +420,9 @@ export class Mouse {
async move(
x: number,
y: number,
options: { steps?: number } = {}
options: {steps?: number} = {}
): Promise<void> {
const { steps = 1 } = options;
const {steps = 1} = options;
const fromX = this.#x,
fromY = this.#y;
this.#x = x;
@ -451,13 +447,13 @@ export class Mouse {
async click(
x: number,
y: number,
options: MouseOptions & { delay?: number } = {}
options: MouseOptions & {delay?: number} = {}
): Promise<void> {
const { delay = null } = options;
const {delay = null} = options;
if (delay !== null) {
await this.move(x, y);
await this.down(options);
await new Promise((f) => {
await new Promise(f => {
return setTimeout(f, delay);
});
await this.up(options);
@ -473,7 +469,7 @@ export class Mouse {
* @param options - Optional `MouseOptions`.
*/
async down(options: MouseOptions = {}): Promise<void> {
const { button = 'left', clickCount = 1 } = options;
const {button = 'left', clickCount = 1} = options;
this.#button = button;
await this.#client.send('Input.dispatchMouseEvent', {
type: 'mousePressed',
@ -490,7 +486,7 @@ export class Mouse {
* @param options - Optional `MouseOptions`.
*/
async up(options: MouseOptions = {}): Promise<void> {
const { button = 'left', clickCount = 1 } = options;
const {button = 'left', clickCount = 1} = options;
this.#button = 'none';
await this.#client.send('Input.dispatchMouseEvent', {
type: 'mouseReleased',
@ -522,7 +518,7 @@ export class Mouse {
* ```
*/
async wheel(options: MouseWheelOptions = {}): Promise<void> {
const { deltaX = 0, deltaY = 0 } = options;
const {deltaX = 0, deltaY = 0} = options;
await this.#client.send('Input.dispatchMouseEvent', {
type: 'mouseWheel',
x: this.#x,
@ -540,8 +536,8 @@ export class Mouse {
* @param target - point to drag to
*/
async drag(start: Point, target: Point): Promise<Protocol.Input.DragData> {
const promise = new Promise<Protocol.Input.DragData>((resolve) => {
this.#client.once('Input.dragIntercepted', (event) => {
const promise = new Promise<Protocol.Input.DragData>(resolve => {
this.#client.once('Input.dragIntercepted', event => {
return resolve(event.data);
});
});
@ -607,14 +603,14 @@ export class Mouse {
async dragAndDrop(
start: Point,
target: Point,
options: { delay?: number } = {}
options: {delay?: number} = {}
): Promise<void> {
const { delay = null } = options;
const {delay = null} = options;
const data = await this.drag(start, target);
await this.dragEnter(target, data);
await this.dragOver(target, data);
if (delay) {
await new Promise((resolve) => {
await new Promise(resolve => {
return setTimeout(resolve, delay);
});
}
@ -645,7 +641,7 @@ export class Touchscreen {
* @param y - Vertical position of the tap.
*/
async tap(x: number, y: number): Promise<void> {
const touchPoints = [{ x: Math.round(x), y: Math.round(y) }];
const touchPoints = [{x: Math.round(x), y: Math.round(y)}];
await this.#client.send('Input.dispatchTouchEvent', {
type: 'touchStart',
touchPoints,

View File

@ -14,9 +14,9 @@
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import { assert } from './assert.js';
import { CDPSession } from './Connection.js';
import {Protocol} from 'devtools-protocol';
import {assert} from './assert.js';
import {CDPSession} from './Connection.js';
import {
EvaluateFn,
EvaluateFnReturnType,
@ -25,12 +25,12 @@ import {
UnwrapPromiseLike,
WrapElementHandle,
} from './EvalTypes.js';
import { ExecutionContext } from './ExecutionContext.js';
import { Frame, FrameManager } from './FrameManager.js';
import { MouseButton } from './Input.js';
import { Page, ScreenshotOptions } from './Page.js';
import { _getQueryHandlerAndSelector } from './QueryHandler.js';
import { KeyInput } from './USKeyboardLayout.js';
import {ExecutionContext} from './ExecutionContext.js';
import {Frame, FrameManager} from './FrameManager.js';
import {MouseButton} from './Input.js';
import {Page, ScreenshotOptions} from './Page.js';
import {_getQueryHandlerAndSelector} from './QueryHandler.js';
import {KeyInput} from './USKeyboardLayout.js';
import {
debugError,
isString,
@ -91,8 +91,8 @@ const applyOffsetsToQuad = (
offsetX: number,
offsetY: number
) => {
return quad.map((part) => {
return { x: part.x + offsetX, y: part.y + offsetY };
return quad.map(part => {
return {x: part.x + offsetX, y: part.y + offsetY};
});
};
@ -219,7 +219,7 @@ export class JSHandle<HandleObjectType = unknown> {
async getProperty(propertyName: string): Promise<JSHandle> {
const objectHandle = await this.evaluateHandle(
(object: Element, propertyName: keyof Element) => {
const result: Record<string, unknown> = { __proto__: null };
const result: Record<string, unknown> = {__proto__: null};
result[propertyName] = object[propertyName];
return result;
},
@ -561,8 +561,8 @@ export class ElementHandle<
});
return false;
}
const visibleRatio = await new Promise((resolve) => {
const observer = new IntersectionObserver((entries) => {
const visibleRatio = await new Promise(resolve => {
const observer = new IntersectionObserver(entries => {
resolve(entries[0]!.intersectionRatio);
observer.disconnect();
});
@ -590,7 +590,7 @@ export class ElementHandle<
async #getOOPIFOffsets(
frame: Frame
): Promise<{ offsetX: number; offsetY: number }> {
): Promise<{offsetX: number; offsetY: number}> {
let offsetX = 0;
let offsetY = 0;
let currentFrame: Frame | null = frame;
@ -600,11 +600,9 @@ export class ElementHandle<
currentFrame = parent;
continue;
}
const { backendNodeId } = await parent
._client()
.send('DOM.getFrameOwner', {
frameId: currentFrame._id,
});
const {backendNodeId} = await parent._client().send('DOM.getFrameOwner', {
frameId: currentFrame._id,
});
const result = await parent._client().send('DOM.getBoxModel', {
backendNodeId: backendNodeId,
});
@ -617,7 +615,7 @@ export class ElementHandle<
offsetY += topLeftCorner!.y;
currentFrame = parent;
}
return { offsetX, offsetY };
return {offsetX, offsetY};
}
/**
@ -637,20 +635,20 @@ export class ElementHandle<
}
// Filter out quads that have too small area to click into.
// Fallback to `layoutViewport` in case of using Firefox.
const { clientWidth, clientHeight } =
const {clientWidth, clientHeight} =
layoutMetrics.cssLayoutViewport || layoutMetrics.layoutViewport;
const { offsetX, offsetY } = await this.#getOOPIFOffsets(this.#frame);
const {offsetX, offsetY} = await this.#getOOPIFOffsets(this.#frame);
const quads = result.quads
.map((quad) => {
.map(quad => {
return this.#fromProtocolQuad(quad);
})
.map((quad) => {
.map(quad => {
return applyOffsetsToQuad(quad, offsetX, offsetY);
})
.map((quad) => {
.map(quad => {
return this.#intersectQuadWithViewport(quad, clientWidth, clientHeight);
})
.filter((quad) => {
.filter(quad => {
return computeQuadArea(quad) > 1;
});
if (!quads.length) {
@ -696,17 +694,17 @@ export class ElementHandle<
const params: Protocol.DOM.GetBoxModelRequest = {
objectId: this._remoteObject.objectId,
};
return this._client.send('DOM.getBoxModel', params).catch((error) => {
return this._client.send('DOM.getBoxModel', params).catch(error => {
return debugError(error);
});
}
#fromProtocolQuad(quad: number[]): Point[] {
return [
{ x: quad[0]!, y: quad[1]! },
{ x: quad[2]!, y: quad[3]! },
{ x: quad[4]!, y: quad[5]! },
{ x: quad[6]!, y: quad[7]! },
{x: quad[0]!, y: quad[1]!},
{x: quad[2]!, y: quad[3]!},
{x: quad[4]!, y: quad[5]!},
{x: quad[6]!, y: quad[7]!},
];
}
@ -715,7 +713,7 @@ export class ElementHandle<
width: number,
height: number
): Point[] {
return quad.map((point) => {
return quad.map(point => {
return {
x: Math.min(Math.max(point.x, 0), width),
y: Math.min(Math.max(point.y, 0), height),
@ -730,7 +728,7 @@ export class ElementHandle<
*/
async hover(): Promise<void> {
await this.#scrollIntoViewIfNeeded();
const { x, y } = await this.clickablePoint();
const {x, y} = await this.clickablePoint();
await this.#page.mouse.move(x, y);
}
@ -741,7 +739,7 @@ export class ElementHandle<
*/
async click(options: ClickOptions = {}): Promise<void> {
await this.#scrollIntoViewIfNeeded();
const { x, y } = await this.clickablePoint(options.offset);
const {x, y} = await this.clickablePoint(options.offset);
await this.#page.mouse.click(x, y, options);
}
@ -762,7 +760,7 @@ export class ElementHandle<
* This method creates a `dragenter` event on the element.
*/
async dragEnter(
data: Protocol.Input.DragData = { items: [], dragOperationsMask: 1 }
data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1}
): Promise<void> {
await this.#scrollIntoViewIfNeeded();
const target = await this.clickablePoint();
@ -773,7 +771,7 @@ export class ElementHandle<
* This method creates a `dragover` event on the element.
*/
async dragOver(
data: Protocol.Input.DragData = { items: [], dragOperationsMask: 1 }
data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1}
): Promise<void> {
await this.#scrollIntoViewIfNeeded();
const target = await this.clickablePoint();
@ -784,7 +782,7 @@ export class ElementHandle<
* This method triggers a drop on the element.
*/
async drop(
data: Protocol.Input.DragData = { items: [], dragOperationsMask: 1 }
data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1}
): Promise<void> {
await this.#scrollIntoViewIfNeeded();
const destination = await this.clickablePoint();
@ -796,7 +794,7 @@ export class ElementHandle<
*/
async dragAndDrop(
target: ElementHandle,
options?: { delay: number }
options?: {delay: number}
): Promise<void> {
await this.#scrollIntoViewIfNeeded();
const startPoint = await this.clickablePoint();
@ -856,8 +854,8 @@ export class ElementHandle<
}
}
}
element.dispatchEvent(new Event('input', { bubbles: true }));
element.dispatchEvent(new Event('change', { bubbles: true }));
element.dispatchEvent(new Event('input', {bubbles: true}));
element.dispatchEvent(new Event('change', {bubbles: true}));
return [...selectedValues.values()];
}, values);
}
@ -874,7 +872,7 @@ export class ElementHandle<
*/
async uploadFile(...filePaths: string[]): Promise<void> {
const isMultiple = await this.evaluate<(element: Element) => boolean>(
(element) => {
element => {
if (!(element instanceof HTMLInputElement)) {
throw new Error('uploadFile can only be called on an input element.');
}
@ -898,28 +896,28 @@ export class ElementHandle<
}
throw error;
}
const files = filePaths.map((filePath) => {
const files = filePaths.map(filePath => {
if (path.win32.isAbsolute(filePath) || path.posix.isAbsolute(filePath)) {
return filePath;
} else {
return path.resolve(filePath);
}
});
const { objectId } = this._remoteObject;
const { node } = await this._client.send('DOM.describeNode', { objectId });
const { backendNodeId } = node;
const {objectId} = this._remoteObject;
const {node} = await this._client.send('DOM.describeNode', {objectId});
const {backendNodeId} = node;
/* The zero-length array is a special case, it seems that
DOM.setFileInputFiles does not actually update the files in that case,
so the solution is to eval the element value to a new FileList directly.
*/
if (files.length === 0) {
await (this as ElementHandle<HTMLInputElement>).evaluate((element) => {
await (this as ElementHandle<HTMLInputElement>).evaluate(element => {
element.files = new DataTransfer().files;
// Dispatch events for this case because it should behave akin to a user action.
element.dispatchEvent(new Event('input', { bubbles: true }));
element.dispatchEvent(new Event('change', { bubbles: true }));
element.dispatchEvent(new Event('input', {bubbles: true}));
element.dispatchEvent(new Event('change', {bubbles: true}));
});
} else {
await this._client.send('DOM.setFileInputFiles', {
@ -937,7 +935,7 @@ export class ElementHandle<
*/
async tap(): Promise<void> {
await this.#scrollIntoViewIfNeeded();
const { x, y } = await this.clickablePoint();
const {x, y} = await this.clickablePoint();
await this.#page.touchscreen.tap(x, y);
}
@ -945,7 +943,7 @@ export class ElementHandle<
* Calls {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus | focus} on the element.
*/
async focus(): Promise<void> {
await (this as ElementHandle<HTMLElement>).evaluate((element) => {
await (this as ElementHandle<HTMLElement>).evaluate(element => {
return element.focus();
});
}
@ -972,7 +970,7 @@ export class ElementHandle<
* await elementHandle.press('Enter');
* ```
*/
async type(text: string, options?: { delay: number }): Promise<void> {
async type(text: string, options?: {delay: number}): Promise<void> {
await this.focus();
await this.#page.keyboard.type(text, options);
}
@ -1007,14 +1005,14 @@ export class ElementHandle<
return null;
}
const { offsetX, offsetY } = await this.#getOOPIFOffsets(this.#frame);
const {offsetX, offsetY} = await this.#getOOPIFOffsets(this.#frame);
const quad = result.model.border;
const x = Math.min(quad[0]!, quad[2]!, quad[4]!, quad[6]!);
const y = Math.min(quad[1]!, quad[3]!, quad[5]!, quad[7]!);
const width = Math.max(quad[0]!, quad[2]!, quad[4]!, quad[6]!) - x;
const height = Math.max(quad[1]!, quad[3]!, quad[5]!, quad[7]!) - y;
return { x: x + offsetX, y: y + offsetY, width, height };
return {x: x + offsetX, y: y + offsetY, width, height};
}
/**
@ -1032,9 +1030,9 @@ export class ElementHandle<
return null;
}
const { offsetX, offsetY } = await this.#getOOPIFOffsets(this.#frame);
const {offsetX, offsetY} = await this.#getOOPIFOffsets(this.#frame);
const { content, padding, border, margin, width, height } = result.model;
const {content, padding, border, margin, width, height} = result.model;
return {
content: applyOffsetsToQuad(
this.#fromProtocolQuad(content),
@ -1097,7 +1095,7 @@ export class ElementHandle<
const layoutMetrics = await this._client.send('Page.getLayoutMetrics');
// Fallback to `layoutViewport` in case of using Firefox.
const { pageX, pageY } =
const {pageX, pageY} =
layoutMetrics.cssVisualViewport || layoutMetrics.layoutViewport;
const clip = Object.assign({}, boundingBox);
@ -1131,7 +1129,7 @@ export class ElementHandle<
async $<T extends Element = Element>(
selector: string
): Promise<ElementHandle<T> | null> {
const { updatedSelector, queryHandler } =
const {updatedSelector, queryHandler} =
_getQueryHandlerAndSelector(selector);
assert(
queryHandler.queryOne,
@ -1154,7 +1152,7 @@ export class ElementHandle<
async $$<T extends Element = Element>(
selector: string
): Promise<Array<ElementHandle<T>>> {
const { updatedSelector, queryHandler } =
const {updatedSelector, queryHandler} =
_getQueryHandlerAndSelector(selector);
assert(
queryHandler.queryAll,
@ -1243,7 +1241,7 @@ export class ElementHandle<
>,
...args: SerializableOrJSHandle[]
): Promise<WrapElementHandle<ReturnType>> {
const { updatedSelector, queryHandler } =
const {updatedSelector, queryHandler} =
_getQueryHandlerAndSelector(selector);
assert(queryHandler.queryAllArray);
const arrayHandle = await queryHandler.queryAllArray(this, updatedSelector);
@ -1300,10 +1298,10 @@ export class ElementHandle<
async isIntersectingViewport(options?: {
threshold?: number;
}): Promise<boolean> {
const { threshold = 0 } = options || {};
const {threshold = 0} = options || {};
return await this.evaluate(async (element: Element, threshold: number) => {
const visibleRatio = await new Promise<number>((resolve) => {
const observer = new IntersectionObserver((entries) => {
const visibleRatio = await new Promise<number>(resolve => {
const observer = new IntersectionObserver(entries => {
resolve(entries[0]!.intersectionRatio);
observer.disconnect();
});

View File

@ -14,22 +14,22 @@
* limitations under the License.
*/
import { assert } from './assert.js';
import {assert} from './assert.js';
import {
addEventListener,
PuppeteerEventListener,
removeEventListeners,
} from './util.js';
import { TimeoutError } from './Errors.js';
import {TimeoutError} from './Errors.js';
import {
FrameManager,
Frame,
FrameManagerEmittedEvents,
} from './FrameManager.js';
import { HTTPRequest } from './HTTPRequest.js';
import { HTTPResponse } from './HTTPResponse.js';
import { NetworkManagerEmittedEvents } from './NetworkManager.js';
import { CDPSessionEmittedEvents } from './Connection.js';
import {HTTPRequest} from './HTTPRequest.js';
import {HTTPResponse} from './HTTPResponse.js';
import {NetworkManagerEmittedEvents} from './NetworkManager.js';
import {CDPSessionEmittedEvents} from './Connection.js';
/**
* @public
*/
@ -72,24 +72,24 @@ export class LifecycleWatcher {
#eventListeners: PuppeteerEventListener[];
#sameDocumentNavigationCompleteCallback: (x?: Error) => void = noop;
#sameDocumentNavigationPromise = new Promise<Error | undefined>((fulfill) => {
#sameDocumentNavigationPromise = new Promise<Error | undefined>(fulfill => {
this.#sameDocumentNavigationCompleteCallback = fulfill;
});
#lifecycleCallback: () => void = noop;
#lifecyclePromise: Promise<void> = new Promise((fulfill) => {
#lifecyclePromise: Promise<void> = new Promise(fulfill => {
this.#lifecycleCallback = fulfill;
});
#newDocumentNavigationCompleteCallback: (x?: Error) => void = noop;
#newDocumentNavigationPromise: Promise<Error | undefined> = new Promise(
(fulfill) => {
fulfill => {
this.#newDocumentNavigationCompleteCallback = fulfill;
}
);
#terminationCallback: (x?: Error) => void = noop;
#terminationPromise: Promise<Error | undefined> = new Promise((fulfill) => {
#terminationPromise: Promise<Error | undefined> = new Promise(fulfill => {
this.#terminationCallback = fulfill;
});
@ -111,7 +111,7 @@ export class LifecycleWatcher {
} else if (typeof waitUntil === 'string') {
waitUntil = [waitUntil];
}
this.#expectedLifecycle = waitUntil.map((value) => {
this.#expectedLifecycle = waitUntil.map(value => {
const protocolEvent = puppeteerToProtocolLifecycle.get(value);
assert(protocolEvent, 'Unknown value for options.waitUntil: ' + value);
return protocolEvent as ProtocolLifeCycleEvent;
@ -214,7 +214,7 @@ export class LifecycleWatcher {
}
const errorMessage =
'Navigation timeout of ' + this.#timeout + ' ms exceeded';
await new Promise((fulfill) => {
await new Promise(fulfill => {
return (this.#maximumTimer = setTimeout(fulfill, this.#timeout));
});
return new TimeoutError(errorMessage);

View File

@ -14,12 +14,12 @@
* limitations under the License.
*/
import { NetworkConditions } from './NetworkManager.js';
import {NetworkConditions} from './NetworkManager.js';
/**
* @public
*/
export type PredefinedNetworkConditions = { [name: string]: NetworkConditions };
export type PredefinedNetworkConditions = {[name: string]: NetworkConditions};
/**
* @public

View File

@ -1,5 +1,5 @@
import { Protocol } from 'devtools-protocol';
import { HTTPRequest } from './HTTPRequest.js';
import {Protocol} from 'devtools-protocol';
import {HTTPRequest} from './HTTPRequest.js';
export type QueuedEventGroup = {
responseReceivedEvent: Protocol.Network.ResponseReceivedEvent;

View File

@ -14,15 +14,15 @@
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import { ProtocolMapping } from 'devtools-protocol/types/protocol-mapping.js';
import { assert } from './assert.js';
import { EventEmitter } from './EventEmitter.js';
import { Frame } from './FrameManager.js';
import { HTTPRequest } from './HTTPRequest.js';
import { HTTPResponse } from './HTTPResponse.js';
import { FetchRequestId, NetworkEventManager } from './NetworkEventManager.js';
import { debugError, isString } from './util.js';
import {Protocol} from 'devtools-protocol';
import {ProtocolMapping} from 'devtools-protocol/types/protocol-mapping.js';
import {assert} from './assert.js';
import {EventEmitter} from './EventEmitter.js';
import {Frame} from './FrameManager.js';
import {HTTPRequest} from './HTTPRequest.js';
import {HTTPResponse} from './HTTPResponse.js';
import {FetchRequestId, NetworkEventManager} from './NetworkEventManager.js';
import {debugError, isString} from './util.js';
/**
* @public
@ -231,7 +231,7 @@ export class NetworkManager extends EventEmitter {
this.#updateProtocolCacheDisabled(),
this.#client.send('Fetch.enable', {
handleAuthRequests: true,
patterns: [{ urlPattern: '*' }],
patterns: [{urlPattern: '*'}],
}),
]);
} else {
@ -258,7 +258,7 @@ export class NetworkManager extends EventEmitter {
this.#userRequestInterceptionEnabled &&
!event.request.url.startsWith('data:')
) {
const { requestId: networkRequestId } = event;
const {requestId: networkRequestId} = event;
this.#networkEventManager.storeRequestWillBeSent(networkRequestId, event);
@ -268,7 +268,7 @@ export class NetworkManager extends EventEmitter {
const requestPausedEvent =
this.#networkEventManager.getRequestPaused(networkRequestId);
if (requestPausedEvent) {
const { requestId: fetchRequestId } = requestPausedEvent;
const {requestId: fetchRequestId} = requestPausedEvent;
this.#patchRequestEventHeaders(event, requestPausedEvent);
this.#onRequest(event, fetchRequestId);
this.#networkEventManager.forgetRequestPaused(networkRequestId);
@ -291,14 +291,14 @@ export class NetworkManager extends EventEmitter {
response = 'ProvideCredentials';
this.#attemptedAuthentications.add(event.requestId);
}
const { username, password } = this.#credentials || {
const {username, password} = this.#credentials || {
username: undefined,
password: undefined,
};
this.#client
.send('Fetch.continueWithAuth', {
requestId: event.requestId,
authChallengeResponse: { response, username, password },
authChallengeResponse: {response, username, password},
})
.catch(debugError);
}
@ -322,7 +322,7 @@ export class NetworkManager extends EventEmitter {
.catch(debugError);
}
const { networkId: networkRequestId, requestId: fetchRequestId } = event;
const {networkId: networkRequestId, requestId: fetchRequestId} = event;
if (!networkRequestId) {
return;

View File

@ -186,15 +186,15 @@ export const _paperFormats: Record<
LowerCasePaperFormat,
PaperFormatDimensions
> = {
letter: { width: 8.5, height: 11 },
legal: { width: 8.5, height: 14 },
tabloid: { width: 11, height: 17 },
ledger: { width: 17, height: 11 },
a0: { width: 33.1, height: 46.8 },
a1: { width: 23.4, height: 33.1 },
a2: { width: 16.54, height: 23.4 },
a3: { width: 11.7, height: 16.54 },
a4: { width: 8.27, height: 11.7 },
a5: { width: 5.83, height: 8.27 },
a6: { width: 4.13, height: 5.83 },
letter: {width: 8.5, height: 11},
legal: {width: 8.5, height: 14},
tabloid: {width: 11, height: 17},
ledger: {width: 17, height: 11},
a0: {width: 33.1, height: 46.8},
a1: {width: 23.4, height: 33.1},
a2: {width: 16.54, height: 23.4},
a3: {width: 11.7, height: 16.54},
a4: {width: 8.27, height: 11.7},
a5: {width: 5.83, height: 8.27},
a6: {width: 4.13, height: 5.83},
} as const;

View File

@ -14,20 +14,16 @@
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import type { Readable } from 'stream';
import { Accessibility } from './Accessibility.js';
import { assert, assertNever } from './assert.js';
import { Browser, BrowserContext } from './Browser.js';
import {
CDPSession,
CDPSessionEmittedEvents,
Connection,
} from './Connection.js';
import { ConsoleMessage, ConsoleMessageType } from './ConsoleMessage.js';
import { Coverage } from './Coverage.js';
import { Dialog } from './Dialog.js';
import { EmulationManager } from './EmulationManager.js';
import {Protocol} from 'devtools-protocol';
import type {Readable} from 'stream';
import {Accessibility} from './Accessibility.js';
import {assert, assertNever} from './assert.js';
import {Browser, BrowserContext} from './Browser.js';
import {CDPSession, CDPSessionEmittedEvents, Connection} from './Connection.js';
import {ConsoleMessage, ConsoleMessageType} from './ConsoleMessage.js';
import {Coverage} from './Coverage.js';
import {Dialog} from './Dialog.js';
import {EmulationManager} from './EmulationManager.js';
import {
EvaluateFn,
EvaluateFnReturnType,
@ -36,8 +32,8 @@ import {
UnwrapPromiseLike,
WrapElementHandle,
} from './EvalTypes.js';
import { EventEmitter, Handler } from './EventEmitter.js';
import { FileChooser } from './FileChooser.js';
import {EventEmitter, Handler} from './EventEmitter.js';
import {FileChooser} from './FileChooser.js';
import {
Frame,
FrameManager,
@ -61,27 +57,23 @@ import {
waitForEvent,
waitWithTimeout,
} from './util.js';
import { HTTPRequest } from './HTTPRequest.js';
import { HTTPResponse } from './HTTPResponse.js';
import { Keyboard, Mouse, MouseButton, Touchscreen } from './Input.js';
import { ElementHandle, JSHandle, _createJSHandle } from './JSHandle.js';
import { PuppeteerLifeCycleEvent } from './LifecycleWatcher.js';
import {HTTPRequest} from './HTTPRequest.js';
import {HTTPResponse} from './HTTPResponse.js';
import {Keyboard, Mouse, MouseButton, Touchscreen} from './Input.js';
import {ElementHandle, JSHandle, _createJSHandle} from './JSHandle.js';
import {PuppeteerLifeCycleEvent} from './LifecycleWatcher.js';
import {
Credentials,
NetworkConditions,
NetworkManagerEmittedEvents,
} from './NetworkManager.js';
import {
LowerCasePaperFormat,
PDFOptions,
_paperFormats,
} from './PDFOptions.js';
import { Viewport } from './PuppeteerViewport.js';
import { Target } from './Target.js';
import { TaskQueue } from './TaskQueue.js';
import { TimeoutSettings } from './TimeoutSettings.js';
import { Tracing } from './Tracing.js';
import { WebWorker } from './WebWorker.js';
import {LowerCasePaperFormat, PDFOptions, _paperFormats} from './PDFOptions.js';
import {Viewport} from './PuppeteerViewport.js';
import {Target} from './Target.js';
import {TaskQueue} from './TaskQueue.js';
import {TimeoutSettings} from './TimeoutSettings.js';
import {Tracing} from './Tracing.js';
import {WebWorker} from './WebWorker.js';
/**
* @public
@ -378,7 +370,7 @@ export interface PageEventObject {
framedetached: Frame;
framenavigated: Frame;
load: never;
metrics: { title: string; metrics: Metrics };
metrics: {title: string; metrics: Metrics};
pageerror: Error;
popup: Page;
request: HTTPRequest;
@ -545,7 +537,7 @@ export class Page extends EventEmitter {
}
}
);
client.on('Target.detachedFromTarget', (event) => {
client.on('Target.detachedFromTarget', event => {
const worker = this.#workers.get(event.sessionId);
if (!worker) {
return;
@ -554,33 +546,33 @@ export class Page extends EventEmitter {
this.emit(PageEmittedEvents.WorkerDestroyed, worker);
});
this.#frameManager.on(FrameManagerEmittedEvents.FrameAttached, (event) => {
this.#frameManager.on(FrameManagerEmittedEvents.FrameAttached, event => {
return this.emit(PageEmittedEvents.FrameAttached, event);
});
this.#frameManager.on(FrameManagerEmittedEvents.FrameDetached, (event) => {
this.#frameManager.on(FrameManagerEmittedEvents.FrameDetached, event => {
return this.emit(PageEmittedEvents.FrameDetached, event);
});
this.#frameManager.on(FrameManagerEmittedEvents.FrameNavigated, (event) => {
this.#frameManager.on(FrameManagerEmittedEvents.FrameNavigated, event => {
return this.emit(PageEmittedEvents.FrameNavigated, event);
});
const networkManager = this.#frameManager.networkManager();
networkManager.on(NetworkManagerEmittedEvents.Request, (event) => {
networkManager.on(NetworkManagerEmittedEvents.Request, event => {
return this.emit(PageEmittedEvents.Request, event);
});
networkManager.on(
NetworkManagerEmittedEvents.RequestServedFromCache,
(event) => {
event => {
return this.emit(PageEmittedEvents.RequestServedFromCache, event);
}
);
networkManager.on(NetworkManagerEmittedEvents.Response, (event) => {
networkManager.on(NetworkManagerEmittedEvents.Response, event => {
return this.emit(PageEmittedEvents.Response, event);
});
networkManager.on(NetworkManagerEmittedEvents.RequestFailed, (event) => {
networkManager.on(NetworkManagerEmittedEvents.RequestFailed, event => {
return this.emit(PageEmittedEvents.RequestFailed, event);
});
networkManager.on(NetworkManagerEmittedEvents.RequestFinished, (event) => {
networkManager.on(NetworkManagerEmittedEvents.RequestFinished, event => {
return this.emit(PageEmittedEvents.RequestFinished, event);
});
this.#fileChooserInterceptors = new Set();
@ -591,28 +583,28 @@ export class Page extends EventEmitter {
client.on('Page.loadEventFired', () => {
return this.emit(PageEmittedEvents.Load);
});
client.on('Runtime.consoleAPICalled', (event) => {
client.on('Runtime.consoleAPICalled', event => {
return this.#onConsoleAPI(event);
});
client.on('Runtime.bindingCalled', (event) => {
client.on('Runtime.bindingCalled', event => {
return this.#onBindingCalled(event);
});
client.on('Page.javascriptDialogOpening', (event) => {
client.on('Page.javascriptDialogOpening', event => {
return this.#onDialog(event);
});
client.on('Runtime.exceptionThrown', (exception) => {
client.on('Runtime.exceptionThrown', exception => {
return this.#handleException(exception.exceptionDetails);
});
client.on('Inspector.targetCrashed', () => {
return this.#onTargetCrashed();
});
client.on('Performance.metrics', (event) => {
client.on('Performance.metrics', event => {
return this.#emitMetrics(event);
});
client.on('Log.entryAdded', (event) => {
client.on('Log.entryAdded', event => {
return this.#onLogEntryAdded(event);
});
client.on('Page.fileChooserOpened', (event) => {
client.on('Page.fileChooserOpened', event => {
return this.#onFileChooser(event);
});
this.#target._isClosedPromise.then(() => {
@ -743,9 +735,9 @@ export class Page extends EventEmitter {
});
}
const { timeout = this.#timeoutSettings.timeout() } = options;
const {timeout = this.#timeoutSettings.timeout()} = options;
let callback!: (value: FileChooser | PromiseLike<FileChooser>) => void;
const promise = new Promise<FileChooser>((x) => {
const promise = new Promise<FileChooser>(x => {
return (callback = x);
});
this.#fileChooserInterceptors.add(callback);
@ -753,7 +745,7 @@ export class Page extends EventEmitter {
promise,
'waiting for file chooser',
timeout
).catch((error) => {
).catch(error => {
this.#fileChooserInterceptors.delete(callback);
throw error;
});
@ -770,7 +762,7 @@ export class Page extends EventEmitter {
* ```
*/
async setGeolocation(options: GeolocationOptions): Promise<void> {
const { longitude, latitude, accuracy = 0 } = options;
const {longitude, latitude, accuracy = 0} = options;
if (longitude < -180 || longitude > 180) {
throw new Error(
`Invalid longitude "${longitude}": precondition -180 <= LONGITUDE <= 180 failed.`
@ -826,16 +818,16 @@ export class Page extends EventEmitter {
}
#onLogEntryAdded(event: Protocol.Log.EntryAddedEvent): void {
const { level, text, args, source, url, lineNumber } = event.entry;
const {level, text, args, source, url, lineNumber} = event.entry;
if (args) {
args.map((arg) => {
args.map(arg => {
return releaseObject(this.#client, arg);
});
}
if (source !== 'worker') {
this.emit(
PageEmittedEvents.Console,
new ConsoleMessage(level, text, [], [{ url, lineNumber }])
new ConsoleMessage(level, text, [], [{url, lineNumber}])
);
}
}
@ -934,7 +926,7 @@ export class Page extends EventEmitter {
*/
async setDragInterception(enabled: boolean): Promise<void> {
this.#userDragInterceptionEnabled = enabled;
return this.#client.send('Input.setInterceptDrags', { enabled });
return this.#client.send('Input.setInterceptDrags', {enabled});
}
/**
@ -1337,7 +1329,7 @@ export class Page extends EventEmitter {
async setCookie(...cookies: Protocol.Network.CookieParam[]): Promise<void> {
const pageURL = this.url();
const startsWithHTTP = pageURL.startsWith('http');
const items = cookies.map((cookie) => {
const items = cookies.map(cookie => {
const item = Object.assign({}, cookie);
if (!item.url && startsWithHTTP) {
item.url = pageURL;
@ -1354,7 +1346,7 @@ export class Page extends EventEmitter {
});
await this.deleteCookie(...items);
if (items.length) {
await this.#client.send('Network.setCookies', { cookies: items });
await this.#client.send('Network.setCookies', {cookies: items});
}
}
@ -1450,7 +1442,7 @@ export class Page extends EventEmitter {
*/
async exposeFunction(
name: string,
puppeteerFunction: Function | { default: Function }
puppeteerFunction: Function | {default: Function}
): Promise<void> {
if (this.#pageBindings.has(name)) {
throw new Error(
@ -1472,12 +1464,12 @@ export class Page extends EventEmitter {
this.#pageBindings.set(name, exposedFunction);
const expression = pageBindingInitString('exposedFun', name);
await this.#client.send('Runtime.addBinding', { name: name });
await this.#client.send('Runtime.addBinding', {name: name});
await this.#client.send('Page.addScriptToEvaluateOnNewDocument', {
source: expression,
});
await Promise.all(
this.frames().map((frame) => {
this.frames().map(frame => {
return frame.evaluate(expression).catch(debugError);
})
);
@ -1609,7 +1601,7 @@ export class Page extends EventEmitter {
event.executionContextId,
this.#client
);
const values = event.args.map((arg) => {
const values = event.args.map(arg => {
return _createJSHandle(context, arg);
});
this.#addConsoleMessage(event.type, values, event.stackTrace);
@ -1618,7 +1610,7 @@ export class Page extends EventEmitter {
async #onBindingCalled(
event: Protocol.Runtime.BindingCalledEvent
): Promise<void> {
let payload: { type: string; name: string; seq: number; args: unknown[] };
let payload: {type: string; name: string; seq: number; args: unknown[]};
try {
payload = JSON.parse(event.payload);
} catch {
@ -1626,7 +1618,7 @@ export class Page extends EventEmitter {
// called before our wrapper was initialized.
return;
}
const { type, name, seq, args } = payload;
const {type, name, seq, args} = payload;
if (type !== 'exposedFun' || !this.#pageBindings.has(name)) {
return;
}
@ -1662,7 +1654,7 @@ export class Page extends EventEmitter {
stackTrace?: Protocol.Runtime.StackTrace
): void {
if (!this.listenerCount(PageEmittedEvents.Console)) {
args.forEach((arg) => {
args.forEach(arg => {
return arg.dispose();
});
return;
@ -1730,7 +1722,7 @@ export class Page extends EventEmitter {
*/
async #setTransparentBackgroundColor(): Promise<void> {
await this.#client.send('Emulation.setDefaultBackgroundColorOverride', {
color: { r: 0, g: 0, b: 0, a: 0 },
color: {r: 0, g: 0, b: 0, a: 0},
});
}
@ -1836,7 +1828,7 @@ export class Page extends EventEmitter {
*/
async goto(
url: string,
options: WaitForOptions & { referer?: string } = {}
options: WaitForOptions & {referer?: string} = {}
): Promise<HTTPResponse | null> {
return await this.#frameManager.mainFrame().goto(url, options);
}
@ -1910,7 +1902,7 @@ export class Page extends EventEmitter {
#sessionClosePromise(): Promise<Error> {
if (!this.#disconnectPromise) {
this.#disconnectPromise = new Promise((fulfill) => {
this.#disconnectPromise = new Promise(fulfill => {
return this.#client.once(CDPSessionEmittedEvents.Disconnected, () => {
return fulfill(new Error('Target closed'));
});
@ -1946,13 +1938,13 @@ export class Page extends EventEmitter {
*/
async waitForRequest(
urlOrPredicate: string | ((req: HTTPRequest) => boolean | Promise<boolean>),
options: { timeout?: number } = {}
options: {timeout?: number} = {}
): Promise<HTTPRequest> {
const { timeout = this.#timeoutSettings.timeout() } = options;
const {timeout = this.#timeoutSettings.timeout()} = options;
return waitForEvent(
this.#frameManager.networkManager(),
NetworkManagerEmittedEvents.Request,
(request) => {
request => {
if (isString(urlOrPredicate)) {
return urlOrPredicate === request.url();
}
@ -1995,13 +1987,13 @@ export class Page extends EventEmitter {
urlOrPredicate:
| string
| ((res: HTTPResponse) => boolean | Promise<boolean>),
options: { timeout?: number } = {}
options: {timeout?: number} = {}
): Promise<HTTPResponse> {
const { timeout = this.#timeoutSettings.timeout() } = options;
const {timeout = this.#timeoutSettings.timeout()} = options;
return waitForEvent(
this.#frameManager.networkManager(),
NetworkManagerEmittedEvents.Response,
async (response) => {
async response => {
if (isString(urlOrPredicate)) {
return urlOrPredicate === response.url();
}
@ -2020,15 +2012,14 @@ export class Page extends EventEmitter {
* @returns Promise which resolves when network is idle
*/
async waitForNetworkIdle(
options: { idleTime?: number; timeout?: number } = {}
options: {idleTime?: number; timeout?: number} = {}
): Promise<void> {
const { idleTime = 500, timeout = this.#timeoutSettings.timeout() } =
options;
const {idleTime = 500, timeout = this.#timeoutSettings.timeout()} = options;
const networkManager = this.#frameManager.networkManager();
let idleResolveCallback: () => void;
const idlePromise = new Promise<void>((resolve) => {
const idlePromise = new Promise<void>(resolve => {
idleResolveCallback = resolve;
});
@ -2081,11 +2072,11 @@ export class Page extends EventEmitter {
...eventPromises,
this.#sessionClosePromise(),
]).then(
(r) => {
r => {
cleanup();
return r;
},
(error) => {
error => {
cleanup();
throw error;
}
@ -2111,9 +2102,9 @@ export class Page extends EventEmitter {
*/
async waitForFrame(
urlOrPredicate: string | ((frame: Frame) => boolean | Promise<boolean>),
options: { timeout?: number } = {}
options: {timeout?: number} = {}
): Promise<Frame> {
const { timeout = this.#timeoutSettings.timeout() } = options;
const {timeout = this.#timeoutSettings.timeout()} = options;
let predicate: (frame: Frame) => Promise<boolean>;
if (isString(urlOrPredicate)) {
@ -2145,7 +2136,7 @@ export class Page extends EventEmitter {
timeout,
this.#sessionClosePromise()
),
...this.frames().map(async (frame) => {
...this.frames().map(async frame => {
if (await predicate(frame)) {
return frame;
}
@ -2231,7 +2222,7 @@ export class Page extends EventEmitter {
}
const result = await Promise.all([
this.waitForNavigation(options),
this.#client.send('Page.navigateToHistoryEntry', { entryId: entry.id }),
this.#client.send('Page.navigateToHistoryEntry', {entryId: entry.id}),
]);
return result[0];
}
@ -2302,7 +2293,7 @@ export class Page extends EventEmitter {
* before navigating to the domain.
*/
async setBypassCSP(enabled: boolean): Promise<void> {
await this.#client.send('Page.setBypassCSP', { enabled });
await this.#client.send('Page.setBypassCSP', {enabled});
}
/**
@ -2850,17 +2841,17 @@ export class Page extends EventEmitter {
targetId: this.#target._targetId,
});
let clip = options.clip ? processClip(options.clip) : undefined;
let { captureBeyondViewport = true } = options;
let {captureBeyondViewport = true} = options;
captureBeyondViewport =
typeof captureBeyondViewport === 'boolean' ? captureBeyondViewport : true;
if (options.fullPage) {
const metrics = await this.#client.send('Page.getLayoutMetrics');
// Fallback to `contentSize` in case of using Firefox.
const { width, height } = metrics.cssContentSize || metrics.contentSize;
const {width, height} = metrics.cssContentSize || metrics.contentSize;
// Overwrite clip for full page.
clip = { x: 0, y: 0, width, height, scale: 1 };
clip = {x: 0, y: 0, width, height, scale: 1};
if (!captureBeyondViewport) {
const {
@ -2870,8 +2861,8 @@ export class Page extends EventEmitter {
} = this.#viewport || {};
const screenOrientation: Protocol.Emulation.ScreenOrientation =
isLandscape
? { angle: 90, type: 'landscapePrimary' }
: { angle: 0, type: 'portraitPrimary' };
? {angle: 90, type: 'landscapePrimary'}
: {angle: 0, type: 'portraitPrimary'};
await this.#client.send('Emulation.setDeviceMetricsOverride', {
mobile: isMobile,
width,
@ -2923,12 +2914,12 @@ export class Page extends EventEmitter {
function processClip(
clip: ScreenshotClip
): ScreenshotClip & { scale: number } {
): ScreenshotClip & {scale: number} {
const x = Math.round(clip.x);
const y = Math.round(clip.y);
const width = Math.round(clip.width + clip.x - x);
const height = Math.round(clip.height + clip.y - y);
return { x, y, width, height, scale: 1 };
return {x, y, width, height, scale: 1};
}
}
@ -3025,7 +3016,7 @@ export class Page extends EventEmitter {
* @returns
*/
async pdf(options: PDFOptions = {}): Promise<Buffer> {
const { path = undefined } = options;
const {path = undefined} = options;
const readable = await this.createPDFStream(options);
const buffer = await getReadableAsBuffer(readable, path);
assert(buffer, 'Could not create buffer');
@ -3042,7 +3033,7 @@ export class Page extends EventEmitter {
}
async close(
options: { runBeforeUnload?: boolean } = { runBeforeUnload: undefined }
options: {runBeforeUnload?: boolean} = {runBeforeUnload: undefined}
): Promise<void> {
const connection = this.#client.connection();
assert(
@ -3207,7 +3198,7 @@ export class Page extends EventEmitter {
type(
selector: string,
text: string,
options?: { delay: number }
options?: {delay: number}
): Promise<void> {
return this.mainFrame().type(selector, text, options);
}

View File

@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { puppeteerErrors, PuppeteerErrors } from './Errors.js';
import { ConnectionTransport } from './ConnectionTransport.js';
import { _devicesMap, DevicesMap } from './DeviceDescriptors.js';
import { Browser } from './Browser.js';
import {puppeteerErrors, PuppeteerErrors} from './Errors.js';
import {ConnectionTransport} from './ConnectionTransport.js';
import {_devicesMap, DevicesMap} from './DeviceDescriptors.js';
import {Browser} from './Browser.js';
import {
_registerCustomQueryHandler,
_unregisterCustomQueryHandler,
@ -24,11 +24,8 @@ import {
_clearCustomQueryHandlers,
CustomQueryHandler,
} from './QueryHandler.js';
import { Product } from './Product.js';
import {
_connectToBrowser,
BrowserConnectOptions,
} from './BrowserConnector.js';
import {Product} from './Product.js';
import {_connectToBrowser, BrowserConnectOptions} from './BrowserConnector.js';
import {
PredefinedNetworkConditions,
networkConditions,

View File

@ -14,9 +14,9 @@
* limitations under the License.
*/
import { WaitForSelectorOptions, DOMWorld } from './DOMWorld.js';
import { ElementHandle, JSHandle } from './JSHandle.js';
import { _ariaHandler } from './AriaQueryHandler.js';
import {WaitForSelectorOptions, DOMWorld} from './DOMWorld.js';
import {ElementHandle, JSHandle} from './JSHandle.js';
import {_ariaHandler} from './AriaQueryHandler.js';
/**
* @internal
@ -211,7 +211,7 @@ export function _unregisterCustomQueryHandler(name: string): void {
* @internal
*/
export function _customQueryHandlerNames(): string[] {
return [...queryHandlers.keys()].filter((name) => {
return [...queryHandlers.keys()].filter(name => {
return !builtInHandlers.has(name);
});
}
@ -232,7 +232,7 @@ export function _getQueryHandlerAndSelector(selector: string): {
} {
const hasCustomQueryHandler = /^[a-zA-Z]+\//.test(selector);
if (!hasCustomQueryHandler) {
return { updatedSelector: selector, queryHandler: _defaultHandler };
return {updatedSelector: selector, queryHandler: _defaultHandler};
}
const index = selector.indexOf('/');

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import {Protocol} from 'devtools-protocol';
/**
* The SecurityDetails class represents the security details of a

View File

@ -14,13 +14,13 @@
* limitations under the License.
*/
import { Page, PageEmittedEvents } from './Page.js';
import { WebWorker } from './WebWorker.js';
import { CDPSession } from './Connection.js';
import { Browser, BrowserContext, IsPageTargetCallback } from './Browser.js';
import { Viewport } from './PuppeteerViewport.js';
import { Protocol } from 'devtools-protocol';
import { TaskQueue } from './TaskQueue.js';
import {Page, PageEmittedEvents} from './Page.js';
import {WebWorker} from './WebWorker.js';
import {CDPSession} from './Connection.js';
import {Browser, BrowserContext, IsPageTargetCallback} from './Browser.js';
import {Viewport} from './PuppeteerViewport.js';
import {Protocol} from 'devtools-protocol';
import {TaskQueue} from './TaskQueue.js';
/**
* @public
@ -84,9 +84,9 @@ export class Target {
this.#defaultViewport = defaultViewport ?? undefined;
this.#screenshotTaskQueue = screenshotTaskQueue;
this._isPageTargetCallback = isPageTargetCallback;
this._initializedPromise = new Promise<boolean>((fulfill) => {
this._initializedPromise = new Promise<boolean>(fulfill => {
return (this._initializedCallback = fulfill);
}).then(async (success) => {
}).then(async success => {
if (!success) {
return false;
}
@ -102,7 +102,7 @@ export class Target {
openerPage.emit(PageEmittedEvents.Popup, popupPage);
return true;
});
this._isClosedPromise = new Promise<void>((fulfill) => {
this._isClosedPromise = new Promise<void>(fulfill => {
return (this._closedCallback = fulfill);
});
this._isInitialized =
@ -132,7 +132,7 @@ export class Target {
*/
async page(): Promise<Page | null> {
if (this._isPageTargetCallback(this.#targetInfo) && !this.#pagePromise) {
this.#pagePromise = this.#sessionFactory().then((client) => {
this.#pagePromise = this.#sessionFactory().then(client => {
return Page._create(
client,
this,
@ -157,7 +157,7 @@ export class Target {
}
if (!this.#workerPromise) {
// TODO(einbinder): Make workers send their console logs.
this.#workerPromise = this.#sessionFactory().then((client) => {
this.#workerPromise = this.#sessionFactory().then(client => {
return new WebWorker(
client,
this.#targetInfo.url,
@ -220,7 +220,7 @@ export class Target {
* Get the target that opened this target. Top-level targets return `null`.
*/
opener(): Target | undefined {
const { openerId } = this.#targetInfo;
const {openerId} = this.#targetInfo;
if (!openerId) {
return;
}

View File

@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { assert } from './assert.js';
import {assert} from './assert.js';
import {
getReadableAsBuffer,
getReadableFromProtocolStream,
isErrorLike,
} from './util.js';
import { CDPSession } from './Connection.js';
import {CDPSession} from './Connection.js';
/**
* @public
@ -83,24 +83,20 @@ export class Tracing {
'disabled-by-default-devtools.timeline.stack',
'disabled-by-default-v8.cpu_profiler',
];
const {
path,
screenshots = false,
categories = defaultCategories,
} = options;
const {path, screenshots = false, categories = defaultCategories} = options;
if (screenshots) {
categories.push('disabled-by-default-devtools.screenshot');
}
const excludedCategories = categories
.filter((cat) => {
.filter(cat => {
return cat.startsWith('-');
})
.map((cat) => {
.map(cat => {
return cat.slice(1);
});
const includedCategories = categories.filter((cat) => {
const includedCategories = categories.filter(cat => {
return !cat.startsWith('-');
});
@ -126,7 +122,7 @@ export class Tracing {
resolve = x;
reject = y;
});
this.#client.once('Tracing.tracingComplete', async (event) => {
this.#client.once('Tracing.tracingComplete', async event => {
try {
const readable = await getReadableFromProtocolStream(
this.#client,

View File

@ -295,22 +295,22 @@ export type KeyInput =
* @internal
*/
export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
'0': { keyCode: 48, key: '0', code: 'Digit0' },
'1': { keyCode: 49, key: '1', code: 'Digit1' },
'2': { keyCode: 50, key: '2', code: 'Digit2' },
'3': { keyCode: 51, key: '3', code: 'Digit3' },
'4': { keyCode: 52, key: '4', code: 'Digit4' },
'5': { keyCode: 53, key: '5', code: 'Digit5' },
'6': { keyCode: 54, key: '6', code: 'Digit6' },
'7': { keyCode: 55, key: '7', code: 'Digit7' },
'8': { keyCode: 56, key: '8', code: 'Digit8' },
'9': { keyCode: 57, key: '9', code: 'Digit9' },
Power: { key: 'Power', code: 'Power' },
Eject: { key: 'Eject', code: 'Eject' },
Abort: { keyCode: 3, code: 'Abort', key: 'Cancel' },
Help: { keyCode: 6, code: 'Help', key: 'Help' },
Backspace: { keyCode: 8, code: 'Backspace', key: 'Backspace' },
Tab: { keyCode: 9, code: 'Tab', key: 'Tab' },
'0': {keyCode: 48, key: '0', code: 'Digit0'},
'1': {keyCode: 49, key: '1', code: 'Digit1'},
'2': {keyCode: 50, key: '2', code: 'Digit2'},
'3': {keyCode: 51, key: '3', code: 'Digit3'},
'4': {keyCode: 52, key: '4', code: 'Digit4'},
'5': {keyCode: 53, key: '5', code: 'Digit5'},
'6': {keyCode: 54, key: '6', code: 'Digit6'},
'7': {keyCode: 55, key: '7', code: 'Digit7'},
'8': {keyCode: 56, key: '8', code: 'Digit8'},
'9': {keyCode: 57, key: '9', code: 'Digit9'},
Power: {key: 'Power', code: 'Power'},
Eject: {key: 'Eject', code: 'Eject'},
Abort: {keyCode: 3, code: 'Abort', key: 'Cancel'},
Help: {keyCode: 6, code: 'Help', key: 'Help'},
Backspace: {keyCode: 8, code: 'Backspace', key: 'Backspace'},
Tab: {keyCode: 9, code: 'Tab', key: 'Tab'},
Numpad5: {
keyCode: 12,
shiftKeyCode: 101,
@ -326,11 +326,11 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
text: '\r',
location: 3,
},
Enter: { keyCode: 13, code: 'Enter', key: 'Enter', text: '\r' },
'\r': { keyCode: 13, code: 'Enter', key: 'Enter', text: '\r' },
'\n': { keyCode: 13, code: 'Enter', key: 'Enter', text: '\r' },
ShiftLeft: { keyCode: 16, code: 'ShiftLeft', key: 'Shift', location: 1 },
ShiftRight: { keyCode: 16, code: 'ShiftRight', key: 'Shift', location: 2 },
Enter: {keyCode: 13, code: 'Enter', key: 'Enter', text: '\r'},
'\r': {keyCode: 13, code: 'Enter', key: 'Enter', text: '\r'},
'\n': {keyCode: 13, code: 'Enter', key: 'Enter', text: '\r'},
ShiftLeft: {keyCode: 16, code: 'ShiftLeft', key: 'Shift', location: 1},
ShiftRight: {keyCode: 16, code: 'ShiftRight', key: 'Shift', location: 2},
ControlLeft: {
keyCode: 17,
code: 'ControlLeft',
@ -343,14 +343,14 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
key: 'Control',
location: 2,
},
AltLeft: { keyCode: 18, code: 'AltLeft', key: 'Alt', location: 1 },
AltRight: { keyCode: 18, code: 'AltRight', key: 'Alt', location: 2 },
Pause: { keyCode: 19, code: 'Pause', key: 'Pause' },
CapsLock: { keyCode: 20, code: 'CapsLock', key: 'CapsLock' },
Escape: { keyCode: 27, code: 'Escape', key: 'Escape' },
Convert: { keyCode: 28, code: 'Convert', key: 'Convert' },
NonConvert: { keyCode: 29, code: 'NonConvert', key: 'NonConvert' },
Space: { keyCode: 32, code: 'Space', key: ' ' },
AltLeft: {keyCode: 18, code: 'AltLeft', key: 'Alt', location: 1},
AltRight: {keyCode: 18, code: 'AltRight', key: 'Alt', location: 2},
Pause: {keyCode: 19, code: 'Pause', key: 'Pause'},
CapsLock: {keyCode: 20, code: 'CapsLock', key: 'CapsLock'},
Escape: {keyCode: 27, code: 'Escape', key: 'Escape'},
Convert: {keyCode: 28, code: 'Convert', key: 'Convert'},
NonConvert: {keyCode: 29, code: 'NonConvert', key: 'NonConvert'},
Space: {keyCode: 32, code: 'Space', key: ' '},
Numpad9: {
keyCode: 33,
shiftKeyCode: 105,
@ -359,7 +359,7 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
shiftKey: '9',
location: 3,
},
PageUp: { keyCode: 33, code: 'PageUp', key: 'PageUp' },
PageUp: {keyCode: 33, code: 'PageUp', key: 'PageUp'},
Numpad3: {
keyCode: 34,
shiftKeyCode: 99,
@ -368,8 +368,8 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
shiftKey: '3',
location: 3,
},
PageDown: { keyCode: 34, code: 'PageDown', key: 'PageDown' },
End: { keyCode: 35, code: 'End', key: 'End' },
PageDown: {keyCode: 34, code: 'PageDown', key: 'PageDown'},
End: {keyCode: 35, code: 'End', key: 'End'},
Numpad1: {
keyCode: 35,
shiftKeyCode: 97,
@ -378,7 +378,7 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
shiftKey: '1',
location: 3,
},
Home: { keyCode: 36, code: 'Home', key: 'Home' },
Home: {keyCode: 36, code: 'Home', key: 'Home'},
Numpad7: {
keyCode: 36,
shiftKeyCode: 103,
@ -387,7 +387,7 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
shiftKey: '7',
location: 3,
},
ArrowLeft: { keyCode: 37, code: 'ArrowLeft', key: 'ArrowLeft' },
ArrowLeft: {keyCode: 37, code: 'ArrowLeft', key: 'ArrowLeft'},
Numpad4: {
keyCode: 37,
shiftKeyCode: 100,
@ -404,8 +404,8 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
shiftKey: '8',
location: 3,
},
ArrowUp: { keyCode: 38, code: 'ArrowUp', key: 'ArrowUp' },
ArrowRight: { keyCode: 39, code: 'ArrowRight', key: 'ArrowRight' },
ArrowUp: {keyCode: 38, code: 'ArrowUp', key: 'ArrowUp'},
ArrowRight: {keyCode: 39, code: 'ArrowRight', key: 'ArrowRight'},
Numpad6: {
keyCode: 39,
shiftKeyCode: 102,
@ -422,11 +422,11 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
shiftKey: '2',
location: 3,
},
ArrowDown: { keyCode: 40, code: 'ArrowDown', key: 'ArrowDown' },
Select: { keyCode: 41, code: 'Select', key: 'Select' },
Open: { keyCode: 43, code: 'Open', key: 'Execute' },
PrintScreen: { keyCode: 44, code: 'PrintScreen', key: 'PrintScreen' },
Insert: { keyCode: 45, code: 'Insert', key: 'Insert' },
ArrowDown: {keyCode: 40, code: 'ArrowDown', key: 'ArrowDown'},
Select: {keyCode: 41, code: 'Select', key: 'Select'},
Open: {keyCode: 43, code: 'Open', key: 'Execute'},
PrintScreen: {keyCode: 44, code: 'PrintScreen', key: 'PrintScreen'},
Insert: {keyCode: 45, code: 'Insert', key: 'Insert'},
Numpad0: {
keyCode: 45,
shiftKeyCode: 96,
@ -435,7 +435,7 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
shiftKey: '0',
location: 3,
},
Delete: { keyCode: 46, code: 'Delete', key: 'Delete' },
Delete: {keyCode: 46, code: 'Delete', key: 'Delete'},
NumpadDecimal: {
keyCode: 46,
shiftKeyCode: 110,
@ -444,85 +444,85 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
shiftKey: '.',
location: 3,
},
Digit0: { keyCode: 48, code: 'Digit0', shiftKey: ')', key: '0' },
Digit1: { keyCode: 49, code: 'Digit1', shiftKey: '!', key: '1' },
Digit2: { keyCode: 50, code: 'Digit2', shiftKey: '@', key: '2' },
Digit3: { keyCode: 51, code: 'Digit3', shiftKey: '#', key: '3' },
Digit4: { keyCode: 52, code: 'Digit4', shiftKey: '$', key: '4' },
Digit5: { keyCode: 53, code: 'Digit5', shiftKey: '%', key: '5' },
Digit6: { keyCode: 54, code: 'Digit6', shiftKey: '^', key: '6' },
Digit7: { keyCode: 55, code: 'Digit7', shiftKey: '&', key: '7' },
Digit8: { keyCode: 56, code: 'Digit8', shiftKey: '*', key: '8' },
Digit9: { keyCode: 57, code: 'Digit9', shiftKey: '(', key: '9' },
KeyA: { keyCode: 65, code: 'KeyA', shiftKey: 'A', key: 'a' },
KeyB: { keyCode: 66, code: 'KeyB', shiftKey: 'B', key: 'b' },
KeyC: { keyCode: 67, code: 'KeyC', shiftKey: 'C', key: 'c' },
KeyD: { keyCode: 68, code: 'KeyD', shiftKey: 'D', key: 'd' },
KeyE: { keyCode: 69, code: 'KeyE', shiftKey: 'E', key: 'e' },
KeyF: { keyCode: 70, code: 'KeyF', shiftKey: 'F', key: 'f' },
KeyG: { keyCode: 71, code: 'KeyG', shiftKey: 'G', key: 'g' },
KeyH: { keyCode: 72, code: 'KeyH', shiftKey: 'H', key: 'h' },
KeyI: { keyCode: 73, code: 'KeyI', shiftKey: 'I', key: 'i' },
KeyJ: { keyCode: 74, code: 'KeyJ', shiftKey: 'J', key: 'j' },
KeyK: { keyCode: 75, code: 'KeyK', shiftKey: 'K', key: 'k' },
KeyL: { keyCode: 76, code: 'KeyL', shiftKey: 'L', key: 'l' },
KeyM: { keyCode: 77, code: 'KeyM', shiftKey: 'M', key: 'm' },
KeyN: { keyCode: 78, code: 'KeyN', shiftKey: 'N', key: 'n' },
KeyO: { keyCode: 79, code: 'KeyO', shiftKey: 'O', key: 'o' },
KeyP: { keyCode: 80, code: 'KeyP', shiftKey: 'P', key: 'p' },
KeyQ: { keyCode: 81, code: 'KeyQ', shiftKey: 'Q', key: 'q' },
KeyR: { keyCode: 82, code: 'KeyR', shiftKey: 'R', key: 'r' },
KeyS: { keyCode: 83, code: 'KeyS', shiftKey: 'S', key: 's' },
KeyT: { keyCode: 84, code: 'KeyT', shiftKey: 'T', key: 't' },
KeyU: { keyCode: 85, code: 'KeyU', shiftKey: 'U', key: 'u' },
KeyV: { keyCode: 86, code: 'KeyV', shiftKey: 'V', key: 'v' },
KeyW: { keyCode: 87, code: 'KeyW', shiftKey: 'W', key: 'w' },
KeyX: { keyCode: 88, code: 'KeyX', shiftKey: 'X', key: 'x' },
KeyY: { keyCode: 89, code: 'KeyY', shiftKey: 'Y', key: 'y' },
KeyZ: { keyCode: 90, code: 'KeyZ', shiftKey: 'Z', key: 'z' },
MetaLeft: { keyCode: 91, code: 'MetaLeft', key: 'Meta', location: 1 },
MetaRight: { keyCode: 92, code: 'MetaRight', key: 'Meta', location: 2 },
ContextMenu: { keyCode: 93, code: 'ContextMenu', key: 'ContextMenu' },
Digit0: {keyCode: 48, code: 'Digit0', shiftKey: ')', key: '0'},
Digit1: {keyCode: 49, code: 'Digit1', shiftKey: '!', key: '1'},
Digit2: {keyCode: 50, code: 'Digit2', shiftKey: '@', key: '2'},
Digit3: {keyCode: 51, code: 'Digit3', shiftKey: '#', key: '3'},
Digit4: {keyCode: 52, code: 'Digit4', shiftKey: '$', key: '4'},
Digit5: {keyCode: 53, code: 'Digit5', shiftKey: '%', key: '5'},
Digit6: {keyCode: 54, code: 'Digit6', shiftKey: '^', key: '6'},
Digit7: {keyCode: 55, code: 'Digit7', shiftKey: '&', key: '7'},
Digit8: {keyCode: 56, code: 'Digit8', shiftKey: '*', key: '8'},
Digit9: {keyCode: 57, code: 'Digit9', shiftKey: '(', key: '9'},
KeyA: {keyCode: 65, code: 'KeyA', shiftKey: 'A', key: 'a'},
KeyB: {keyCode: 66, code: 'KeyB', shiftKey: 'B', key: 'b'},
KeyC: {keyCode: 67, code: 'KeyC', shiftKey: 'C', key: 'c'},
KeyD: {keyCode: 68, code: 'KeyD', shiftKey: 'D', key: 'd'},
KeyE: {keyCode: 69, code: 'KeyE', shiftKey: 'E', key: 'e'},
KeyF: {keyCode: 70, code: 'KeyF', shiftKey: 'F', key: 'f'},
KeyG: {keyCode: 71, code: 'KeyG', shiftKey: 'G', key: 'g'},
KeyH: {keyCode: 72, code: 'KeyH', shiftKey: 'H', key: 'h'},
KeyI: {keyCode: 73, code: 'KeyI', shiftKey: 'I', key: 'i'},
KeyJ: {keyCode: 74, code: 'KeyJ', shiftKey: 'J', key: 'j'},
KeyK: {keyCode: 75, code: 'KeyK', shiftKey: 'K', key: 'k'},
KeyL: {keyCode: 76, code: 'KeyL', shiftKey: 'L', key: 'l'},
KeyM: {keyCode: 77, code: 'KeyM', shiftKey: 'M', key: 'm'},
KeyN: {keyCode: 78, code: 'KeyN', shiftKey: 'N', key: 'n'},
KeyO: {keyCode: 79, code: 'KeyO', shiftKey: 'O', key: 'o'},
KeyP: {keyCode: 80, code: 'KeyP', shiftKey: 'P', key: 'p'},
KeyQ: {keyCode: 81, code: 'KeyQ', shiftKey: 'Q', key: 'q'},
KeyR: {keyCode: 82, code: 'KeyR', shiftKey: 'R', key: 'r'},
KeyS: {keyCode: 83, code: 'KeyS', shiftKey: 'S', key: 's'},
KeyT: {keyCode: 84, code: 'KeyT', shiftKey: 'T', key: 't'},
KeyU: {keyCode: 85, code: 'KeyU', shiftKey: 'U', key: 'u'},
KeyV: {keyCode: 86, code: 'KeyV', shiftKey: 'V', key: 'v'},
KeyW: {keyCode: 87, code: 'KeyW', shiftKey: 'W', key: 'w'},
KeyX: {keyCode: 88, code: 'KeyX', shiftKey: 'X', key: 'x'},
KeyY: {keyCode: 89, code: 'KeyY', shiftKey: 'Y', key: 'y'},
KeyZ: {keyCode: 90, code: 'KeyZ', shiftKey: 'Z', key: 'z'},
MetaLeft: {keyCode: 91, code: 'MetaLeft', key: 'Meta', location: 1},
MetaRight: {keyCode: 92, code: 'MetaRight', key: 'Meta', location: 2},
ContextMenu: {keyCode: 93, code: 'ContextMenu', key: 'ContextMenu'},
NumpadMultiply: {
keyCode: 106,
code: 'NumpadMultiply',
key: '*',
location: 3,
},
NumpadAdd: { keyCode: 107, code: 'NumpadAdd', key: '+', location: 3 },
NumpadAdd: {keyCode: 107, code: 'NumpadAdd', key: '+', location: 3},
NumpadSubtract: {
keyCode: 109,
code: 'NumpadSubtract',
key: '-',
location: 3,
},
NumpadDivide: { keyCode: 111, code: 'NumpadDivide', key: '/', location: 3 },
F1: { keyCode: 112, code: 'F1', key: 'F1' },
F2: { keyCode: 113, code: 'F2', key: 'F2' },
F3: { keyCode: 114, code: 'F3', key: 'F3' },
F4: { keyCode: 115, code: 'F4', key: 'F4' },
F5: { keyCode: 116, code: 'F5', key: 'F5' },
F6: { keyCode: 117, code: 'F6', key: 'F6' },
F7: { keyCode: 118, code: 'F7', key: 'F7' },
F8: { keyCode: 119, code: 'F8', key: 'F8' },
F9: { keyCode: 120, code: 'F9', key: 'F9' },
F10: { keyCode: 121, code: 'F10', key: 'F10' },
F11: { keyCode: 122, code: 'F11', key: 'F11' },
F12: { keyCode: 123, code: 'F12', key: 'F12' },
F13: { keyCode: 124, code: 'F13', key: 'F13' },
F14: { keyCode: 125, code: 'F14', key: 'F14' },
F15: { keyCode: 126, code: 'F15', key: 'F15' },
F16: { keyCode: 127, code: 'F16', key: 'F16' },
F17: { keyCode: 128, code: 'F17', key: 'F17' },
F18: { keyCode: 129, code: 'F18', key: 'F18' },
F19: { keyCode: 130, code: 'F19', key: 'F19' },
F20: { keyCode: 131, code: 'F20', key: 'F20' },
F21: { keyCode: 132, code: 'F21', key: 'F21' },
F22: { keyCode: 133, code: 'F22', key: 'F22' },
F23: { keyCode: 134, code: 'F23', key: 'F23' },
F24: { keyCode: 135, code: 'F24', key: 'F24' },
NumLock: { keyCode: 144, code: 'NumLock', key: 'NumLock' },
ScrollLock: { keyCode: 145, code: 'ScrollLock', key: 'ScrollLock' },
NumpadDivide: {keyCode: 111, code: 'NumpadDivide', key: '/', location: 3},
F1: {keyCode: 112, code: 'F1', key: 'F1'},
F2: {keyCode: 113, code: 'F2', key: 'F2'},
F3: {keyCode: 114, code: 'F3', key: 'F3'},
F4: {keyCode: 115, code: 'F4', key: 'F4'},
F5: {keyCode: 116, code: 'F5', key: 'F5'},
F6: {keyCode: 117, code: 'F6', key: 'F6'},
F7: {keyCode: 118, code: 'F7', key: 'F7'},
F8: {keyCode: 119, code: 'F8', key: 'F8'},
F9: {keyCode: 120, code: 'F9', key: 'F9'},
F10: {keyCode: 121, code: 'F10', key: 'F10'},
F11: {keyCode: 122, code: 'F11', key: 'F11'},
F12: {keyCode: 123, code: 'F12', key: 'F12'},
F13: {keyCode: 124, code: 'F13', key: 'F13'},
F14: {keyCode: 125, code: 'F14', key: 'F14'},
F15: {keyCode: 126, code: 'F15', key: 'F15'},
F16: {keyCode: 127, code: 'F16', key: 'F16'},
F17: {keyCode: 128, code: 'F17', key: 'F17'},
F18: {keyCode: 129, code: 'F18', key: 'F18'},
F19: {keyCode: 130, code: 'F19', key: 'F19'},
F20: {keyCode: 131, code: 'F20', key: 'F20'},
F21: {keyCode: 132, code: 'F21', key: 'F21'},
F22: {keyCode: 133, code: 'F22', key: 'F22'},
F23: {keyCode: 134, code: 'F23', key: 'F23'},
F24: {keyCode: 135, code: 'F24', key: 'F24'},
NumLock: {keyCode: 144, code: 'NumLock', key: 'NumLock'},
ScrollLock: {keyCode: 145, code: 'ScrollLock', key: 'ScrollLock'},
AudioVolumeMute: {
keyCode: 173,
code: 'AudioVolumeMute',
@ -533,7 +533,7 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
code: 'AudioVolumeDown',
key: 'AudioVolumeDown',
},
AudioVolumeUp: { keyCode: 175, code: 'AudioVolumeUp', key: 'AudioVolumeUp' },
AudioVolumeUp: {keyCode: 175, code: 'AudioVolumeUp', key: 'AudioVolumeUp'},
MediaTrackNext: {
keyCode: 176,
code: 'MediaTrackNext',
@ -544,138 +544,138 @@ export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
code: 'MediaTrackPrevious',
key: 'MediaTrackPrevious',
},
MediaStop: { keyCode: 178, code: 'MediaStop', key: 'MediaStop' },
MediaStop: {keyCode: 178, code: 'MediaStop', key: 'MediaStop'},
MediaPlayPause: {
keyCode: 179,
code: 'MediaPlayPause',
key: 'MediaPlayPause',
},
Semicolon: { keyCode: 186, code: 'Semicolon', shiftKey: ':', key: ';' },
Equal: { keyCode: 187, code: 'Equal', shiftKey: '+', key: '=' },
NumpadEqual: { keyCode: 187, code: 'NumpadEqual', key: '=', location: 3 },
Comma: { keyCode: 188, code: 'Comma', shiftKey: '<', key: ',' },
Minus: { keyCode: 189, code: 'Minus', shiftKey: '_', key: '-' },
Period: { keyCode: 190, code: 'Period', shiftKey: '>', key: '.' },
Slash: { keyCode: 191, code: 'Slash', shiftKey: '?', key: '/' },
Backquote: { keyCode: 192, code: 'Backquote', shiftKey: '~', key: '`' },
BracketLeft: { keyCode: 219, code: 'BracketLeft', shiftKey: '{', key: '[' },
Backslash: { keyCode: 220, code: 'Backslash', shiftKey: '|', key: '\\' },
BracketRight: { keyCode: 221, code: 'BracketRight', shiftKey: '}', key: ']' },
Quote: { keyCode: 222, code: 'Quote', shiftKey: '"', key: "'" },
AltGraph: { keyCode: 225, code: 'AltGraph', key: 'AltGraph' },
Props: { keyCode: 247, code: 'Props', key: 'CrSel' },
Cancel: { keyCode: 3, key: 'Cancel', code: 'Abort' },
Clear: { keyCode: 12, key: 'Clear', code: 'Numpad5', location: 3 },
Shift: { keyCode: 16, key: 'Shift', code: 'ShiftLeft', location: 1 },
Control: { keyCode: 17, key: 'Control', code: 'ControlLeft', location: 1 },
Alt: { keyCode: 18, key: 'Alt', code: 'AltLeft', location: 1 },
Accept: { keyCode: 30, key: 'Accept' },
ModeChange: { keyCode: 31, key: 'ModeChange' },
' ': { keyCode: 32, key: ' ', code: 'Space' },
Print: { keyCode: 42, key: 'Print' },
Execute: { keyCode: 43, key: 'Execute', code: 'Open' },
'\u0000': { keyCode: 46, key: '\u0000', code: 'NumpadDecimal', location: 3 },
a: { keyCode: 65, key: 'a', code: 'KeyA' },
b: { keyCode: 66, key: 'b', code: 'KeyB' },
c: { keyCode: 67, key: 'c', code: 'KeyC' },
d: { keyCode: 68, key: 'd', code: 'KeyD' },
e: { keyCode: 69, key: 'e', code: 'KeyE' },
f: { keyCode: 70, key: 'f', code: 'KeyF' },
g: { keyCode: 71, key: 'g', code: 'KeyG' },
h: { keyCode: 72, key: 'h', code: 'KeyH' },
i: { keyCode: 73, key: 'i', code: 'KeyI' },
j: { keyCode: 74, key: 'j', code: 'KeyJ' },
k: { keyCode: 75, key: 'k', code: 'KeyK' },
l: { keyCode: 76, key: 'l', code: 'KeyL' },
m: { keyCode: 77, key: 'm', code: 'KeyM' },
n: { keyCode: 78, key: 'n', code: 'KeyN' },
o: { keyCode: 79, key: 'o', code: 'KeyO' },
p: { keyCode: 80, key: 'p', code: 'KeyP' },
q: { keyCode: 81, key: 'q', code: 'KeyQ' },
r: { keyCode: 82, key: 'r', code: 'KeyR' },
s: { keyCode: 83, key: 's', code: 'KeyS' },
t: { keyCode: 84, key: 't', code: 'KeyT' },
u: { keyCode: 85, key: 'u', code: 'KeyU' },
v: { keyCode: 86, key: 'v', code: 'KeyV' },
w: { keyCode: 87, key: 'w', code: 'KeyW' },
x: { keyCode: 88, key: 'x', code: 'KeyX' },
y: { keyCode: 89, key: 'y', code: 'KeyY' },
z: { keyCode: 90, key: 'z', code: 'KeyZ' },
Meta: { keyCode: 91, key: 'Meta', code: 'MetaLeft', location: 1 },
'*': { keyCode: 106, key: '*', code: 'NumpadMultiply', location: 3 },
'+': { keyCode: 107, key: '+', code: 'NumpadAdd', location: 3 },
'-': { keyCode: 109, key: '-', code: 'NumpadSubtract', location: 3 },
'/': { keyCode: 111, key: '/', code: 'NumpadDivide', location: 3 },
';': { keyCode: 186, key: ';', code: 'Semicolon' },
'=': { keyCode: 187, key: '=', code: 'Equal' },
',': { keyCode: 188, key: ',', code: 'Comma' },
'.': { keyCode: 190, key: '.', code: 'Period' },
'`': { keyCode: 192, key: '`', code: 'Backquote' },
'[': { keyCode: 219, key: '[', code: 'BracketLeft' },
'\\': { keyCode: 220, key: '\\', code: 'Backslash' },
']': { keyCode: 221, key: ']', code: 'BracketRight' },
"'": { keyCode: 222, key: "'", code: 'Quote' },
Attn: { keyCode: 246, key: 'Attn' },
CrSel: { keyCode: 247, key: 'CrSel', code: 'Props' },
ExSel: { keyCode: 248, key: 'ExSel' },
EraseEof: { keyCode: 249, key: 'EraseEof' },
Play: { keyCode: 250, key: 'Play' },
ZoomOut: { keyCode: 251, key: 'ZoomOut' },
')': { keyCode: 48, key: ')', code: 'Digit0' },
'!': { keyCode: 49, key: '!', code: 'Digit1' },
'@': { keyCode: 50, key: '@', code: 'Digit2' },
'#': { keyCode: 51, key: '#', code: 'Digit3' },
$: { keyCode: 52, key: '$', code: 'Digit4' },
'%': { keyCode: 53, key: '%', code: 'Digit5' },
'^': { keyCode: 54, key: '^', code: 'Digit6' },
'&': { keyCode: 55, key: '&', code: 'Digit7' },
'(': { keyCode: 57, key: '(', code: 'Digit9' },
A: { keyCode: 65, key: 'A', code: 'KeyA' },
B: { keyCode: 66, key: 'B', code: 'KeyB' },
C: { keyCode: 67, key: 'C', code: 'KeyC' },
D: { keyCode: 68, key: 'D', code: 'KeyD' },
E: { keyCode: 69, key: 'E', code: 'KeyE' },
F: { keyCode: 70, key: 'F', code: 'KeyF' },
G: { keyCode: 71, key: 'G', code: 'KeyG' },
H: { keyCode: 72, key: 'H', code: 'KeyH' },
I: { keyCode: 73, key: 'I', code: 'KeyI' },
J: { keyCode: 74, key: 'J', code: 'KeyJ' },
K: { keyCode: 75, key: 'K', code: 'KeyK' },
L: { keyCode: 76, key: 'L', code: 'KeyL' },
M: { keyCode: 77, key: 'M', code: 'KeyM' },
N: { keyCode: 78, key: 'N', code: 'KeyN' },
O: { keyCode: 79, key: 'O', code: 'KeyO' },
P: { keyCode: 80, key: 'P', code: 'KeyP' },
Q: { keyCode: 81, key: 'Q', code: 'KeyQ' },
R: { keyCode: 82, key: 'R', code: 'KeyR' },
S: { keyCode: 83, key: 'S', code: 'KeyS' },
T: { keyCode: 84, key: 'T', code: 'KeyT' },
U: { keyCode: 85, key: 'U', code: 'KeyU' },
V: { keyCode: 86, key: 'V', code: 'KeyV' },
W: { keyCode: 87, key: 'W', code: 'KeyW' },
X: { keyCode: 88, key: 'X', code: 'KeyX' },
Y: { keyCode: 89, key: 'Y', code: 'KeyY' },
Z: { keyCode: 90, key: 'Z', code: 'KeyZ' },
':': { keyCode: 186, key: ':', code: 'Semicolon' },
'<': { keyCode: 188, key: '<', code: 'Comma' },
_: { keyCode: 189, key: '_', code: 'Minus' },
'>': { keyCode: 190, key: '>', code: 'Period' },
'?': { keyCode: 191, key: '?', code: 'Slash' },
'~': { keyCode: 192, key: '~', code: 'Backquote' },
'{': { keyCode: 219, key: '{', code: 'BracketLeft' },
'|': { keyCode: 220, key: '|', code: 'Backslash' },
'}': { keyCode: 221, key: '}', code: 'BracketRight' },
'"': { keyCode: 222, key: '"', code: 'Quote' },
SoftLeft: { key: 'SoftLeft', code: 'SoftLeft', location: 4 },
SoftRight: { key: 'SoftRight', code: 'SoftRight', location: 4 },
Camera: { keyCode: 44, key: 'Camera', code: 'Camera', location: 4 },
Call: { key: 'Call', code: 'Call', location: 4 },
EndCall: { keyCode: 95, key: 'EndCall', code: 'EndCall', location: 4 },
Semicolon: {keyCode: 186, code: 'Semicolon', shiftKey: ':', key: ';'},
Equal: {keyCode: 187, code: 'Equal', shiftKey: '+', key: '='},
NumpadEqual: {keyCode: 187, code: 'NumpadEqual', key: '=', location: 3},
Comma: {keyCode: 188, code: 'Comma', shiftKey: '<', key: ','},
Minus: {keyCode: 189, code: 'Minus', shiftKey: '_', key: '-'},
Period: {keyCode: 190, code: 'Period', shiftKey: '>', key: '.'},
Slash: {keyCode: 191, code: 'Slash', shiftKey: '?', key: '/'},
Backquote: {keyCode: 192, code: 'Backquote', shiftKey: '~', key: '`'},
BracketLeft: {keyCode: 219, code: 'BracketLeft', shiftKey: '{', key: '['},
Backslash: {keyCode: 220, code: 'Backslash', shiftKey: '|', key: '\\'},
BracketRight: {keyCode: 221, code: 'BracketRight', shiftKey: '}', key: ']'},
Quote: {keyCode: 222, code: 'Quote', shiftKey: '"', key: "'"},
AltGraph: {keyCode: 225, code: 'AltGraph', key: 'AltGraph'},
Props: {keyCode: 247, code: 'Props', key: 'CrSel'},
Cancel: {keyCode: 3, key: 'Cancel', code: 'Abort'},
Clear: {keyCode: 12, key: 'Clear', code: 'Numpad5', location: 3},
Shift: {keyCode: 16, key: 'Shift', code: 'ShiftLeft', location: 1},
Control: {keyCode: 17, key: 'Control', code: 'ControlLeft', location: 1},
Alt: {keyCode: 18, key: 'Alt', code: 'AltLeft', location: 1},
Accept: {keyCode: 30, key: 'Accept'},
ModeChange: {keyCode: 31, key: 'ModeChange'},
' ': {keyCode: 32, key: ' ', code: 'Space'},
Print: {keyCode: 42, key: 'Print'},
Execute: {keyCode: 43, key: 'Execute', code: 'Open'},
'\u0000': {keyCode: 46, key: '\u0000', code: 'NumpadDecimal', location: 3},
a: {keyCode: 65, key: 'a', code: 'KeyA'},
b: {keyCode: 66, key: 'b', code: 'KeyB'},
c: {keyCode: 67, key: 'c', code: 'KeyC'},
d: {keyCode: 68, key: 'd', code: 'KeyD'},
e: {keyCode: 69, key: 'e', code: 'KeyE'},
f: {keyCode: 70, key: 'f', code: 'KeyF'},
g: {keyCode: 71, key: 'g', code: 'KeyG'},
h: {keyCode: 72, key: 'h', code: 'KeyH'},
i: {keyCode: 73, key: 'i', code: 'KeyI'},
j: {keyCode: 74, key: 'j', code: 'KeyJ'},
k: {keyCode: 75, key: 'k', code: 'KeyK'},
l: {keyCode: 76, key: 'l', code: 'KeyL'},
m: {keyCode: 77, key: 'm', code: 'KeyM'},
n: {keyCode: 78, key: 'n', code: 'KeyN'},
o: {keyCode: 79, key: 'o', code: 'KeyO'},
p: {keyCode: 80, key: 'p', code: 'KeyP'},
q: {keyCode: 81, key: 'q', code: 'KeyQ'},
r: {keyCode: 82, key: 'r', code: 'KeyR'},
s: {keyCode: 83, key: 's', code: 'KeyS'},
t: {keyCode: 84, key: 't', code: 'KeyT'},
u: {keyCode: 85, key: 'u', code: 'KeyU'},
v: {keyCode: 86, key: 'v', code: 'KeyV'},
w: {keyCode: 87, key: 'w', code: 'KeyW'},
x: {keyCode: 88, key: 'x', code: 'KeyX'},
y: {keyCode: 89, key: 'y', code: 'KeyY'},
z: {keyCode: 90, key: 'z', code: 'KeyZ'},
Meta: {keyCode: 91, key: 'Meta', code: 'MetaLeft', location: 1},
'*': {keyCode: 106, key: '*', code: 'NumpadMultiply', location: 3},
'+': {keyCode: 107, key: '+', code: 'NumpadAdd', location: 3},
'-': {keyCode: 109, key: '-', code: 'NumpadSubtract', location: 3},
'/': {keyCode: 111, key: '/', code: 'NumpadDivide', location: 3},
';': {keyCode: 186, key: ';', code: 'Semicolon'},
'=': {keyCode: 187, key: '=', code: 'Equal'},
',': {keyCode: 188, key: ',', code: 'Comma'},
'.': {keyCode: 190, key: '.', code: 'Period'},
'`': {keyCode: 192, key: '`', code: 'Backquote'},
'[': {keyCode: 219, key: '[', code: 'BracketLeft'},
'\\': {keyCode: 220, key: '\\', code: 'Backslash'},
']': {keyCode: 221, key: ']', code: 'BracketRight'},
"'": {keyCode: 222, key: "'", code: 'Quote'},
Attn: {keyCode: 246, key: 'Attn'},
CrSel: {keyCode: 247, key: 'CrSel', code: 'Props'},
ExSel: {keyCode: 248, key: 'ExSel'},
EraseEof: {keyCode: 249, key: 'EraseEof'},
Play: {keyCode: 250, key: 'Play'},
ZoomOut: {keyCode: 251, key: 'ZoomOut'},
')': {keyCode: 48, key: ')', code: 'Digit0'},
'!': {keyCode: 49, key: '!', code: 'Digit1'},
'@': {keyCode: 50, key: '@', code: 'Digit2'},
'#': {keyCode: 51, key: '#', code: 'Digit3'},
$: {keyCode: 52, key: '$', code: 'Digit4'},
'%': {keyCode: 53, key: '%', code: 'Digit5'},
'^': {keyCode: 54, key: '^', code: 'Digit6'},
'&': {keyCode: 55, key: '&', code: 'Digit7'},
'(': {keyCode: 57, key: '(', code: 'Digit9'},
A: {keyCode: 65, key: 'A', code: 'KeyA'},
B: {keyCode: 66, key: 'B', code: 'KeyB'},
C: {keyCode: 67, key: 'C', code: 'KeyC'},
D: {keyCode: 68, key: 'D', code: 'KeyD'},
E: {keyCode: 69, key: 'E', code: 'KeyE'},
F: {keyCode: 70, key: 'F', code: 'KeyF'},
G: {keyCode: 71, key: 'G', code: 'KeyG'},
H: {keyCode: 72, key: 'H', code: 'KeyH'},
I: {keyCode: 73, key: 'I', code: 'KeyI'},
J: {keyCode: 74, key: 'J', code: 'KeyJ'},
K: {keyCode: 75, key: 'K', code: 'KeyK'},
L: {keyCode: 76, key: 'L', code: 'KeyL'},
M: {keyCode: 77, key: 'M', code: 'KeyM'},
N: {keyCode: 78, key: 'N', code: 'KeyN'},
O: {keyCode: 79, key: 'O', code: 'KeyO'},
P: {keyCode: 80, key: 'P', code: 'KeyP'},
Q: {keyCode: 81, key: 'Q', code: 'KeyQ'},
R: {keyCode: 82, key: 'R', code: 'KeyR'},
S: {keyCode: 83, key: 'S', code: 'KeyS'},
T: {keyCode: 84, key: 'T', code: 'KeyT'},
U: {keyCode: 85, key: 'U', code: 'KeyU'},
V: {keyCode: 86, key: 'V', code: 'KeyV'},
W: {keyCode: 87, key: 'W', code: 'KeyW'},
X: {keyCode: 88, key: 'X', code: 'KeyX'},
Y: {keyCode: 89, key: 'Y', code: 'KeyY'},
Z: {keyCode: 90, key: 'Z', code: 'KeyZ'},
':': {keyCode: 186, key: ':', code: 'Semicolon'},
'<': {keyCode: 188, key: '<', code: 'Comma'},
_: {keyCode: 189, key: '_', code: 'Minus'},
'>': {keyCode: 190, key: '>', code: 'Period'},
'?': {keyCode: 191, key: '?', code: 'Slash'},
'~': {keyCode: 192, key: '~', code: 'Backquote'},
'{': {keyCode: 219, key: '{', code: 'BracketLeft'},
'|': {keyCode: 220, key: '|', code: 'Backslash'},
'}': {keyCode: 221, key: '}', code: 'BracketRight'},
'"': {keyCode: 222, key: '"', code: 'Quote'},
SoftLeft: {key: 'SoftLeft', code: 'SoftLeft', location: 4},
SoftRight: {key: 'SoftRight', code: 'SoftRight', location: 4},
Camera: {keyCode: 44, key: 'Camera', code: 'Camera', location: 4},
Call: {key: 'Call', code: 'Call', location: 4},
EndCall: {keyCode: 95, key: 'EndCall', code: 'EndCall', location: 4},
VolumeDown: {
keyCode: 182,
key: 'VolumeDown',
code: 'VolumeDown',
location: 4,
},
VolumeUp: { keyCode: 183, key: 'VolumeUp', code: 'VolumeUp', location: 4 },
VolumeUp: {keyCode: 183, key: 'VolumeUp', code: 'VolumeUp', location: 4},
};

View File

@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import { CDPSession } from './Connection.js';
import { ConsoleMessageType } from './ConsoleMessage.js';
import { EvaluateHandleFn, SerializableOrJSHandle } from './EvalTypes.js';
import { EventEmitter } from './EventEmitter.js';
import { ExecutionContext } from './ExecutionContext.js';
import { debugError } from './util.js';
import { JSHandle } from './JSHandle.js';
import {Protocol} from 'devtools-protocol';
import {CDPSession} from './Connection.js';
import {ConsoleMessageType} from './ConsoleMessage.js';
import {EvaluateHandleFn, SerializableOrJSHandle} from './EvalTypes.js';
import {EventEmitter} from './EventEmitter.js';
import {ExecutionContext} from './ExecutionContext.js';
import {debugError} from './util.js';
import {JSHandle} from './JSHandle.js';
/**
* @internal
@ -79,14 +79,14 @@ export class WebWorker extends EventEmitter {
super();
this.#client = client;
this.#url = url;
this.#executionContextPromise = new Promise<ExecutionContext>((x) => {
this.#executionContextPromise = new Promise<ExecutionContext>(x => {
return (this.#executionContextCallback = x);
});
let jsHandleFactory: JSHandleFactory;
this.#client.once('Runtime.executionContextCreated', async (event) => {
this.#client.once('Runtime.executionContextCreated', async event => {
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
jsHandleFactory = (remoteObject) => {
jsHandleFactory = remoteObject => {
return new JSHandle(executionContext, client, remoteObject);
};
const executionContext = new ExecutionContext(client, event.context);
@ -95,14 +95,14 @@ export class WebWorker extends EventEmitter {
// This might fail if the target is closed before we receive all execution contexts.
this.#client.send('Runtime.enable').catch(debugError);
this.#client.on('Runtime.consoleAPICalled', (event) => {
this.#client.on('Runtime.consoleAPICalled', event => {
return consoleAPICalled(
event.type,
event.args.map(jsHandleFactory),
event.stackTrace
);
});
this.#client.on('Runtime.exceptionThrown', (exception) => {
this.#client.on('Runtime.exceptionThrown', exception => {
return exceptionThrown(exception.exceptionDetails);
});
}

View File

@ -14,14 +14,14 @@
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import type { Readable } from 'stream';
import { isNode } from '../environment.js';
import { assert } from './assert.js';
import { CDPSession } from './Connection.js';
import { debug } from './Debug.js';
import { TimeoutError } from './Errors.js';
import { CommonEventEmitter } from './EventEmitter.js';
import {Protocol} from 'devtools-protocol';
import type {Readable} from 'stream';
import {isNode} from '../environment.js';
import {assert} from './assert.js';
import {CDPSession} from './Connection.js';
import {debug} from './Debug.js';
import {TimeoutError} from './Errors.js';
import {CommonEventEmitter} from './EventEmitter.js';
export const debugError = debug('puppeteer:error');
@ -84,8 +84,8 @@ export async function releaseObject(
return;
}
await client
.send('Runtime.releaseObject', { objectId: remoteObject.objectId })
.catch((error) => {
.send('Runtime.releaseObject', {objectId: remoteObject.objectId})
.catch(error => {
// Exceptions might happen in case of a page been navigated or closed.
// Swallow these since they are harmless and we don't leak anything in this case.
debugError(error);
@ -104,7 +104,7 @@ export function addEventListener(
handler: (...args: any[]) => void
): PuppeteerEventListener {
emitter.on(eventName, handler);
return { emitter, eventName, handler };
return {emitter, eventName, handler};
}
export function removeEventListeners(
@ -142,7 +142,7 @@ export async function waitForEvent<T>(
resolveCallback = resolve;
rejectCallback = reject;
});
const listener = addEventListener(emitter, eventName, async (event) => {
const listener = addEventListener(emitter, eventName, async event => {
if (!(await predicate(event))) {
return;
}
@ -160,11 +160,11 @@ export async function waitForEvent<T>(
clearTimeout(eventTimeout);
}
const result = await Promise.race([promise, abortPromise]).then(
(r) => {
r => {
cleanup();
return r;
},
(error) => {
error => {
cleanup();
throw error;
}
@ -213,9 +213,9 @@ export function pageBindingInitString(type: string, name: string): string {
const seq = (me.lastSeq || 0) + 1;
me.lastSeq = seq;
const promise = new Promise((resolve, reject) => {
return callbacks.set(seq, { resolve, reject });
return callbacks.set(seq, {resolve, reject});
});
binding(JSON.stringify({ type, name: bindingName, seq, args }));
binding(JSON.stringify({type, name: bindingName, seq, args}));
return promise;
};
}
@ -381,7 +381,7 @@ export async function getReadableFromProtocolStream(
throw new Error('Cannot create a stream outside of Node.js environment.');
}
const { Readable } = await import('stream');
const {Readable} = await import('stream');
let eof = false;
return new Readable({
@ -390,11 +390,11 @@ export async function getReadableFromProtocolStream(
return;
}
const response = await client.send('IO.read', { handle, size });
const response = await client.send('IO.read', {handle, size});
this.push(response.data, response.base64Encoded ? 'base64' : undefined);
if (response.eof) {
eof = true;
await client.send('IO.close', { handle });
await client.send('IO.close', {handle});
this.push(null);
}
},

2
src/compat.d.ts vendored
View File

@ -1,3 +1,3 @@
declare const puppeteerDirname: string;
export { puppeteerDirname };
export {puppeteerDirname};

View File

@ -1,4 +1,4 @@
import { dirname } from 'path';
import { puppeteerDirname } from './compat.js';
import {dirname} from 'path';
import {puppeteerDirname} from './compat.js';
export const rootDirname = dirname(dirname(dirname(puppeteerDirname)));

View File

@ -14,11 +14,11 @@
* limitations under the License.
*/
import { sync } from 'pkg-dir';
import { Product } from './common/Product.js';
import { rootDirname } from './constants.js';
import { PuppeteerNode } from './node/Puppeteer.js';
import { PUPPETEER_REVISIONS } from './revisions.js';
import {sync} from 'pkg-dir';
import {Product} from './common/Product.js';
import {rootDirname} from './constants.js';
import {PuppeteerNode} from './node/Puppeteer.js';
import {PUPPETEER_REVISIONS} from './revisions.js';
export const initializePuppeteer = (packageName: string): PuppeteerNode => {
const isPuppeteerCore = packageName === 'puppeteer-core';

View File

@ -22,23 +22,23 @@ import * as childProcess from 'child_process';
import * as https from 'https';
import * as http from 'http';
import { Product } from '../common/Product.js';
import {Product} from '../common/Product.js';
import extractZip from 'extract-zip';
import { debug } from '../common/Debug.js';
import { promisify } from 'util';
import {debug} from '../common/Debug.js';
import {promisify} from 'util';
import removeRecursive from 'rimraf';
import * as URL from 'url';
import createHttpsProxyAgent, {
HttpsProxyAgent,
HttpsProxyAgentOptions,
} from 'https-proxy-agent';
import { getProxyForUrl } from 'proxy-from-env';
import { assert } from '../common/assert.js';
import {getProxyForUrl} from 'proxy-from-env';
import {assert} from '../common/assert.js';
import tar from 'tar-fs';
import bzip from 'unbzip2-stream';
const { PUPPETEER_EXPERIMENTAL_CHROMIUM_MAC_ARM } = process.env;
const {PUPPETEER_EXPERIMENTAL_CHROMIUM_MAC_ARM} = process.env;
const debugFetcher = debug('puppeteer:fetcher');
@ -142,8 +142,8 @@ const unlinkAsync = promisify(fs.unlink.bind(fs));
const chmodAsync = promisify(fs.chmod.bind(fs));
function existsAsync(filePath: string): Promise<boolean> {
return new Promise((resolve) => {
fs.access(filePath, (err) => {
return new Promise(resolve => {
fs.access(filePath, err => {
return resolve(!err);
});
});
@ -288,16 +288,16 @@ export class BrowserFetcher {
this.#downloadHost,
revision
);
return new Promise((resolve) => {
return new Promise(resolve => {
const request = httpRequest(
url,
'HEAD',
(response) => {
response => {
resolve(response.statusCode === 200);
},
false
);
request.on('error', (error) => {
request.on('error', error => {
console.error(error);
resolve(false);
});
@ -367,17 +367,17 @@ export class BrowserFetcher {
}
const fileNames = await readdirAsync(this.#downloadsFolder);
return fileNames
.map((fileName) => {
.map(fileName => {
return parseFolderPath(this.#product, fileName);
})
.filter(
(
entry
): entry is { product: string; platform: string; revision: string } => {
): entry is {product: string; platform: string; revision: string} => {
return (entry && entry.platform === this.#platform) ?? false;
}
)
.map((entry) => {
.map(entry => {
return entry.revision;
});
}
@ -395,7 +395,7 @@ export class BrowserFetcher {
await existsAsync(folderPath),
`Failed to remove: revision ${revision} is not downloaded`
);
await new Promise((fulfill) => {
await new Promise(fulfill => {
return removeRecursive(folderPath, fulfill);
});
}
@ -484,7 +484,7 @@ export class BrowserFetcher {
function parseFolderPath(
product: Product,
folderPath: string
): { product: string; platform: string; revision: string } | undefined {
): {product: string; platform: string; revision: string} | undefined {
const name = path.basename(folderPath);
const splits = name.split('-');
if (splits.length !== 2) {
@ -494,7 +494,7 @@ function parseFolderPath(
if (!revision || !platform || !(platform in downloadURLs[product])) {
return;
}
return { product, platform, revision };
return {product, platform, revision};
}
/**
@ -516,7 +516,7 @@ function _downloadFile(
let downloadedBytes = 0;
let totalBytes = 0;
const request = httpRequest(url, 'GET', (response) => {
const request = httpRequest(url, 'GET', response => {
if (response.statusCode !== 200) {
const error = new Error(
`Download failed: server returned code ${response.statusCode}. URL: ${url}`
@ -530,7 +530,7 @@ function _downloadFile(
file.on('finish', () => {
return fulfill();
});
file.on('error', (error) => {
file.on('error', error => {
return reject(error);
});
response.pipe(file);
@ -539,7 +539,7 @@ function _downloadFile(
response.on('data', onData);
}
});
request.on('error', (error) => {
request.on('error', error => {
return reject(error);
});
return promise;
@ -553,7 +553,7 @@ function _downloadFile(
function install(archivePath: string, folderPath: string): Promise<unknown> {
debugFetcher(`Installing ${archivePath} to ${folderPath}`);
if (archivePath.endsWith('.zip')) {
return extractZip(archivePath, { dir: folderPath });
return extractZip(archivePath, {dir: folderPath});
} else if (archivePath.endsWith('.tar.bz2')) {
return _extractTar(archivePath, folderPath);
} else if (archivePath.endsWith('.dmg')) {
@ -596,8 +596,8 @@ function _installDMG(dmgPath: string, folderPath: string): Promise<void> {
}
mountPath = volumes[0]!;
readdirAsync(mountPath)
.then((fileNames) => {
const appName = fileNames.find((item) => {
.then(fileNames => {
const appName = fileNames.find(item => {
return typeof item === 'string' && item.endsWith('.app');
});
if (!appName) {
@ -605,7 +605,7 @@ function _installDMG(dmgPath: string, folderPath: string): Promise<void> {
}
const copyPath = path.join(mountPath!, appName);
debugFetcher(`Copying ${copyPath} to ${folderPath}`);
childProcess.exec(`cp -R "${copyPath}" "${folderPath}"`, (err) => {
childProcess.exec(`cp -R "${copyPath}" "${folderPath}"`, err => {
if (err) {
reject(err);
} else {
@ -616,7 +616,7 @@ function _installDMG(dmgPath: string, folderPath: string): Promise<void> {
.catch(reject);
});
})
.catch((error) => {
.catch(error => {
console.error(error);
})
.finally((): void => {
@ -625,7 +625,7 @@ function _installDMG(dmgPath: string, folderPath: string): Promise<void> {
}
const unmountCommand = `hdiutil detach "${mountPath}" -quiet`;
debugFetcher(`Unmounting ${mountPath}`);
childProcess.exec(unmountCommand, (err) => {
childProcess.exec(unmountCommand, err => {
if (err) {
console.error(`Error unmounting dmg: ${err}`);
}

View File

@ -19,11 +19,11 @@ import * as fs from 'fs';
import * as path from 'path';
import * as readline from 'readline';
import removeFolder from 'rimraf';
import { promisify } from 'util';
import { assert } from '../common/assert.js';
import { Connection } from '../common/Connection.js';
import { debug } from '../common/Debug.js';
import { TimeoutError } from '../common/Errors.js';
import {promisify} from 'util';
import {assert} from '../common/assert.js';
import {Connection} from '../common/Connection.js';
import {debug} from '../common/Debug.js';
import {TimeoutError} from '../common/Errors.js';
import {
debugError,
addEventListener,
@ -32,10 +32,10 @@ import {
PuppeteerEventListener,
removeEventListeners,
} from '../common/util.js';
import { Product } from '../common/Product.js';
import { NodeWebSocketTransport as WebSocketTransport } from '../node/NodeWebSocketTransport.js';
import { LaunchOptions } from './LaunchOptions.js';
import { PipeTransport } from './PipeTransport.js';
import {Product} from '../common/Product.js';
import {NodeWebSocketTransport as WebSocketTransport} from '../node/NodeWebSocketTransport.js';
import {LaunchOptions} from './LaunchOptions.js';
import {PipeTransport} from './PipeTransport.js';
const removeFolderAsync = promisify(removeFolder);
const renameAsync = promisify(fs.rename);
@ -76,7 +76,7 @@ export class BrowserRunner {
}
start(options: LaunchOptions): void {
const { handleSIGINT, handleSIGTERM, handleSIGHUP, dumpio, env, pipe } =
const {handleSIGINT, handleSIGTERM, handleSIGHUP, dumpio, env, pipe} =
options;
let stdio: Array<'ignore' | 'pipe'>;
if (pipe) {
@ -181,7 +181,7 @@ export class BrowserRunner {
this.kill();
} else if (this.connection) {
// Attempt to close the browser gracefully
this.connection.send('Browser.close').catch((error) => {
this.connection.send('Browser.close').catch(error => {
debugError(error);
this.kill();
});
@ -200,7 +200,7 @@ export class BrowserRunner {
const proc = this.proc;
try {
if (process.platform === 'win32') {
childProcess.exec(`taskkill /pid ${this.proc.pid} /T /F`, (error) => {
childProcess.exec(`taskkill /pid ${this.proc.pid} /T /F`, error => {
if (error) {
// taskkill can fail to kill the process e.g. due to missing permissions.
// Let's kill the process via Node API. This delays killing of all child
@ -251,7 +251,7 @@ export class BrowserRunner {
}): Promise<Connection> {
assert(this.proc, 'BrowserRunner not started.');
const { usePipe, timeout, slowMo, preferredRevision } = options;
const {usePipe, timeout, slowMo, preferredRevision} = options;
if (!usePipe) {
const browserWSEndpoint = await waitForWSEndpoint(
this.proc,
@ -263,7 +263,7 @@ export class BrowserRunner {
} else {
// stdio was assigned during start(), and the 'pipe' option there adds the
// 4th and 5th items to stdio array
const { 3: pipeWrite, 4: pipeRead } = this.proc.stdio;
const {3: pipeWrite, 4: pipeRead} = this.proc.stdio;
const transport = new PipeTransport(
pipeWrite as NodeJS.WritableStream,
pipeRead as NodeJS.ReadableStream
@ -292,7 +292,7 @@ function waitForWSEndpoint(
addEventListener(browserProcess, 'exit', () => {
return onClose();
}),
addEventListener(browserProcess, 'error', (error) => {
addEventListener(browserProcess, 'error', error => {
return onClose(error);
}),
];

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
import { BrowserConnectOptions } from '../common/BrowserConnector.js';
import { Product } from '../common/Product.js';
import {BrowserConnectOptions} from '../common/BrowserConnector.js';
import {Product} from '../common/Product.js';
/**
* Launcher options that only apply to Chrome.

View File

@ -17,11 +17,11 @@ import * as os from 'os';
import * as path from 'path';
import * as fs from 'fs';
import { assert } from '../common/assert.js';
import { BrowserFetcher } from './BrowserFetcher.js';
import { Browser } from '../common/Browser.js';
import { BrowserRunner } from './BrowserRunner.js';
import { promisify } from 'util';
import {assert} from '../common/assert.js';
import {BrowserFetcher} from './BrowserFetcher.js';
import {Browser} from '../common/Browser.js';
import {BrowserRunner} from './BrowserRunner.js';
import {promisify} from 'util';
const copyFileAsync = promisify(fs.copyFile);
const mkdtempAsync = promisify(fs.mkdtemp);
@ -33,7 +33,7 @@ import {
PuppeteerNodeLaunchOptions,
} from './LaunchOptions.js';
import { Product } from '../common/Product.js';
import {Product} from '../common/Product.js';
const tmpDir = () => {
return process.env['PUPPETEER_TMP_DIR'] || os.tmpdir();
@ -90,7 +90,7 @@ class ChromeLauncher implements ProductLauncher {
handleSIGTERM = true,
handleSIGHUP = true,
ignoreHTTPSErrors = false,
defaultViewport = { width: 800, height: 600 },
defaultViewport = {width: 800, height: 600},
slowMo = 0,
timeout = 30000,
waitForInitialPage = true,
@ -102,7 +102,7 @@ class ChromeLauncher implements ProductLauncher {
chromeArguments.push(...this.defaultArgs(options));
} else if (Array.isArray(ignoreDefaultArgs)) {
chromeArguments.push(
...this.defaultArgs(options).filter((arg) => {
...this.defaultArgs(options).filter(arg => {
return !ignoreDefaultArgs.includes(arg);
})
);
@ -111,7 +111,7 @@ class ChromeLauncher implements ProductLauncher {
}
if (
!chromeArguments.some((argument) => {
!chromeArguments.some(argument => {
return argument.startsWith('--remote-debugging-');
})
) {
@ -130,7 +130,7 @@ class ChromeLauncher implements ProductLauncher {
// Check for the user data dir argument, which will always be set even
// with a custom directory specified via the userDataDir option.
let userDataDirIndex = chromeArguments.findIndex((arg) => {
let userDataDirIndex = chromeArguments.findIndex(arg => {
return arg.startsWith('--user-data-dir');
});
if (userDataDirIndex < 0) {
@ -157,7 +157,7 @@ class ChromeLauncher implements ProductLauncher {
chromeExecutable = executablePathForChannel(channel);
} else if (!chromeExecutable) {
const { missingText, executablePath } = resolveExecutablePath(this);
const {missingText, executablePath} = resolveExecutablePath(this);
if (missingText) {
throw new Error(missingText);
}
@ -205,10 +205,10 @@ class ChromeLauncher implements ProductLauncher {
if (waitForInitialPage) {
try {
await browser.waitForTarget(
(t) => {
t => {
return t.type() === 'page';
},
{ timeout }
{timeout}
);
} catch (error) {
await browser.close();
@ -272,7 +272,7 @@ class ChromeLauncher implements ProductLauncher {
);
}
if (
args.every((arg) => {
args.every(arg => {
return arg.startsWith('-');
})
) {
@ -335,7 +335,7 @@ class FirefoxLauncher implements ProductLauncher {
handleSIGTERM = true,
handleSIGHUP = true,
ignoreHTTPSErrors = false,
defaultViewport = { width: 800, height: 600 },
defaultViewport = {width: 800, height: 600},
slowMo = 0,
timeout = 30000,
extraPrefsFirefox = {},
@ -348,7 +348,7 @@ class FirefoxLauncher implements ProductLauncher {
firefoxArguments.push(...this.defaultArgs(options));
} else if (Array.isArray(ignoreDefaultArgs)) {
firefoxArguments.push(
...this.defaultArgs(options).filter((arg) => {
...this.defaultArgs(options).filter(arg => {
return !ignoreDefaultArgs.includes(arg);
})
);
@ -357,7 +357,7 @@ class FirefoxLauncher implements ProductLauncher {
}
if (
!firefoxArguments.some((argument) => {
!firefoxArguments.some(argument => {
return argument.startsWith('--remote-debugging-');
})
) {
@ -375,7 +375,7 @@ class FirefoxLauncher implements ProductLauncher {
// Check for the profile argument, which will always be set even
// with a custom directory specified via the userDataDir option.
const profileArgIndex = firefoxArguments.findIndex((arg) => {
const profileArgIndex = firefoxArguments.findIndex(arg => {
return ['-profile', '--profile'].includes(arg);
});
@ -399,7 +399,7 @@ class FirefoxLauncher implements ProductLauncher {
await this._updateRevision();
let firefoxExecutable = executablePath;
if (!executablePath) {
const { missingText, executablePath } = resolveExecutablePath(this);
const {missingText, executablePath} = resolveExecutablePath(this);
if (missingText) {
throw new Error(missingText);
}
@ -450,10 +450,10 @@ class FirefoxLauncher implements ProductLauncher {
if (waitForInitialPage) {
try {
await browser.waitForTarget(
(t) => {
t => {
return t.type() === 'page';
},
{ timeout }
{timeout}
);
} catch (error) {
await browser.close();
@ -516,7 +516,7 @@ class FirefoxLauncher implements ProductLauncher {
firefoxArguments.push('--devtools');
}
if (
args.every((arg) => {
args.every(arg => {
return arg.startsWith('-');
})
) {
@ -526,7 +526,7 @@ class FirefoxLauncher implements ProductLauncher {
return firefoxArguments;
}
defaultPreferences(extraPrefs: { [x: string]: unknown }): {
defaultPreferences(extraPrefs: {[x: string]: unknown}): {
[x: string]: unknown;
} {
const server = 'dummy.test';
@ -747,7 +747,7 @@ class FirefoxLauncher implements ProductLauncher {
* @param profilePath - Firefox profile to write the preferences to.
*/
async writePreferences(
prefs: { [x: string]: unknown },
prefs: {[x: string]: unknown},
profilePath: string
): Promise<void> {
const lines = Object.entries(prefs).map(([key, value]) => {
@ -764,7 +764,7 @@ class FirefoxLauncher implements ProductLauncher {
}
}
async _createProfile(extraPrefs: { [x: string]: unknown }): Promise<string> {
async _createProfile(extraPrefs: {[x: string]: unknown}): Promise<string> {
const temporaryProfilePath = await mkdtempAsync(
path.join(tmpDir(), 'puppeteer_dev_firefox_profile-')
);
@ -854,7 +854,7 @@ function resolveExecutablePath(launcher: ChromeLauncher | FirefoxLauncher): {
executablePath: string;
missingText?: string;
} {
const { product, _isPuppeteerCore, _projectRoot, _preferredRevision } =
const {product, _isPuppeteerCore, _projectRoot, _preferredRevision} =
launcher;
let downloadPath: string | undefined;
// puppeteer-core doesn't take into account PUPPETEER_* env variables.
@ -868,7 +868,7 @@ function resolveExecutablePath(launcher: ChromeLauncher | FirefoxLauncher): {
? 'Tried to use PUPPETEER_EXECUTABLE_PATH env variable to launch browser but did not find any executable at: ' +
executablePath
: undefined;
return { executablePath, missingText };
return {executablePath, missingText};
}
const ubuntuChromiumPath = '/usr/bin/chromium-browser';
if (
@ -877,7 +877,7 @@ function resolveExecutablePath(launcher: ChromeLauncher | FirefoxLauncher): {
os.arch() === 'arm64' &&
fs.existsSync(ubuntuChromiumPath)
) {
return { executablePath: ubuntuChromiumPath, missingText: undefined };
return {executablePath: ubuntuChromiumPath, missingText: undefined};
}
downloadPath =
process.env['PUPPETEER_DOWNLOAD_PATH'] ||
@ -902,7 +902,7 @@ function resolveExecutablePath(launcher: ChromeLauncher | FirefoxLauncher): {
? 'Tried to use PUPPETEER_CHROMIUM_REVISION env variable to launch browser but did not find executable at: ' +
revisionInfo.executablePath
: undefined;
return { executablePath: revisionInfo.executablePath, missingText };
return {executablePath: revisionInfo.executablePath, missingText};
}
}
const revisionInfo = browserFetcher.revisionInfo(_preferredRevision);
@ -914,7 +914,7 @@ function resolveExecutablePath(launcher: ChromeLauncher | FirefoxLauncher): {
product === 'chrome' ? chromeHelp : firefoxHelp
}`
: undefined;
return { executablePath: revisionInfo.executablePath, missingText };
return {executablePath: revisionInfo.executablePath, missingText};
}
/**

View File

@ -14,9 +14,9 @@
* limitations under the License.
*/
import NodeWebSocket from 'ws';
import { ConnectionTransport } from '../common/ConnectionTransport.js';
import { packageVersion } from '../generated/version.js';
import { promises as dns } from 'dns';
import {ConnectionTransport} from '../common/ConnectionTransport.js';
import {packageVersion} from '../generated/version.js';
import {promises as dns} from 'dns';
export class NodeWebSocketTransport implements ConnectionTransport {
static async create(urlString: string): Promise<NodeWebSocketTransport> {
@ -29,7 +29,7 @@ export class NodeWebSocketTransport implements ConnectionTransport {
// because of https://bugzilla.mozilla.org/show_bug.cgi?id=1769994.
const url = new URL(urlString);
if (url.hostname === 'localhost') {
const { address } = await dns.lookup(url.hostname, { verbatim: false });
const {address} = await dns.lookup(url.hostname, {verbatim: false});
url.hostname = address;
}
@ -56,7 +56,7 @@ export class NodeWebSocketTransport implements ConnectionTransport {
constructor(ws: NodeWebSocket) {
this.#ws = ws;
this.#ws.addEventListener('message', (event) => {
this.#ws.addEventListener('message', event => {
if (this.onmessage) {
this.onmessage.call(null, event.data);
}

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { assert } from '../common/assert.js';
import { ConnectionTransport } from '../common/ConnectionTransport.js';
import {assert} from '../common/assert.js';
import {ConnectionTransport} from '../common/ConnectionTransport.js';
import {
addEventListener,
debugError,
@ -38,7 +38,7 @@ export class PipeTransport implements ConnectionTransport {
) {
this.#pipeWrite = pipeWrite;
this.#eventListeners = [
addEventListener(pipeRead, 'data', (buffer) => {
addEventListener(pipeRead, 'data', buffer => {
return this.#dispatch(buffer);
}),
addEventListener(pipeRead, 'close', () => {

View File

@ -19,16 +19,13 @@ import {
CommonPuppeteerSettings,
ConnectOptions,
} from '../common/Puppeteer.js';
import { BrowserFetcher, BrowserFetcherOptions } from './BrowserFetcher.js';
import {
LaunchOptions,
BrowserLaunchArgumentOptions,
} from './LaunchOptions.js';
import { BrowserConnectOptions } from '../common/BrowserConnector.js';
import { Browser } from '../common/Browser.js';
import Launcher, { ProductLauncher } from './Launcher.js';
import { PUPPETEER_REVISIONS } from '../revisions.js';
import { Product } from '../common/Product.js';
import {BrowserFetcher, BrowserFetcherOptions} from './BrowserFetcher.js';
import {LaunchOptions, BrowserLaunchArgumentOptions} from './LaunchOptions.js';
import {BrowserConnectOptions} from '../common/BrowserConnector.js';
import {Browser} from '../common/Browser.js';
import Launcher, {ProductLauncher} from './Launcher.js';
import {PUPPETEER_REVISIONS} from '../revisions.js';
import {Product} from '../common/Product.js';
/**
* @public
@ -93,7 +90,7 @@ export class PuppeteerNode extends Puppeteer {
productName?: Product;
} & CommonPuppeteerSettings
) {
const { projectRoot, preferredRevision, productName, ...commonSettings } =
const {projectRoot, preferredRevision, productName, ...commonSettings} =
settings;
super(commonSettings);
this.#projectRoot = projectRoot;

View File

@ -14,16 +14,14 @@
* limitations under the License.
*/
import https, { RequestOptions } from 'https';
import https, {RequestOptions} from 'https';
import ProgressBar from 'progress';
import URL from 'url';
import puppeteer from '../puppeteer.js';
import { PUPPETEER_REVISIONS } from '../revisions.js';
import { PuppeteerNode } from './Puppeteer.js';
import createHttpsProxyAgent, {
HttpsProxyAgentOptions,
} from 'https-proxy-agent';
import { getProxyForUrl } from 'proxy-from-env';
import {PUPPETEER_REVISIONS} from '../revisions.js';
import {PuppeteerNode} from './Puppeteer.js';
import createHttpsProxyAgent, {HttpsProxyAgentOptions} from 'https-proxy-agent';
import {getProxyForUrl} from 'proxy-from-env';
const supportedProducts = {
chrome: 'Chromium',
@ -70,7 +68,7 @@ export async function downloadBrowser(): Promise<void> {
} else if (product === 'firefox') {
(puppeteer as PuppeteerNode)._preferredRevision =
PUPPETEER_REVISIONS.firefox;
return getFirefoxNightlyVersion().catch((error) => {
return getFirefoxNightlyVersion().catch(error => {
console.error(error);
process.exit(1);
});
@ -111,10 +109,10 @@ export async function downloadBrowser(): Promise<void> {
logPolitely(
`${supportedProducts[product]} (${revisionInfo.revision}) downloaded to ${revisionInfo.folderPath}`
);
localRevisions = localRevisions.filter((revision) => {
localRevisions = localRevisions.filter(revision => {
return revision !== revisionInfo.revision;
});
const cleanupOldVersions = localRevisions.map((revision) => {
const cleanupOldVersions = localRevisions.map(revision => {
return browserFetcher.remove(revision);
});
Promise.all([...cleanupOldVersions]);
@ -189,11 +187,11 @@ export async function downloadBrowser(): Promise<void> {
`Requesting latest Firefox Nightly version from ${firefoxVersionsUrl}`
);
https
.get(firefoxVersionsUrl, requestOptions, (r) => {
.get(firefoxVersionsUrl, requestOptions, r => {
if (r.statusCode && r.statusCode >= 400) {
return reject(new Error(`Got status code ${r.statusCode}`));
}
r.on('data', (chunk) => {
r.on('data', chunk => {
data += chunk;
});
r.on('end', () => {

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { initializePuppeteer } from './initializePuppeteer.js';
import {initializePuppeteer} from './initializePuppeteer.js';
const puppeteer = initializePuppeteer('puppeteer-core');

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { initializePuppeteer } from './initializePuppeteer.js';
import {initializePuppeteer} from './initializePuppeteer.js';
const puppeteer = initializePuppeteer('puppeteer');

View File

@ -6,7 +6,7 @@
"module": "CommonJS"
},
"references": [
{ "path": "../vendor/tsconfig.cjs.json" },
{ "path": "../compat/cjs/tsconfig.json" }
{"path": "../vendor/tsconfig.cjs.json"},
{"path": "../compat/cjs/tsconfig.json"}
]
}

View File

@ -6,7 +6,7 @@
"module": "esnext"
},
"references": [
{ "path": "../vendor/tsconfig.esm.json" },
{ "path": "../compat/esm/tsconfig.json" }
{"path": "../vendor/tsconfig.esm.json"},
{"path": "../compat/esm/tsconfig.json"}
]
}

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { waitEvent } from './utils.js';
import {waitEvent} from './utils.js';
import expect from 'expect';
import {
getTestState,
@ -22,20 +22,20 @@ import {
setupTestPageAndContextHooks,
describeChromeOnly,
} from './mocha-utils.js';
import { isErrorLike } from '../../lib/cjs/puppeteer/common/util.js';
import {isErrorLike} from '../../lib/cjs/puppeteer/common/util.js';
describeChromeOnly('Target.createCDPSession', function () {
setupTestBrowserHooks();
setupTestPageAndContextHooks();
it('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
const client = await page.target().createCDPSession();
await Promise.all([
client.send('Runtime.enable'),
client.send('Runtime.evaluate', { expression: 'window.foo = "bar"' }),
client.send('Runtime.evaluate', {expression: 'window.foo = "bar"'}),
]);
const foo = await page.evaluate(() => {
return (globalThis as any).foo;
@ -43,19 +43,19 @@ describeChromeOnly('Target.createCDPSession', function () {
expect(foo).toBe('bar');
});
it('should send events', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const client = await page.target().createCDPSession();
await client.send('Network.enable');
const events = [];
client.on('Network.requestWillBeSent', (event) => {
client.on('Network.requestWillBeSent', event => {
return events.push(event);
});
await page.goto(server.EMPTY_PAGE);
expect(events.length).toBe(1);
});
it('should enable and disable domains independently', async () => {
const { page } = getTestState();
const {page} = getTestState();
const client = await page.target().createCDPSession();
await client.send('Runtime.enable');
@ -72,7 +72,7 @@ describeChromeOnly('Target.createCDPSession', function () {
expect(event.url).toBe('foo.js');
});
it('should be able to detach session', async () => {
const { page } = getTestState();
const {page} = getTestState();
const client = await page.target().createCDPSession();
await client.send('Runtime.enable');
@ -96,10 +96,10 @@ describeChromeOnly('Target.createCDPSession', function () {
expect(error.message).toContain('Session closed.');
});
it('should throw nice errors', async () => {
const { page } = getTestState();
const {page} = getTestState();
const client = await page.target().createCDPSession();
const error = await theSourceOfTheProblems().catch((error) => {
const error = await theSourceOfTheProblems().catch(error => {
return error;
});
expect(error.stack).toContain('theSourceOfTheProblems');
@ -114,7 +114,7 @@ describeChromeOnly('Target.createCDPSession', function () {
});
it('should expose the underlying connection', async () => {
const { page } = getTestState();
const {page} = getTestState();
const client = await page.target().createCDPSession();
expect(client.connection()).toBeTruthy();

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { EventEmitter } from '../../lib/cjs/puppeteer/common/EventEmitter.js';
import {EventEmitter} from '../../lib/cjs/puppeteer/common/EventEmitter.js';
import sinon from 'sinon';
import expect from 'expect';

View File

@ -14,16 +14,16 @@
* limitations under the License.
*/
import { describeChromeOnly } from './mocha-utils.js';
import {describeChromeOnly} from './mocha-utils.js';
import expect from 'expect';
import {
NetworkManager,
NetworkManagerEmittedEvents,
} from '../../lib/cjs/puppeteer/common/NetworkManager.js';
import { HTTPRequest } from '../../lib/cjs/puppeteer/common/HTTPRequest.js';
import { EventEmitter } from '../../lib/cjs/puppeteer/common/EventEmitter.js';
import { Frame } from '../../lib/cjs/puppeteer/common/FrameManager.js';
import {HTTPRequest} from '../../lib/cjs/puppeteer/common/HTTPRequest.js';
import {EventEmitter} from '../../lib/cjs/puppeteer/common/EventEmitter.js';
import {Frame} from '../../lib/cjs/puppeteer/common/FrameManager.js';
class MockCDPSession extends EventEmitter {
async send(): Promise<any> {}
@ -56,7 +56,7 @@ describeChromeOnly('NetworkManager', () => {
},
timestamp: 2111.55635,
wallTime: 1637315638.473634,
initiator: { type: 'other' },
initiator: {type: 'other'},
redirectHasExtraInfo: false,
type: 'Document',
frameId: '099A5216AF03AAFEC988F214B024DF08',
@ -80,7 +80,7 @@ describeChromeOnly('NetworkManager', () => {
'Sec-Fetch-Dest': 'document',
'Accept-Encoding': 'gzip, deflate, br',
},
connectTiming: { requestTime: 2111.557593 },
connectTiming: {requestTime: 2111.557593},
});
mockCDPSession.emit('Network.responseReceivedExtraInfo', {
requestId: '7760711DEFCFA23132D98ABA6B4E175C',
@ -116,7 +116,7 @@ describeChromeOnly('NetworkManager', () => {
},
timestamp: 2111.559124,
wallTime: 1637315638.47642,
initiator: { type: 'other' },
initiator: {type: 'other'},
redirectHasExtraInfo: true,
redirectResponse: {
url: 'http://localhost:8907/redirect/1.html',
@ -183,7 +183,7 @@ describeChromeOnly('NetworkManager', () => {
'Sec-Fetch-Dest': 'document',
'Accept-Encoding': 'gzip, deflate, br',
},
connectTiming: { requestTime: 2111.559346 },
connectTiming: {requestTime: 2111.559346},
});
mockCDPSession.emit('Network.requestWillBeSent', {
requestId: '7760711DEFCFA23132D98ABA6B4E175C',
@ -204,7 +204,7 @@ describeChromeOnly('NetworkManager', () => {
},
timestamp: 2111.560249,
wallTime: 1637315638.477543,
initiator: { type: 'other' },
initiator: {type: 'other'},
redirectHasExtraInfo: true,
redirectResponse: {
url: 'http://localhost:8907/redirect/2.html',
@ -286,7 +286,7 @@ describeChromeOnly('NetworkManager', () => {
'Sec-Fetch-Dest': 'document',
'Accept-Encoding': 'gzip, deflate, br',
},
connectTiming: { requestTime: 2111.560482 },
connectTiming: {requestTime: 2111.560482},
});
mockCDPSession.emit('Network.requestWillBeSent', {
requestId: '7760711DEFCFA23132D98ABA6B4E175C',
@ -307,7 +307,7 @@ describeChromeOnly('NetworkManager', () => {
},
timestamp: 2111.561542,
wallTime: 1637315638.478837,
initiator: { type: 'other' },
initiator: {type: 'other'},
redirectHasExtraInfo: true,
redirectResponse: {
url: 'http://localhost:8907/redirect/3.html',
@ -389,7 +389,7 @@ describeChromeOnly('NetworkManager', () => {
'Sec-Fetch-Dest': 'document',
'Accept-Encoding': 'gzip, deflate, br',
},
connectTiming: { requestTime: 2111.561759 },
connectTiming: {requestTime: 2111.561759},
});
mockCDPSession.emit('Network.responseReceivedExtraInfo', {
requestId: '7760711DEFCFA23132D98ABA6B4E175C',
@ -508,7 +508,7 @@ describeChromeOnly('NetworkManager', () => {
},
timestamp: 224604.980827,
wallTime: 1637955746.786191,
initiator: { type: 'other' },
initiator: {type: 'other'},
redirectHasExtraInfo: false,
type: 'Document',
frameId: '84AC261A351B86932B775B76D1DD79F8',

View File

@ -16,7 +16,7 @@
import assert from 'assert';
import expect from 'expect';
import { SerializedAXNode } from '../../lib/cjs/puppeteer/common/Accessibility.js';
import {SerializedAXNode} from '../../lib/cjs/puppeteer/common/Accessibility.js';
import {
getTestState,
setupTestBrowserHooks,
@ -29,7 +29,7 @@ describeFailsFirefox('Accessibility', function () {
setupTestPageAndContextHooks();
it('should work', async () => {
const { page, isFirefox } = getTestState();
const {page, isFirefox} = getTestState();
await page.setContent(`
<head>
@ -58,14 +58,14 @@ describeFailsFirefox('Accessibility', function () {
role: 'document',
name: 'Accessibility Test',
children: [
{ role: 'text leaf', name: 'Hello World' },
{ role: 'heading', name: 'Inputs', level: 1 },
{ role: 'entry', name: 'Empty input', focused: true },
{ role: 'entry', name: 'readonly input', readonly: true },
{ role: 'entry', name: 'disabled input', disabled: true },
{ role: 'entry', name: 'Input with whitespace', value: ' ' },
{ role: 'entry', name: '', value: 'value only' },
{ role: 'entry', name: '', value: 'and a value' }, // firefox doesn't use aria-placeholder for the name
{role: 'text leaf', name: 'Hello World'},
{role: 'heading', name: 'Inputs', level: 1},
{role: 'entry', name: 'Empty input', focused: true},
{role: 'entry', name: 'readonly input', readonly: true},
{role: 'entry', name: 'disabled input', disabled: true},
{role: 'entry', name: 'Input with whitespace', value: ' '},
{role: 'entry', name: '', value: 'value only'},
{role: 'entry', name: '', value: 'and a value'}, // firefox doesn't use aria-placeholder for the name
{
role: 'entry',
name: '',
@ -83,7 +83,7 @@ describeFailsFirefox('Accessibility', function () {
name: 'First Option',
selected: true,
},
{ role: 'combobox option', name: 'Second Option' },
{role: 'combobox option', name: 'Second Option'},
],
},
],
@ -92,14 +92,14 @@ describeFailsFirefox('Accessibility', function () {
role: 'RootWebArea',
name: 'Accessibility Test',
children: [
{ role: 'StaticText', name: 'Hello World' },
{ role: 'heading', name: 'Inputs', level: 1 },
{ role: 'textbox', name: 'Empty input', focused: true },
{ role: 'textbox', name: 'readonly input', readonly: true },
{ role: 'textbox', name: 'disabled input', disabled: true },
{ role: 'textbox', name: 'Input with whitespace', value: ' ' },
{ role: 'textbox', name: '', value: 'value only' },
{ role: 'textbox', name: 'placeholder', value: 'and a value' },
{role: 'StaticText', name: 'Hello World'},
{role: 'heading', name: 'Inputs', level: 1},
{role: 'textbox', name: 'Empty input', focused: true},
{role: 'textbox', name: 'readonly input', readonly: true},
{role: 'textbox', name: 'disabled input', disabled: true},
{role: 'textbox', name: 'Input with whitespace', value: ' '},
{role: 'textbox', name: '', value: 'value only'},
{role: 'textbox', name: 'placeholder', value: 'and a value'},
{
role: 'textbox',
name: 'placeholder',
@ -112,8 +112,8 @@ describeFailsFirefox('Accessibility', function () {
value: 'First Option',
haspopup: 'menu',
children: [
{ role: 'menuitem', name: 'First Option', selected: true },
{ role: 'menuitem', name: 'Second Option' },
{role: 'menuitem', name: 'First Option', selected: true},
{role: 'menuitem', name: 'Second Option'},
],
},
],
@ -121,7 +121,7 @@ describeFailsFirefox('Accessibility', function () {
expect(await page.accessibility.snapshot()).toEqual(golden);
});
it('should report uninteresting nodes', async () => {
const { page, isFirefox } = getTestState();
const {page, isFirefox} = getTestState();
await page.setContent(`<textarea>hi</textarea>`);
await page.focus('textarea');
@ -160,12 +160,12 @@ describeFailsFirefox('Accessibility', function () {
};
expect(
findFocusedNode(
await page.accessibility.snapshot({ interestingOnly: false })
await page.accessibility.snapshot({interestingOnly: false})
)
).toEqual(golden);
});
it('roledescription', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
'<div tabIndex=-1 aria-roledescription="foo">Hi</div>'
@ -178,7 +178,7 @@ describeFailsFirefox('Accessibility', function () {
expect(snapshot.children[0]!.roledescription).toBeUndefined();
});
it('orientation', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
'<a href="" role="slider" aria-orientation="vertical">11</a>'
@ -190,7 +190,7 @@ describeFailsFirefox('Accessibility', function () {
expect(snapshot.children[0]!.orientation).toEqual('vertical');
});
it('autocomplete', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent('<input type="number" aria-autocomplete="list" />');
const snapshot = await page.accessibility.snapshot();
@ -200,7 +200,7 @@ describeFailsFirefox('Accessibility', function () {
expect(snapshot.children[0]!.autocomplete).toEqual('list');
});
it('multiselectable', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
'<div role="grid" tabIndex=-1 aria-multiselectable=true>hey</div>'
@ -212,7 +212,7 @@ describeFailsFirefox('Accessibility', function () {
expect(snapshot.children[0]!.multiselectable).toEqual(true);
});
it('keyshortcuts', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
'<div role="grid" tabIndex=-1 aria-keyshortcuts="foo">hey</div>'
@ -225,7 +225,7 @@ describeFailsFirefox('Accessibility', function () {
});
describe('filtering children of leaf nodes', function () {
it('should not report text nodes inside controls', async () => {
const { page, isFirefox } = getTestState();
const {page, isFirefox} = getTestState();
await page.setContent(`
<div role="tablist">
@ -266,7 +266,7 @@ describeFailsFirefox('Accessibility', function () {
expect(await page.accessibility.snapshot()).toEqual(golden);
});
it('rich text editable fields should have children', async () => {
const { page, isFirefox } = getTestState();
const {page, isFirefox} = getTestState();
await page.setContent(`
<div contenteditable="true">
@ -308,7 +308,7 @@ describeFailsFirefox('Accessibility', function () {
expect(snapshot.children[0]!).toEqual(golden);
});
it('rich text editable fields with role should have children', async () => {
const { page, isFirefox } = getTestState();
const {page, isFirefox} = getTestState();
await page.setContent(`
<div contenteditable="true" role='textbox'>
@ -351,7 +351,7 @@ describeFailsFirefox('Accessibility', function () {
// Firefox does not support contenteditable="plaintext-only".
describeFailsFirefox('plaintext contenteditable', function () {
it('plain text field with role should not have children', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`
<div contenteditable="plaintext-only" role='textbox'>Edit this image:<img src="fakeimage.png" alt="my fake image"></div>`);
@ -367,7 +367,7 @@ describeFailsFirefox('Accessibility', function () {
});
});
it('non editable textbox with role and tabIndex and label should not have children', async () => {
const { page, isFirefox } = getTestState();
const {page, isFirefox} = getTestState();
await page.setContent(`
<div role="textbox" tabIndex=0 aria-checked="true" aria-label="my favorite textbox">
@ -391,7 +391,7 @@ describeFailsFirefox('Accessibility', function () {
expect(snapshot.children[0]!).toEqual(golden);
});
it('checkbox with and tabIndex and label should not have children', async () => {
const { page, isFirefox } = getTestState();
const {page, isFirefox} = getTestState();
await page.setContent(`
<div role="checkbox" tabIndex=0 aria-checked="true" aria-label="my favorite checkbox">
@ -415,7 +415,7 @@ describeFailsFirefox('Accessibility', function () {
expect(snapshot.children[0]!).toEqual(golden);
});
it('checkbox without label should not have children', async () => {
const { page, isFirefox } = getTestState();
const {page, isFirefox} = getTestState();
await page.setContent(`
<div role="checkbox" aria-checked="true">
@ -441,30 +441,30 @@ describeFailsFirefox('Accessibility', function () {
describe('root option', function () {
it('should work a button', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<button>My Button</button>`);
const button = (await page.$('button'))!;
expect(await page.accessibility.snapshot({ root: button })).toEqual({
expect(await page.accessibility.snapshot({root: button})).toEqual({
role: 'button',
name: 'My Button',
});
});
it('should work an input', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input title="My Input" value="My Value">`);
const input = (await page.$('input'))!;
expect(await page.accessibility.snapshot({ root: input })).toEqual({
expect(await page.accessibility.snapshot({root: input})).toEqual({
role: 'textbox',
name: 'My Input',
value: 'My Value',
});
});
it('should work a menu', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`
<div role="menu" title="My Menu">
@ -475,35 +475,33 @@ describeFailsFirefox('Accessibility', function () {
`);
const menu = (await page.$('div[role="menu"]'))!;
expect(await page.accessibility.snapshot({ root: menu })).toEqual({
expect(await page.accessibility.snapshot({root: menu})).toEqual({
role: 'menu',
name: 'My Menu',
children: [
{ role: 'menuitem', name: 'First Item' },
{ role: 'menuitem', name: 'Second Item' },
{ role: 'menuitem', name: 'Third Item' },
{role: 'menuitem', name: 'First Item'},
{role: 'menuitem', name: 'Second Item'},
{role: 'menuitem', name: 'Third Item'},
],
orientation: 'vertical',
});
});
it('should return null when the element is no longer in DOM', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<button>My Button</button>`);
const button = (await page.$('button'))!;
await page.$eval('button', (button) => {
await page.$eval('button', button => {
return button.remove();
});
expect(await page.accessibility.snapshot({ root: button })).toEqual(
null
);
expect(await page.accessibility.snapshot({root: button})).toEqual(null);
});
it('should support the interestingOnly option', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<div><button>My Button</button></div>`);
const div = (await page.$('div'))!;
expect(await page.accessibility.snapshot({ root: div })).toEqual(null);
expect(await page.accessibility.snapshot({root: div})).toEqual(null);
expect(
await page.accessibility.snapshot({
root: div,
@ -516,7 +514,7 @@ describeFailsFirefox('Accessibility', function () {
{
role: 'button',
name: 'My Button',
children: [{ role: 'StaticText', name: 'My Button' }],
children: [{role: 'StaticText', name: 'My Button'}],
},
],
});

View File

@ -22,7 +22,7 @@ import {
describeChromeOnly,
} from './mocha-utils.js';
import { ElementHandle } from '../../lib/cjs/puppeteer/common/JSHandle.js';
import {ElementHandle} from '../../lib/cjs/puppeteer/common/JSHandle.js';
import utils from './utils.js';
import assert from 'assert';
@ -32,13 +32,13 @@ describeChromeOnly('AriaQueryHandler', () => {
describe('parseAriaSelector', () => {
beforeEach(async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
'<button id="btn" role="button"> Submit button and some spaces </button>'
);
});
it('should find button', async () => {
const { page } = getTestState();
const {page} = getTestState();
const expectFound = async (button: ElementHandle | null) => {
assert(button);
const id = await button.evaluate((button: Element) => {
@ -94,7 +94,7 @@ describeChromeOnly('AriaQueryHandler', () => {
describe('queryOne', () => {
it('should find button by role', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
'<div id="div"><button id="btn" role="button">Submit</button></div>'
);
@ -106,7 +106,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should find button by name and role', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
'<div id="div"><button id="btn" role="button">Submit</button></div>'
);
@ -118,7 +118,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should find first matching element', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
`
<div role="menu" id="mnu1" aria-label="menu div"></div>
@ -133,7 +133,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should find by name', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
`
<div role="menu" id="mnu1" aria-label="menu-label1">menu div</div>
@ -148,7 +148,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should find by name', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
`
<div role="menu" id="mnu1" aria-label="menu-label1">menu div</div>
@ -165,7 +165,7 @@ describeChromeOnly('AriaQueryHandler', () => {
describe('queryAll', () => {
it('should find menu by name', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
`
<div role="menu" id="mnu1" aria-label="menu div"></div>
@ -174,7 +174,7 @@ describeChromeOnly('AriaQueryHandler', () => {
);
const divs = await page.$$('aria/menu div');
const ids = await Promise.all(
divs.map((n) => {
divs.map(n => {
return n.evaluate((div: Element) => {
return div.id;
});
@ -185,7 +185,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
describe('queryAllArray', () => {
it('$$eval should handle many elements', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent('');
await page.evaluate(
`
@ -196,7 +196,7 @@ describeChromeOnly('AriaQueryHandler', () => {
}
`
);
const sum = await page.$$eval('aria/[role="button"]', (buttons) => {
const sum = await page.$$eval('aria/[role="button"]', buttons => {
return buttons.reduce((acc, button) => {
return acc + Number(button.textContent);
}, 0);
@ -211,14 +211,14 @@ describeChromeOnly('AriaQueryHandler', () => {
};
it('should immediately resolve promise if node exists', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.evaluate(addElement, 'button');
await page.waitForSelector('aria/[role="button"]');
});
it('should work for ElementHandler.waitForSelector', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => {
return (document.body.innerHTML = `<div><button>test</button></div>`);
@ -228,7 +228,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should persist query handler bindings across reloads', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.evaluate(addElement, 'button');
await page.waitForSelector('aria/[role="button"]');
@ -238,7 +238,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should persist query handler bindings across navigations', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
// Reset page but make sure that execution context ids start with 1.
await page.goto('data:text/html,');
@ -254,7 +254,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should work independently of `exposeFunction`', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.exposeFunction('ariaQuerySelector', (a: number, b: number) => {
return a + b;
@ -266,7 +266,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should work with removed MutationObserver', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.evaluate(() => {
// @ts-expect-error This is the point of the test.
@ -284,7 +284,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should resolve promise when node is added', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
const frame = page.mainFrame();
@ -299,7 +299,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should work when node is added through innerHTML', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
const watchdog = page.waitForSelector('aria/name');
@ -312,7 +312,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('Page.waitForSelector is shortcut for main frame', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
@ -325,7 +325,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should run in specified frame', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
await utils.attachFrame(page, 'frame2', server.EMPTY_PAGE);
@ -341,14 +341,14 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should throw when frame is detached', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
const frame = page.frames()[1];
let waitError!: Error;
const waitPromise = frame!
.waitForSelector('aria/does-not-exist')
.catch((error) => {
.catch(error => {
return (waitError = error);
});
await utils.detachFrame(page, 'frame1');
@ -360,7 +360,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should survive cross-process navigation', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
let imgFound = false;
const waitForSelector = page
@ -378,11 +378,11 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should wait for visible', async () => {
const { page } = getTestState();
const {page} = getTestState();
let divFound = false;
const waitForSelector = page
.waitForSelector('aria/name', { visible: true })
.waitForSelector('aria/name', {visible: true})
.then(() => {
return (divFound = true);
});
@ -404,11 +404,11 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should wait for visible recursively', async () => {
const { page } = getTestState();
const {page} = getTestState();
let divVisible = false;
const waitForSelector = page
.waitForSelector('aria/inner', { visible: true })
.waitForSelector('aria/inner', {visible: true})
.then(() => {
return (divVisible = true);
});
@ -430,14 +430,14 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('hidden should wait for visibility: hidden', async () => {
const { page } = getTestState();
const {page} = getTestState();
let divHidden = false;
await page.setContent(
`<div role='button' style='display: block;'></div>`
);
const waitForSelector = page
.waitForSelector('aria/[role="button"]', { hidden: true })
.waitForSelector('aria/[role="button"]', {hidden: true})
.then(() => {
return (divHidden = true);
});
@ -453,12 +453,12 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('hidden should wait for display: none', async () => {
const { page } = getTestState();
const {page} = getTestState();
let divHidden = false;
await page.setContent(`<div role='main' style='display: block;'></div>`);
const waitForSelector = page
.waitForSelector('aria/[role="main"]', { hidden: true })
.waitForSelector('aria/[role="main"]', {hidden: true})
.then(() => {
return (divHidden = true);
});
@ -474,12 +474,12 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('hidden should wait for removal', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<div role='main'></div>`);
let divRemoved = false;
const waitForSelector = page
.waitForSelector('aria/[role="main"]', { hidden: true })
.waitForSelector('aria/[role="main"]', {hidden: true})
.then(() => {
return (divRemoved = true);
});
@ -493,7 +493,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should return null if waiting to hide non-existing element', async () => {
const { page } = getTestState();
const {page} = getTestState();
const handle = await page.waitForSelector('aria/non-existing', {
hidden: true,
@ -502,12 +502,12 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should respect timeout', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
let error!: Error;
await page
.waitForSelector('aria/[role="button"]', { timeout: 10 })
.catch((error_) => {
.waitForSelector('aria/[role="button"]', {timeout: 10})
.catch(error_ => {
return (error = error_);
});
expect(error).toBeTruthy();
@ -518,13 +518,13 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should have an error message specifically for awaiting an element to be hidden', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<div role='main'></div>`);
let error!: Error;
await page
.waitForSelector('aria/[role="main"]', { hidden: true, timeout: 10 })
.catch((error_) => {
.waitForSelector('aria/[role="main"]', {hidden: true, timeout: 10})
.catch(error_ => {
return (error = error_);
});
expect(error).toBeTruthy();
@ -534,7 +534,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should respond to node attribute mutation', async () => {
const { page } = getTestState();
const {page} = getTestState();
let divFound = false;
const waitForSelector = page.waitForSelector('aria/zombo').then(() => {
@ -551,7 +551,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should return the element handle', async () => {
const { page } = getTestState();
const {page} = getTestState();
const waitForSelector = page.waitForSelector('aria/zombo');
await page.setContent(`<div aria-label='zombo'>anything</div>`);
@ -563,21 +563,19 @@ describeChromeOnly('AriaQueryHandler', () => {
});
it('should have correct stack trace for timeout', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error!: Error;
await page
.waitForSelector('aria/zombo', { timeout: 10 })
.catch((error_) => {
return (error = error_);
});
await page.waitForSelector('aria/zombo', {timeout: 10}).catch(error_ => {
return (error = error_);
});
expect(error!.stack).toContain('waiting for selector `zombo` failed');
});
});
describe('queryOne (Chromium web test)', async () => {
beforeEach(async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
`
<h2 id="shown">title</h2>
@ -626,7 +624,7 @@ describeChromeOnly('AriaQueryHandler', () => {
});
const getIds = async (elements: ElementHandle[]) => {
return Promise.all(
elements.map((element) => {
elements.map(element => {
return element.evaluate((element: Element) => {
return element.id;
});
@ -634,25 +632,25 @@ describeChromeOnly('AriaQueryHandler', () => {
);
};
it('should find by name "foo"', async () => {
const { page } = getTestState();
const {page} = getTestState();
const found = await page.$$('aria/foo');
const ids = await getIds(found);
expect(ids).toEqual(['node3', 'node5', 'node6']);
});
it('should find by name "bar"', async () => {
const { page } = getTestState();
const {page} = getTestState();
const found = await page.$$('aria/bar');
const ids = await getIds(found);
expect(ids).toEqual(['node1', 'node2', 'node8']);
});
it('should find treeitem by name', async () => {
const { page } = getTestState();
const {page} = getTestState();
const found = await page.$$('aria/item1 item2 item3');
const ids = await getIds(found);
expect(ids).toEqual(['node30']);
});
it('should find by role "button"', async () => {
const { page } = getTestState();
const {page} = getTestState();
const found = await page.$$<HTMLButtonElement>('aria/[role="button"]');
const ids = await getIds(found);
expect(ids).toEqual([
@ -665,13 +663,13 @@ describeChromeOnly('AriaQueryHandler', () => {
]);
});
it('should find by role "heading"', async () => {
const { page } = getTestState();
const {page} = getTestState();
const found = await page.$$('aria/[role="heading"]');
const ids = await getIds(found);
expect(ids).toEqual(['shown', 'hidden', 'node11', 'node13']);
});
it('should find both ignored and unignored', async () => {
const { page } = getTestState();
const {page} = getTestState();
const found = await page.$$('aria/title');
const ids = await getIds(found);
expect(ids).toEqual(['shown', 'hidden']);

View File

@ -15,14 +15,14 @@
*/
import expect from 'expect';
import { getTestState, setupTestBrowserHooks } from './mocha-utils.js';
import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
describe('Browser specs', function () {
setupTestBrowserHooks();
describe('Browser.version', function () {
it('should return whether we are in headless', async () => {
const { browser, isHeadless, headless } = getTestState();
const {browser, isHeadless, headless} = getTestState();
const version = await browser.version();
expect(version.length).toBeGreaterThan(0);
@ -34,7 +34,7 @@ describe('Browser specs', function () {
describe('Browser.userAgent', function () {
it('should include WebKit', async () => {
const { browser, isChrome } = getTestState();
const {browser, isChrome} = getTestState();
const userAgent = await browser.userAgent();
expect(userAgent.length).toBeGreaterThan(0);
@ -48,7 +48,7 @@ describe('Browser specs', function () {
describe('Browser.target', function () {
it('should return browser target', async () => {
const { browser } = getTestState();
const {browser} = getTestState();
const target = browser.target();
expect(target.type()).toBe('browser');
@ -57,16 +57,16 @@ describe('Browser specs', function () {
describe('Browser.process', function () {
it('should return child_process instance', async () => {
const { browser } = getTestState();
const {browser} = getTestState();
const process = await browser.process();
expect(process!.pid).toBeGreaterThan(0);
});
it('should not return child_process for remote browser', async () => {
const { browser, puppeteer } = getTestState();
const {browser, puppeteer} = getTestState();
const browserWSEndpoint = browser.wsEndpoint();
const remoteBrowser = await puppeteer.connect({ browserWSEndpoint });
const remoteBrowser = await puppeteer.connect({browserWSEndpoint});
expect(remoteBrowser.process()).toBe(null);
remoteBrowser.disconnect();
});
@ -74,10 +74,10 @@ describe('Browser specs', function () {
describe('Browser.isConnected', () => {
it('should set the browser connected state', async () => {
const { browser, puppeteer } = getTestState();
const {browser, puppeteer} = getTestState();
const browserWSEndpoint = browser.wsEndpoint();
const newBrowser = await puppeteer.connect({ browserWSEndpoint });
const newBrowser = await puppeteer.connect({browserWSEndpoint});
expect(newBrowser.isConnected()).toBe(true);
newBrowser.disconnect();
expect(newBrowser.isConnected()).toBe(false);

View File

@ -25,19 +25,19 @@ import utils from './utils.js';
describe('BrowserContext', function () {
setupTestBrowserHooks();
it('should have default context', async () => {
const { browser } = getTestState();
const {browser} = getTestState();
expect(browser.browserContexts().length).toEqual(1);
const defaultContext = browser.browserContexts()[0]!;
expect(defaultContext!.isIncognito()).toBe(false);
let error!: Error;
await defaultContext!.close().catch((error_) => {
await defaultContext!.close().catch(error_ => {
return (error = error_);
});
expect(browser.defaultBrowserContext()).toBe(defaultContext);
expect(error.message).toContain('cannot be closed');
});
it('should create new incognito context', async () => {
const { browser } = getTestState();
const {browser} = getTestState();
expect(browser.browserContexts().length).toBe(1);
const context = await browser.createIncognitoBrowserContext();
@ -48,7 +48,7 @@ describe('BrowserContext', function () {
expect(browser.browserContexts().length).toBe(1);
});
it('should close all belonging targets once closing context', async () => {
const { browser } = getTestState();
const {browser} = getTestState();
expect((await browser.pages()).length).toBe(1);
@ -61,14 +61,14 @@ describe('BrowserContext', function () {
expect((await browser.pages()).length).toBe(1);
});
itFailsFirefox('window.open should use parent tab context', async () => {
const { browser, server } = getTestState();
const {browser, server} = getTestState();
const context = await browser.createIncognitoBrowserContext();
const page = await context.newPage();
await page.goto(server.EMPTY_PAGE);
const [popupTarget] = await Promise.all([
utils.waitEvent(browser, 'targetcreated'),
page.evaluate<(url: string) => void>((url) => {
page.evaluate<(url: string) => void>(url => {
return window.open(url);
}, server.EMPTY_PAGE),
]);
@ -76,17 +76,17 @@ describe('BrowserContext', function () {
await context.close();
});
itFailsFirefox('should fire target events', async () => {
const { browser, server } = getTestState();
const {browser, server} = getTestState();
const context = await browser.createIncognitoBrowserContext();
const events: any[] = [];
context.on('targetcreated', (target) => {
context.on('targetcreated', target => {
return events.push('CREATED: ' + target.url());
});
context.on('targetchanged', (target) => {
context.on('targetchanged', target => {
return events.push('CHANGED: ' + target.url());
});
context.on('targetdestroyed', (target) => {
context.on('targetdestroyed', target => {
return events.push('DESTROYED: ' + target.url());
});
const page = await context.newPage();
@ -100,19 +100,19 @@ describe('BrowserContext', function () {
await context.close();
});
itFailsFirefox('should wait for a target', async () => {
const { browser, puppeteer, server } = getTestState();
const {browser, puppeteer, server} = getTestState();
const context = await browser.createIncognitoBrowserContext();
let resolved = false;
const targetPromise = context.waitForTarget((target) => {
const targetPromise = context.waitForTarget(target => {
return target.url() === server.EMPTY_PAGE;
});
targetPromise
.then(() => {
return (resolved = true);
})
.catch((error) => {
.catch(error => {
resolved = true;
if (error instanceof puppeteer.errors.TimeoutError) {
console.error(error);
@ -137,19 +137,19 @@ describe('BrowserContext', function () {
});
it('should timeout waiting for a non-existent target', async () => {
const { browser, puppeteer, server } = getTestState();
const {browser, puppeteer, server} = getTestState();
const context = await browser.createIncognitoBrowserContext();
const error = await context
.waitForTarget(
(target) => {
target => {
return target.url() === server.EMPTY_PAGE;
},
{
timeout: 1,
}
)
.catch((error_) => {
.catch(error_ => {
return error_;
});
expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);
@ -157,7 +157,7 @@ describe('BrowserContext', function () {
});
itFailsFirefox('should isolate localStorage and cookies', async () => {
const { browser, server } = getTestState();
const {browser, server} = getTestState();
// Create two incognito contexts.
const context1 = await browser.createIncognitoBrowserContext();
@ -217,7 +217,7 @@ describe('BrowserContext', function () {
});
itFailsFirefox('should work across sessions', async () => {
const { browser, puppeteer } = getTestState();
const {browser, puppeteer} = getTestState();
expect(browser.browserContexts().length).toBe(1);
const context = await browser.createIncognitoBrowserContext();

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import expect from 'expect';
import { IncomingMessage } from 'http';
import {IncomingMessage} from 'http';
import {
getTestState,
setupTestBrowserHooks,
@ -25,7 +25,7 @@ import {
describeChromeOnly('Chromium-Specific Launcher tests', function () {
describe('Puppeteer.launch |browserURL| option', function () {
it('should be able to connect using browserUrl, with and without trailing slash', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const originalBrowser = await puppeteer.launch(
Object.assign({}, defaultBrowserOptions, {
@ -34,7 +34,7 @@ describeChromeOnly('Chromium-Specific Launcher tests', function () {
);
const browserURL = 'http://127.0.0.1:21222';
const browser1 = await puppeteer.connect({ browserURL });
const browser1 = await puppeteer.connect({browserURL});
const page1 = await browser1.newPage();
expect(
await page1.evaluate(() => {
@ -56,7 +56,7 @@ describeChromeOnly('Chromium-Specific Launcher tests', function () {
originalBrowser.close();
});
it('should throw when using both browserWSEndpoint and browserURL', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const originalBrowser = await puppeteer.launch(
Object.assign({}, defaultBrowserOptions, {
@ -71,7 +71,7 @@ describeChromeOnly('Chromium-Specific Launcher tests', function () {
browserURL,
browserWSEndpoint: originalBrowser.wsEndpoint(),
})
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error.message).toContain(
@ -81,7 +81,7 @@ describeChromeOnly('Chromium-Specific Launcher tests', function () {
originalBrowser.close();
});
it('should throw when trying to connect to non-existing browser', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const originalBrowser = await puppeteer.launch(
Object.assign({}, defaultBrowserOptions, {
@ -91,7 +91,7 @@ describeChromeOnly('Chromium-Specific Launcher tests', function () {
const browserURL = 'http://127.0.0.1:32333';
let error!: Error;
await puppeteer.connect({ browserURL }).catch((error_) => {
await puppeteer.connect({browserURL}).catch(error_ => {
return (error = error_);
});
expect(error.message).toContain(
@ -103,8 +103,8 @@ describeChromeOnly('Chromium-Specific Launcher tests', function () {
describe('Puppeteer.launch |pipe| option', function () {
it('should support the pipe option', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const options = Object.assign({ pipe: true }, defaultBrowserOptions);
const {defaultBrowserOptions, puppeteer} = getTestState();
const options = Object.assign({pipe: true}, defaultBrowserOptions);
const browser = await puppeteer.launch(options);
expect((await browser.pages()).length).toBe(1);
expect(browser.wsEndpoint()).toBe('');
@ -114,7 +114,7 @@ describeChromeOnly('Chromium-Specific Launcher tests', function () {
await browser.close();
});
it('should support the pipe argument', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const options = Object.assign({}, defaultBrowserOptions);
options.args = ['--remote-debugging-pipe'].concat(options.args || []);
const browser = await puppeteer.launch(options);
@ -125,10 +125,10 @@ describeChromeOnly('Chromium-Specific Launcher tests', function () {
await browser.close();
});
it('should fire "disconnected" when closing with pipe', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const options = Object.assign({ pipe: true }, defaultBrowserOptions);
const {defaultBrowserOptions, puppeteer} = getTestState();
const options = Object.assign({pipe: true}, defaultBrowserOptions);
const browser = await puppeteer.launch(options);
const disconnectedEventPromise = new Promise((resolve) => {
const disconnectedEventPromise = new Promise(resolve => {
return browser.once('disconnected', resolve);
});
// Emulate user exiting browser.
@ -142,7 +142,7 @@ describeChromeOnly('Chromium-Specific Page Tests', function () {
setupTestBrowserHooks();
setupTestPageAndContextHooks();
it('Page.setRequestInterception should work with intervention headers', async () => {
const { server, page } = getTestState();
const {server, page} = getTestState();
server.setRoute('/intervention', (_req, res) => {
return res.end(`
@ -159,7 +159,7 @@ describeChromeOnly('Chromium-Specific Page Tests', function () {
});
await page.setRequestInterception(true);
page.on('request', (request) => {
page.on('request', request => {
return request.continue();
});
await page.goto(server.PREFIX + '/intervention');

View File

@ -27,7 +27,7 @@ describe('Page.click', function () {
setupTestBrowserHooks();
setupTestPageAndContextHooks();
it('should click the button', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/button.html');
await page.click('button');
@ -38,7 +38,7 @@ describe('Page.click', function () {
).toBe('Clicked');
});
it('should click svg', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`
<svg height="100" width="100">
@ -55,7 +55,7 @@ describe('Page.click', function () {
itFailsFirefox(
'should click the button if window.Node is removed',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/button.html');
await page.evaluate(() => {
@ -72,7 +72,7 @@ describe('Page.click', function () {
);
// @see https://github.com/puppeteer/puppeteer/issues/4281
it('should click on a span with an inline element inside', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`
<style>
@ -90,7 +90,7 @@ describe('Page.click', function () {
).toBe(42);
});
it('should not throw UnhandledPromiseRejection when page closes', async () => {
const { page } = getTestState();
const {page} = getTestState();
const newPage = await page.browser().newPage();
await Promise.all([newPage.close(), newPage.mouse.click(1, 2)]).catch(
@ -98,7 +98,7 @@ describe('Page.click', function () {
);
});
it('should click the button after navigation ', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/button.html');
await page.click('button');
@ -111,7 +111,7 @@ describe('Page.click', function () {
).toBe('Clicked');
});
itFailsFirefox('should click with disabled javascript', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.setJavaScriptEnabled(false);
await page.goto(server.PREFIX + '/wrappedlink.html');
@ -119,7 +119,7 @@ describe('Page.click', function () {
expect(page.url()).toBe(server.PREFIX + '/wrappedlink.html#clicked');
});
it('should click when one of inline box children is outside of viewport', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`
<style>
@ -138,7 +138,7 @@ describe('Page.click', function () {
).toBe(42);
});
it('should select the text by triple clicking', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
await page.focus('textarea');
@ -146,8 +146,8 @@ describe('Page.click', function () {
"This is the text that we are going to try to select. Let's see how it goes.";
await page.keyboard.type(text);
await page.click('textarea');
await page.click('textarea', { clickCount: 2 });
await page.click('textarea', { clickCount: 3 });
await page.click('textarea', {clickCount: 2});
await page.click('textarea', {clickCount: 3});
expect(
await page.evaluate(() => {
const textarea = document.querySelector('textarea');
@ -159,11 +159,11 @@ describe('Page.click', function () {
).toBe(text);
});
it('should click offscreen buttons', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/offscreenbuttons.html');
const messages: any[] = [];
page.on('console', (msg) => {
page.on('console', msg => {
return messages.push(msg.text());
});
for (let i = 0; i < 11; ++i) {
@ -189,7 +189,7 @@ describe('Page.click', function () {
});
it('should click wrapped links', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/wrappedlink.html');
await page.click('a');
@ -201,7 +201,7 @@ describe('Page.click', function () {
});
it('should click on checkbox input and toggle', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/checkbox.html');
expect(
@ -238,7 +238,7 @@ describe('Page.click', function () {
});
itFailsFirefox('should click on checkbox label and toggle', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/checkbox.html');
expect(
@ -266,11 +266,11 @@ describe('Page.click', function () {
});
it('should fail to click a missing button', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/button.html');
let error!: Error;
await page.click('button.does-not-exist').catch((error_) => {
await page.click('button.does-not-exist').catch(error_ => {
return (error = error_);
});
expect(error.message).toBe(
@ -279,7 +279,7 @@ describe('Page.click', function () {
});
// @see https://github.com/puppeteer/puppeteer/issues/161
it('should not hang with touch-enabled viewports', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
await page.setViewport(puppeteer.devices['iPhone 6']!.viewport);
await page.mouse.down();
@ -287,7 +287,7 @@ describe('Page.click', function () {
await page.mouse.up();
});
it('should scroll and click the button', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/scrollable.html');
await page.click('#button-5');
@ -304,7 +304,7 @@ describe('Page.click', function () {
).toBe('clicked');
});
it('should double click the button', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/button.html');
await page.evaluate(() => {
@ -315,12 +315,12 @@ describe('Page.click', function () {
});
});
const button = (await page.$('button'))!;
await button!.click({ clickCount: 2 });
await button!.click({clickCount: 2});
expect(await page.evaluate('double')).toBe(true);
expect(await page.evaluate('result')).toBe('Clicked');
});
it('should click a partially obscured button', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/button.html');
await page.evaluate(() => {
@ -337,7 +337,7 @@ describe('Page.click', function () {
).toBe('Clicked');
});
it('should click a rotated button', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/rotatedButton.html');
await page.click('button');
@ -348,10 +348,10 @@ describe('Page.click', function () {
).toBe('Clicked');
});
it('should fire contextmenu event on right click', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/scrollable.html');
await page.click('#button-8', { button: 'right' });
await page.click('#button-8', {button: 'right'});
expect(
await page.evaluate(() => {
return document.querySelector('#button-8')!.textContent;
@ -359,10 +359,10 @@ describe('Page.click', function () {
).toBe('context menu');
});
it('should fire aux event on middle click', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/scrollable.html');
await page.click('#button-8', { button: 'middle' });
await page.click('#button-8', {button: 'middle'});
expect(
await page.evaluate(() => {
return document.querySelector('#button-8')!.textContent;
@ -370,10 +370,10 @@ describe('Page.click', function () {
).toBe('aux click');
});
it('should fire back click', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/scrollable.html');
await page.click('#button-8', { button: 'back' });
await page.click('#button-8', {button: 'back'});
expect(
await page.evaluate(() => {
return document.querySelector('#button-8')!.textContent;
@ -381,10 +381,10 @@ describe('Page.click', function () {
).toBe('back click');
});
it('should fire forward click', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/scrollable.html');
await page.click('#button-8', { button: 'forward' });
await page.click('#button-8', {button: 'forward'});
expect(
await page.evaluate(() => {
return document.querySelector('#button-8')!.textContent;
@ -393,14 +393,14 @@ describe('Page.click', function () {
});
// @see https://github.com/puppeteer/puppeteer/issues/206
it('should click links which cause navigation', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`);
// This await should not hang.
await page.click('a');
});
it('should click the button inside an iframe', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setContent('<div style="width:100px;height:100px">spacer</div>');
@ -420,10 +420,10 @@ describe('Page.click', function () {
});
// @see https://github.com/puppeteer/puppeteer/issues/4110
xit('should click the button with fixed position inside an iframe', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setViewport({ width: 500, height: 500 });
await page.setViewport({width: 500, height: 500});
await page.setContent(
'<div style="width:100px;height:2000px">spacer</div>'
);
@ -444,9 +444,9 @@ describe('Page.click', function () {
).toBe('Clicked');
});
it('should click the button with deviceScaleFactor set', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.setViewport({ width: 400, height: 400, deviceScaleFactor: 5 });
await page.setViewport({width: 400, height: 400, deviceScaleFactor: 5});
expect(
await page.evaluate(() => {
return window.devicePixelRatio;

View File

@ -28,12 +28,12 @@ describe('Cookie specs', () => {
describe('Page.cookies', function () {
it('should return no cookies in pristine browser context', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
expectCookieEquals(await page.cookies(), []);
});
it('should get a cookie', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => {
document.cookie = 'username=John Doe';
@ -57,7 +57,7 @@ describe('Cookie specs', () => {
]);
});
it('should properly report httpOnly cookie', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
server.setRoute('/empty.html', (_req, res) => {
res.setHeader('Set-Cookie', 'a=b; HttpOnly; Path=/');
res.end();
@ -68,7 +68,7 @@ describe('Cookie specs', () => {
expect(cookies[0]!.httpOnly).toBe(true);
});
it('should properly report "Strict" sameSite cookie', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
server.setRoute('/empty.html', (_req, res) => {
res.setHeader('Set-Cookie', 'a=b; SameSite=Strict');
res.end();
@ -79,7 +79,7 @@ describe('Cookie specs', () => {
expect(cookies[0]!.sameSite).toBe('Strict');
});
it('should properly report "Lax" sameSite cookie', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
server.setRoute('/empty.html', (_req, res) => {
res.setHeader('Set-Cookie', 'a=b; SameSite=Lax');
res.end();
@ -90,7 +90,7 @@ describe('Cookie specs', () => {
expect(cookies[0]!.sameSite).toBe('Lax');
});
it('should get multiple cookies', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => {
document.cookie = 'username=John Doe';
@ -132,7 +132,7 @@ describe('Cookie specs', () => {
]);
});
itFailsFirefox('should get cookies from multiple urls', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setCookie(
{
url: 'https://foo.com',
@ -188,7 +188,7 @@ describe('Cookie specs', () => {
});
describe('Page.setCookie', function () {
itFailsFirefox('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setCookie({
@ -202,7 +202,7 @@ describe('Cookie specs', () => {
).toEqual('password=123456');
});
itFailsFirefox('should isolate cookies in browser contexts', async () => {
const { page, server, browser } = getTestState();
const {page, server, browser} = getTestState();
const anotherContext = await browser.createIncognitoBrowserContext();
const anotherPage = await anotherContext.newPage();
@ -210,8 +210,8 @@ describe('Cookie specs', () => {
await page.goto(server.EMPTY_PAGE);
await anotherPage.goto(server.EMPTY_PAGE);
await page.setCookie({ name: 'page1cookie', value: 'page1value' });
await anotherPage.setCookie({ name: 'page2cookie', value: 'page2value' });
await page.setCookie({name: 'page1cookie', value: 'page1value'});
await anotherPage.setCookie({name: 'page2cookie', value: 'page2value'});
const cookies1 = await page.cookies();
const cookies2 = await anotherPage.cookies();
@ -224,7 +224,7 @@ describe('Cookie specs', () => {
await anotherContext.close();
});
itFailsFirefox('should set multiple cookies', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setCookie(
@ -240,7 +240,7 @@ describe('Cookie specs', () => {
const cookieStrings = await page.evaluate(() => {
const cookies = document.cookie.split(';');
return cookies
.map((cookie) => {
.map(cookie => {
return cookie.trim();
})
.sort();
@ -249,7 +249,7 @@ describe('Cookie specs', () => {
expect(cookieStrings).toEqual(['foo=bar', 'password=123456']);
});
it('should have |expires| set to |-1| for session cookies', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setCookie({
@ -261,7 +261,7 @@ describe('Cookie specs', () => {
expect(cookies[0]!.expires).toBe(-1);
});
itFailsFirefox('should set cookie with reasonable defaults', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setCookie({
@ -292,7 +292,7 @@ describe('Cookie specs', () => {
);
});
itFailsFirefox('should set a cookie with a path', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/grid.html');
await page.setCookie({
@ -324,12 +324,12 @@ describe('Cookie specs', () => {
expect(await page.evaluate('document.cookie')).toBe('gridcookie=GRID');
});
it('should not set a cookie on a blank page', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.goto('about:blank');
let error!: Error;
try {
await page.setCookie({ name: 'example-cookie', value: 'best' });
await page.setCookie({name: 'example-cookie', value: 'best'});
} catch (error_) {
error = error_ as Error;
}
@ -338,14 +338,14 @@ describe('Cookie specs', () => {
);
});
it('should not set a cookie with blank page URL', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
let error!: Error;
await page.goto(server.EMPTY_PAGE);
try {
await page.setCookie(
{ name: 'example-cookie', value: 'best' },
{ url: 'about:blank', name: 'example-cookie-blank', value: 'best' }
{name: 'example-cookie', value: 'best'},
{url: 'about:blank', name: 'example-cookie-blank', value: 'best'}
);
} catch (error_) {
error = error_ as Error;
@ -355,12 +355,12 @@ describe('Cookie specs', () => {
);
});
it('should not set a cookie on a data URL page', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error!: Error;
await page.goto('data:,Hello%2C%20World!');
try {
await page.setCookie({ name: 'example-cookie', value: 'best' });
await page.setCookie({name: 'example-cookie', value: 'best'});
} catch (error_) {
error = error_ as Error;
}
@ -371,7 +371,7 @@ describe('Cookie specs', () => {
itFailsFirefox(
'should default to setting secure cookie for HTTPS websites',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
const SECURE_URL = 'https://example.com';
@ -385,7 +385,7 @@ describe('Cookie specs', () => {
}
);
it('should be able to set unsecure cookie for HTTP website', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
const HTTP_URL = 'http://example.com';
@ -398,7 +398,7 @@ describe('Cookie specs', () => {
expect(cookie!.secure).toBe(false);
});
itFailsFirefox('should set a cookie on a different domain', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setCookie({
@ -426,13 +426,13 @@ describe('Cookie specs', () => {
]);
});
itFailsFirefox('should set cookies from a frame', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/grid.html');
await page.setCookie({ name: 'localhost-cookie', value: 'best' });
await page.evaluate<(src: string) => Promise<void>>((src) => {
await page.setCookie({name: 'localhost-cookie', value: 'best'});
await page.evaluate<(src: string) => Promise<void>>(src => {
let fulfill!: () => void;
const promise = new Promise<void>((x) => {
const promise = new Promise<void>(x => {
return (fulfill = x);
});
const iframe = document.createElement('iframe') as HTMLIFrameElement;
@ -488,8 +488,7 @@ describe('Cookie specs', () => {
itFailsFirefox(
'should set secure same-site cookies from a frame',
async () => {
const { httpsServer, puppeteer, defaultBrowserOptions } =
getTestState();
const {httpsServer, puppeteer, defaultBrowserOptions} = getTestState();
const browser = await puppeteer.launch({
...defaultBrowserOptions,
@ -500,9 +499,9 @@ describe('Cookie specs', () => {
try {
await page.goto(httpsServer.PREFIX + '/grid.html');
await page.evaluate<(src: string) => Promise<void>>((src) => {
await page.evaluate<(src: string) => Promise<void>>(src => {
let fulfill!: () => void;
const promise = new Promise<void>((x) => {
const promise = new Promise<void>(x => {
return (fulfill = x);
});
const iframe = document.createElement('iframe');
@ -551,7 +550,7 @@ describe('Cookie specs', () => {
describe('Page.deleteCookie', function () {
itFailsFirefox('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setCookie(
@ -571,7 +570,7 @@ describe('Cookie specs', () => {
expect(await page.evaluate('document.cookie')).toBe(
'cookie1=1; cookie2=2; cookie3=3'
);
await page.deleteCookie({ name: 'cookie2' });
await page.deleteCookie({name: 'cookie2'});
expect(await page.evaluate('document.cookie')).toBe(
'cookie1=1; cookie3=3'
);

View File

@ -28,7 +28,7 @@ describe('Coverage specs', function () {
setupTestPageAndContextHooks();
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/simple.html', {
waitUntil: 'networkidle0',
@ -37,12 +37,12 @@ describe('Coverage specs', function () {
expect(coverage.length).toBe(1);
expect(coverage[0]!.url).toContain('/jscoverage/simple.html');
expect(coverage[0]!.ranges).toEqual([
{ start: 0, end: 17 },
{ start: 35, end: 61 },
{start: 0, end: 17},
{start: 35, end: 61},
]);
});
it('should report sourceURLs', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/sourceurl.html');
@ -51,7 +51,7 @@ describe('Coverage specs', function () {
expect(coverage[0]!.url).toBe('nicename.js');
});
it('should ignore eval() scripts by default', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/eval.html');
@ -59,22 +59,22 @@ describe('Coverage specs', function () {
expect(coverage.length).toBe(1);
});
it("shouldn't ignore eval() scripts if reportAnonymousScripts is true", async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage({ reportAnonymousScripts: true });
await page.coverage.startJSCoverage({reportAnonymousScripts: true});
await page.goto(server.PREFIX + '/jscoverage/eval.html');
const coverage = await page.coverage.stopJSCoverage();
expect(
coverage.find((entry) => {
coverage.find(entry => {
return entry.url.startsWith('debugger://');
})
).not.toBe(null);
expect(coverage.length).toBe(2);
});
it('should ignore pptr internal scripts if reportAnonymousScripts is true', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage({ reportAnonymousScripts: true });
await page.coverage.startJSCoverage({reportAnonymousScripts: true});
await page.goto(server.EMPTY_PAGE);
await page.evaluate('console.log("foo")');
await page.evaluate(() => {
@ -84,7 +84,7 @@ describe('Coverage specs', function () {
expect(coverage.length).toBe(0);
});
it('should report multiple scripts', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
@ -97,7 +97,7 @@ describe('Coverage specs', function () {
expect(coverage[1]!.url).toContain('/jscoverage/script2.js');
});
it('should report right ranges', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/ranges.html');
@ -111,7 +111,7 @@ describe('Coverage specs', function () {
);
});
it('should report scripts that have no coverage', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/unused.html');
@ -122,7 +122,7 @@ describe('Coverage specs', function () {
expect(entry.ranges.length).toBe(0);
});
it('should work with conditionals', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/involved.html');
@ -133,7 +133,7 @@ describe('Coverage specs', function () {
});
// @see https://crbug.com/990945
xit('should not hang when there is a debugger statement', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.EMPTY_PAGE);
@ -144,9 +144,9 @@ describe('Coverage specs', function () {
});
describe('resetOnNavigation', function () {
it('should report scripts across navigations when disabled', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage({ resetOnNavigation: false });
await page.coverage.startJSCoverage({resetOnNavigation: false});
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
await page.goto(server.EMPTY_PAGE);
const coverage = await page.coverage.stopJSCoverage();
@ -154,7 +154,7 @@ describe('Coverage specs', function () {
});
it('should NOT report scripts across navigations when enabled', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage(); // Enabled by default.
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
@ -165,7 +165,7 @@ describe('Coverage specs', function () {
});
describe('includeRawScriptCoverage', function () {
it('should not include rawScriptCoverage field when disabled', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.PREFIX + '/jscoverage/simple.html', {
waitUntil: 'networkidle0',
@ -175,7 +175,7 @@ describe('Coverage specs', function () {
expect(coverage[0]!.rawScriptCoverage).toBeUndefined();
});
it('should include rawScriptCoverage field when enabled', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage({
includeRawScriptCoverage: true,
});
@ -189,7 +189,7 @@ describe('Coverage specs', function () {
});
// @see https://crbug.com/990945
xit('should not hang when there is a debugger statement', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startJSCoverage();
await page.goto(server.EMPTY_PAGE);
@ -205,21 +205,21 @@ describe('Coverage specs', function () {
setupTestPageAndContextHooks();
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/simple.html');
const coverage = await page.coverage.stopCSSCoverage();
expect(coverage.length).toBe(1);
expect(coverage[0]!.url).toContain('/csscoverage/simple.html');
expect(coverage[0]!.ranges).toEqual([{ start: 1, end: 22 }]);
expect(coverage[0]!.ranges).toEqual([{start: 1, end: 22}]);
const range = coverage[0]!.ranges[0]!;
expect(coverage[0]!.text.substring(range.start, range.end)).toBe(
'div { color: green; }'
);
});
it('should report sourceURLs', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/sourceurl.html');
@ -228,7 +228,7 @@ describe('Coverage specs', function () {
expect(coverage[0]!.url).toBe('nicename.css');
});
it('should report multiple stylesheets', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/multiple.html');
@ -241,7 +241,7 @@ describe('Coverage specs', function () {
expect(coverage[1]!.url).toContain('/csscoverage/stylesheet2.css');
});
it('should report stylesheets that have no coverage', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/unused.html');
@ -251,17 +251,17 @@ describe('Coverage specs', function () {
expect(coverage[0]!.ranges.length).toBe(0);
});
it('should work with media queries', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/media.html');
const coverage = await page.coverage.stopCSSCoverage();
expect(coverage.length).toBe(1);
expect(coverage[0]!.url).toContain('/csscoverage/media.html');
expect(coverage[0]!.ranges).toEqual([{ start: 17, end: 38 }]);
expect(coverage[0]!.ranges).toEqual([{start: 17, end: 38}]);
});
it('should work with complicated usecases', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/involved.html');
@ -271,10 +271,10 @@ describe('Coverage specs', function () {
).toBeGolden('csscoverage-involved.txt');
});
it('should ignore injected stylesheets', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.coverage.startCSSCoverage();
await page.addStyleTag({ content: 'body { margin: 10px;}' });
await page.addStyleTag({content: 'body { margin: 10px;}'});
// trigger style recalc
const margin = await page.evaluate(() => {
return window.getComputedStyle(document.body).margin;
@ -284,17 +284,17 @@ describe('Coverage specs', function () {
expect(coverage.length).toBe(0);
});
it('should work with a recently loaded stylesheet', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startCSSCoverage();
await page.evaluate<(url: string) => Promise<void>>(async (url) => {
await page.evaluate<(url: string) => Promise<void>>(async url => {
document.body.textContent = 'hello, world';
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.head.appendChild(link);
await new Promise((x) => {
await new Promise(x => {
return (link.onload = x);
});
}, server.PREFIX + '/csscoverage/stylesheet1.css');
@ -303,16 +303,16 @@ describe('Coverage specs', function () {
});
describe('resetOnNavigation', function () {
it('should report stylesheets across navigations', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startCSSCoverage({ resetOnNavigation: false });
await page.coverage.startCSSCoverage({resetOnNavigation: false});
await page.goto(server.PREFIX + '/csscoverage/multiple.html');
await page.goto(server.EMPTY_PAGE);
const coverage = await page.coverage.stopCSSCoverage();
expect(coverage.length).toBe(2);
});
it('should NOT report scripts across navigations', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.coverage.startCSSCoverage(); // Enabled by default.
await page.goto(server.PREFIX + '/csscoverage/multiple.html');

View File

@ -26,7 +26,7 @@ describe('DefaultBrowserContext', function () {
setupTestBrowserHooks();
setupTestPageAndContextHooks();
it('page.cookies() should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => {
@ -50,7 +50,7 @@ describe('DefaultBrowserContext', function () {
]);
});
itFailsFirefox('page.setCookie() should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setCookie({
@ -80,7 +80,7 @@ describe('DefaultBrowserContext', function () {
]);
});
itFailsFirefox('page.deleteCookie() should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setCookie(
@ -94,7 +94,7 @@ describe('DefaultBrowserContext', function () {
}
);
expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie2=2');
await page.deleteCookie({ name: 'cookie2' });
await page.deleteCookie({name: 'cookie2'});
expect(await page.evaluate('document.cookie')).toBe('cookie1=1');
expectCookieEquals(await page.cookies(), [
{

View File

@ -28,9 +28,9 @@ describe('Page.Events.Dialog', function () {
setupTestPageAndContextHooks();
it('should fire', async () => {
const { page } = getTestState();
const {page} = getTestState();
const onDialog = sinon.stub().callsFake((dialog) => {
const onDialog = sinon.stub().callsFake(dialog => {
dialog.accept();
});
page.on('dialog', onDialog);
@ -47,9 +47,9 @@ describe('Page.Events.Dialog', function () {
});
itFailsFirefox('should allow accepting prompts', async () => {
const { page } = getTestState();
const {page} = getTestState();
const onDialog = sinon.stub().callsFake((dialog) => {
const onDialog = sinon.stub().callsFake(dialog => {
dialog.accept('answer!');
});
page.on('dialog', onDialog);
@ -67,9 +67,9 @@ describe('Page.Events.Dialog', function () {
expect(result).toBe('answer!');
});
it('should dismiss the prompt', async () => {
const { page } = getTestState();
const {page} = getTestState();
page.on('dialog', (dialog) => {
page.on('dialog', dialog => {
dialog.dismiss();
});
const result = await page.evaluate(() => {

View File

@ -26,13 +26,13 @@ describeChromeOnly('Input.drag', function () {
setupTestBrowserHooks();
setupTestPageAndContextHooks();
it('should throw an exception if not enabled before usage', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/drag-and-drop.html');
const draggable = (await page.$('#drag'))!;
try {
await draggable!.drag({ x: 1, y: 1 });
await draggable!.drag({x: 1, y: 1});
} catch (error) {
expect((error as Error).message).toContain(
'Drag Interception is not enabled!'
@ -40,14 +40,14 @@ describeChromeOnly('Input.drag', function () {
}
});
it('should emit a dragIntercepted event when dragged', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/drag-and-drop.html');
expect(page.isDragInterceptionEnabled()).toBe(false);
await page.setDragInterception(true);
expect(page.isDragInterceptionEnabled()).toBe(true);
const draggable = (await page.$('#drag'))!;
const data = await draggable.drag({ x: 1, y: 1 });
const data = await draggable.drag({x: 1, y: 1});
expect(data.items.length).toBe(1);
expect(
@ -57,14 +57,14 @@ describeChromeOnly('Input.drag', function () {
).toBe(true);
});
it('should emit a dragEnter', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/drag-and-drop.html');
expect(page.isDragInterceptionEnabled()).toBe(false);
await page.setDragInterception(true);
expect(page.isDragInterceptionEnabled()).toBe(true);
const draggable = (await page.$('#drag'))!;
const data = await draggable.drag({ x: 1, y: 1 });
const data = await draggable.drag({x: 1, y: 1});
const dropzone = (await page.$('#drop'))!;
await dropzone.dragEnter(data);
@ -80,14 +80,14 @@ describeChromeOnly('Input.drag', function () {
).toBe(true);
});
it('should emit a dragOver event', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/drag-and-drop.html');
expect(page.isDragInterceptionEnabled()).toBe(false);
await page.setDragInterception(true);
expect(page.isDragInterceptionEnabled()).toBe(true);
const draggable = (await page.$('#drag'))!;
const data = await draggable.drag({ x: 1, y: 1 });
const data = await draggable.drag({x: 1, y: 1});
const dropzone = (await page.$('#drop'))!;
await dropzone.dragEnter(data);
await dropzone.dragOver(data);
@ -109,7 +109,7 @@ describeChromeOnly('Input.drag', function () {
).toBe(true);
});
it('can be dropped', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/drag-and-drop.html');
expect(page.isDragInterceptionEnabled()).toBe(false);
@ -117,7 +117,7 @@ describeChromeOnly('Input.drag', function () {
expect(page.isDragInterceptionEnabled()).toBe(true);
const draggable = (await page.$('#drag'))!;
const dropzone = (await page.$('#drop'))!;
const data = await draggable.drag({ x: 1, y: 1 });
const data = await draggable.drag({x: 1, y: 1});
await dropzone.dragEnter(data);
await dropzone.dragOver(data);
await dropzone.drop(data);
@ -144,7 +144,7 @@ describeChromeOnly('Input.drag', function () {
).toBe(true);
});
it('can be dragged and dropped with a single function', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/drag-and-drop.html');
expect(page.isDragInterceptionEnabled()).toBe(false);
@ -176,18 +176,18 @@ describeChromeOnly('Input.drag', function () {
).toBe(true);
});
it('can be disabled', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/drag-and-drop.html');
expect(page.isDragInterceptionEnabled()).toBe(false);
await page.setDragInterception(true);
expect(page.isDragInterceptionEnabled()).toBe(true);
const draggable = (await page.$('#drag'))!;
await draggable.drag({ x: 1, y: 1 });
await draggable.drag({x: 1, y: 1});
await page.setDragInterception(false);
try {
await draggable.drag({ x: 1, y: 1 });
await draggable.drag({x: 1, y: 1});
} catch (error) {
expect((error as Error).message).toContain(
'Drag Interception is not enabled!'

View File

@ -25,7 +25,7 @@ import {
} from './mocha-utils.js';
import utils from './utils.js';
import { ElementHandle } from '../../lib/cjs/puppeteer/common/JSHandle.js';
import {ElementHandle} from '../../lib/cjs/puppeteer/common/JSHandle.js';
describe('ElementHandle specs', function () {
setupTestBrowserHooks();
@ -33,39 +33,39 @@ describe('ElementHandle specs', function () {
describeFailsFirefox('ElementHandle.boundingBox', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.setViewport({ width: 500, height: 500 });
await page.setViewport({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid.html');
const elementHandle = (await page.$('.box:nth-of-type(13)'))!;
const box = await elementHandle.boundingBox();
expect(box).toEqual({ x: 100, y: 50, width: 50, height: 50 });
expect(box).toEqual({x: 100, y: 50, width: 50, height: 50});
});
it('should handle nested frames', async () => {
const { page, server, isChrome } = getTestState();
const {page, server, isChrome} = getTestState();
await page.setViewport({ width: 500, height: 500 });
await page.setViewport({width: 500, height: 500});
await page.goto(server.PREFIX + '/frames/nested-frames.html');
const nestedFrame = page.frames()[1]!.childFrames()[1]!;
const elementHandle = (await nestedFrame.$('div'))!;
const box = await elementHandle.boundingBox();
if (isChrome) {
expect(box).toEqual({ x: 28, y: 182, width: 264, height: 18 });
expect(box).toEqual({x: 28, y: 182, width: 264, height: 18});
} else {
expect(box).toEqual({ x: 28, y: 182, width: 254, height: 18 });
expect(box).toEqual({x: 28, y: 182, width: 254, height: 18});
}
});
it('should return null for invisible elements', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent('<div style="display:none">hi</div>');
const element = (await page.$('div'))!;
expect(await element.boundingBox()).toBe(null);
});
it('should force a layout', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setViewport({ width: 500, height: 500 });
await page.setViewport({width: 500, height: 500});
await page.setContent(
'<div style="width: 100px; height: 100px">hello</div>'
);
@ -74,10 +74,10 @@ describe('ElementHandle specs', function () {
return (element.style.height = '200px');
}, elementHandle);
const box = await elementHandle.boundingBox();
expect(box).toEqual({ x: 8, y: 8, width: 100, height: 200 });
expect(box).toEqual({x: 8, y: 8, width: 100, height: 200});
});
it('should work with SVG nodes', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500">
@ -88,7 +88,7 @@ describe('ElementHandle specs', function () {
const pptrBoundingBox = await element.boundingBox();
const webBoundingBox = await page.evaluate((e: HTMLElement) => {
const rect = e.getBoundingClientRect();
return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
return {x: rect.x, y: rect.y, width: rect.width, height: rect.height};
}, element);
expect(pptrBoundingBox).toEqual(webBoundingBox);
});
@ -96,7 +96,7 @@ describe('ElementHandle specs', function () {
describeFailsFirefox('ElementHandle.boxModel', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/resetcss.html');
@ -151,7 +151,7 @@ describe('ElementHandle specs', function () {
});
it('should return null for invisible elements', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent('<div style="display:none">hi</div>');
const element = (await page.$('div'))!;
@ -161,7 +161,7 @@ describe('ElementHandle specs', function () {
describe('ElementHandle.contentFrame', function () {
itFailsFirefox('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
@ -174,7 +174,7 @@ describe('ElementHandle specs', function () {
describe('ElementHandle.click', function () {
// See https://github.com/puppeteer/puppeteer/issues/7175
itFailsFirefox('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/button.html');
const button = (await page.$('button'))!;
@ -186,7 +186,7 @@ describe('ElementHandle specs', function () {
).toBe('Clicked');
});
it('should work for Shadow DOM v1', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/shadow.html');
const buttonHandle = await page.evaluateHandle<ElementHandle>(() => {
@ -202,20 +202,20 @@ describe('ElementHandle specs', function () {
).toBe(true);
});
it('should work for TextNodes', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/button.html');
const buttonTextNode = await page.evaluateHandle<ElementHandle>(() => {
return document.querySelector('button')!.firstChild;
});
let error!: Error;
await buttonTextNode.click().catch((error_) => {
await buttonTextNode.click().catch(error_ => {
return (error = error_);
});
expect(error.message).toBe('Node is not of type HTMLElement');
});
it('should throw for detached nodes', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/button.html');
const button = (await page.$('button'))!;
@ -223,20 +223,20 @@ describe('ElementHandle specs', function () {
return button.remove();
}, button);
let error!: Error;
await button.click().catch((error_) => {
await button.click().catch(error_ => {
return (error = error_);
});
expect(error.message).toBe('Node is detached from document');
});
it('should throw for hidden nodes', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/button.html');
const button = (await page.$('button'))!;
await page.evaluate((button: HTMLElement) => {
return (button.style.display = 'none');
}, button);
const error = await button.click().catch((error_) => {
const error = await button.click().catch(error_ => {
return error_;
});
expect(error.message).toBe(
@ -244,14 +244,14 @@ describe('ElementHandle specs', function () {
);
});
it('should throw for recursively hidden nodes', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/button.html');
const button = (await page.$('button'))!;
await page.evaluate((button: HTMLElement) => {
return (button.parentElement!.style.display = 'none');
}, button);
const error = await button.click().catch((error_) => {
const error = await button.click().catch(error_ => {
return error_;
});
expect(error.message).toBe(
@ -259,11 +259,11 @@ describe('ElementHandle specs', function () {
);
});
it('should throw for <br> elements', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent('hello<br>goodbye');
const br = (await page.$('br'))!;
const error = await br.click().catch((error_) => {
const error = await br.click().catch(error_ => {
return error_;
});
expect(error.message).toBe(
@ -274,7 +274,7 @@ describe('ElementHandle specs', function () {
describe('Element.waitForSelector', () => {
it('should wait correctly with waitForSelector on an element', async () => {
const { page } = getTestState();
const {page} = getTestState();
const waitFor = page.waitForSelector('.foo');
// Set the page content after the waitFor has been started.
await page.setContent(
@ -284,13 +284,13 @@ describe('ElementHandle specs', function () {
expect(element).toBeDefined();
const innerWaitFor = element.waitForSelector('.bar');
await element.evaluate((el) => {
await element.evaluate(el => {
el.innerHTML = '<div class="bar">bar1</div>';
});
element = (await innerWaitFor)!;
expect(element).toBeDefined();
expect(
await element.evaluate((el) => {
await element.evaluate(el => {
return (el as HTMLElement).innerText;
})
).toStrictEqual('bar1');
@ -299,7 +299,7 @@ describe('ElementHandle specs', function () {
describe('Element.waitForXPath', () => {
it('should wait correctly with waitForXPath on an element', async () => {
const { page } = getTestState();
const {page} = getTestState();
// Set the page content after the waitFor has been started.
await page.setContent(
`<div id=el1>
@ -316,13 +316,13 @@ describe('ElementHandle specs', function () {
const el2 = (await page.waitForSelector('#el1'))!;
expect(
await (await el2.waitForXPath('//div'))!.evaluate((el) => {
await (await el2.waitForXPath('//div'))!.evaluate(el => {
return el.id;
})
).toStrictEqual('el2');
expect(
await (await el2.waitForXPath('.//div'))!.evaluate((el) => {
await (await el2.waitForXPath('.//div'))!.evaluate(el => {
return el.id;
})
).toStrictEqual('el2');
@ -331,7 +331,7 @@ describe('ElementHandle specs', function () {
describe('ElementHandle.hover', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/scrollable.html');
const button = (await page.$('#button-6'))!;
@ -346,7 +346,7 @@ describe('ElementHandle specs', function () {
describe('ElementHandle.isIntersectingViewport', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/offscreenbuttons.html');
for (let i = 0; i < 11; ++i) {
@ -357,7 +357,7 @@ describe('ElementHandle specs', function () {
}
});
it('should work with threshold', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/offscreenbuttons.html');
// a button almost cannot be seen
@ -370,7 +370,7 @@ describe('ElementHandle specs', function () {
).toBe(false);
});
it('should work with threshold of 1', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/offscreenbuttons.html');
// a button almost cannot be seen
@ -386,11 +386,11 @@ describe('ElementHandle specs', function () {
describe('Custom queries', function () {
this.afterEach(() => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
puppeteer.clearCustomQueryHandlers();
});
it('should register and unregister', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
await page.setContent('<div id="not-foo"></div><div id="foo"></div>');
// Register.
@ -401,7 +401,7 @@ describe('ElementHandle specs', function () {
});
const element = (await page.$('getById/foo'))!;
expect(
await page.evaluate<(element: HTMLElement) => string>((element) => {
await page.evaluate<(element: HTMLElement) => string>(element => {
return element.id;
}, element)
).toBe('foo');
@ -426,7 +426,7 @@ describe('ElementHandle specs', function () {
});
it('should throw with invalid query names', () => {
try {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
puppeteer.registerCustomQueryHandler('1/2/3', {
queryOne: () => {
return document.querySelector('foo');
@ -442,7 +442,7 @@ describe('ElementHandle specs', function () {
}
});
it('should work for multiple elements', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
await page.setContent(
'<div id="not-foo"></div><div class="foo">Foo1</div><div class="foo baz">Foo2</div>'
);
@ -453,9 +453,9 @@ describe('ElementHandle specs', function () {
});
const elements = await page.$$('getByClass/foo');
const classNames = await Promise.all(
elements.map(async (element) => {
elements.map(async element => {
return await page.evaluate<(element: HTMLElement) => string>(
(element) => {
element => {
return element.className;
},
element
@ -466,7 +466,7 @@ describe('ElementHandle specs', function () {
expect(classNames).toStrictEqual(['foo', 'foo baz']);
});
it('should eval correctly', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
await page.setContent(
'<div id="not-foo"></div><div class="foo">Foo1</div><div class="foo baz">Foo2</div>'
);
@ -475,14 +475,14 @@ describe('ElementHandle specs', function () {
return document.querySelectorAll(`.${selector}`);
},
});
const elements = await page.$$eval('getByClass/foo', (divs) => {
const elements = await page.$$eval('getByClass/foo', divs => {
return divs.length;
});
expect(elements).toBe(2);
});
it('should wait correctly with waitForSelector', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
puppeteer.registerCustomQueryHandler('getByClass', {
queryOne: (element, selector) => {
return element.querySelector(`.${selector}`);
@ -500,7 +500,7 @@ describe('ElementHandle specs', function () {
});
it('should wait correctly with waitForSelector on an element', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
puppeteer.registerCustomQueryHandler('getByClass', {
queryOne: (element, selector) => {
return element.querySelector(`.${selector}`);
@ -517,14 +517,14 @@ describe('ElementHandle specs', function () {
const innerWaitFor = element.waitForSelector('getByClass/bar');
await element.evaluate((el) => {
await element.evaluate(el => {
el.innerHTML = '<div class="bar">bar1</div>';
});
element = (await innerWaitFor)!;
expect(element).toBeDefined();
expect(
await element.evaluate((el) => {
await element.evaluate(el => {
return (el as HTMLElement).innerText;
})
).toStrictEqual('bar1');
@ -533,7 +533,7 @@ describe('ElementHandle specs', function () {
it('should wait correctly with waitFor', async () => {
/* page.waitFor is deprecated so we silence the warning to avoid test noise */
sinon.stub(console, 'warn').callsFake(() => {});
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
puppeteer.registerCustomQueryHandler('getByClass', {
queryOne: (element, selector) => {
return element.querySelector(`.${selector}`);
@ -550,7 +550,7 @@ describe('ElementHandle specs', function () {
expect(element).toBeDefined();
});
it('should work when both queryOne and queryAll are registered', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
await page.setContent(
'<div id="not-foo"></div><div class="foo"><div id="nested-foo" class="foo"/></div><div class="foo baz">Foo2</div>'
);
@ -570,7 +570,7 @@ describe('ElementHandle specs', function () {
expect(elements.length).toBe(3);
});
it('should eval when both queryOne and queryAll are registered', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
await page.setContent(
'<div id="not-foo"></div><div class="foo">text</div><div class="foo baz">content</div>'
);
@ -583,14 +583,14 @@ describe('ElementHandle specs', function () {
},
});
const txtContent = await page.$eval('getByClass/foo', (div) => {
const txtContent = await page.$eval('getByClass/foo', div => {
return div.textContent;
});
expect(txtContent).toBe('text');
const txtContents = await page.$$eval('getByClass/foo', (divs) => {
const txtContents = await page.$$eval('getByClass/foo', divs => {
return divs
.map((d) => {
.map(d => {
return d.textContent;
})
.join('');

View File

@ -15,7 +15,7 @@
*/
import expect from 'expect';
import { Device } from '../../lib/cjs/puppeteer/common/DeviceDescriptors.js';
import {Device} from '../../lib/cjs/puppeteer/common/DeviceDescriptors.js';
import {
getTestState,
setupTestBrowserHooks,
@ -31,21 +31,21 @@ describe('Emulation', () => {
let iPhoneLandscape!: Device;
before(() => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
iPhone = puppeteer.devices['iPhone 6']!;
iPhoneLandscape = puppeteer.devices['iPhone 6 landscape']!;
});
describe('Page.viewport', function () {
it('should get the proper viewport size', async () => {
const { page } = getTestState();
const {page} = getTestState();
expect(page.viewport()).toEqual({ width: 800, height: 600 });
await page.setViewport({ width: 123, height: 456 });
expect(page.viewport()).toEqual({ width: 123, height: 456 });
expect(page.viewport()).toEqual({width: 800, height: 600});
await page.setViewport({width: 123, height: 456});
expect(page.viewport()).toEqual({width: 123, height: 456});
});
it('should support mobile emulation', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/mobile.html');
expect(
@ -59,7 +59,7 @@ describe('Emulation', () => {
return window.innerWidth;
})
).toBe(375);
await page.setViewport({ width: 400, height: 300 });
await page.setViewport({width: 400, height: 300});
expect(
await page.evaluate(() => {
return window.innerWidth;
@ -67,7 +67,7 @@ describe('Emulation', () => {
).toBe(400);
});
it('should support touch emulation', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/mobile.html');
expect(
@ -82,7 +82,7 @@ describe('Emulation', () => {
})
).toBe(true);
expect(await page.evaluate(dispatchTouch)).toBe('Received touch');
await page.setViewport({ width: 100, height: 100 });
await page.setViewport({width: 100, height: 100});
expect(
await page.evaluate(() => {
return 'ontouchstart' in window;
@ -91,7 +91,7 @@ describe('Emulation', () => {
function dispatchTouch() {
let fulfill!: (value: string) => void;
const promise = new Promise((x) => {
const promise = new Promise(x => {
fulfill = x;
});
window.ontouchstart = () => {
@ -105,7 +105,7 @@ describe('Emulation', () => {
}
});
it('should be detectable by Modernizr', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/detect-touch.html');
expect(
@ -122,10 +122,10 @@ describe('Emulation', () => {
).toBe('YES');
});
it('should detect touch when applying viewport with touches', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.setViewport({ width: 800, height: 600, hasTouch: true });
await page.addScriptTag({ url: server.PREFIX + '/modernizr.js' });
await page.setViewport({width: 800, height: 600, hasTouch: true});
await page.addScriptTag({url: server.PREFIX + '/modernizr.js'});
expect(
await page.evaluate(() => {
return (globalThis as any).Modernizr.touchevents;
@ -133,7 +133,7 @@ describe('Emulation', () => {
).toBe(true);
});
itFailsFirefox('should support landscape emulation', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/mobile.html');
expect(
@ -147,7 +147,7 @@ describe('Emulation', () => {
return screen.orientation.type;
})
).toBe('landscape-primary');
await page.setViewport({ width: 100, height: 100 });
await page.setViewport({width: 100, height: 100});
expect(
await page.evaluate(() => {
return screen.orientation.type;
@ -158,7 +158,7 @@ describe('Emulation', () => {
describe('Page.emulate', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/mobile.html');
await page.emulate(iPhone);
@ -174,7 +174,7 @@ describe('Emulation', () => {
).toContain('iPhone');
});
itFailsFirefox('should support clicking', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.emulate(iPhone);
await page.goto(server.PREFIX + '/input/button.html');
@ -193,7 +193,7 @@ describe('Emulation', () => {
describe('Page.emulateMediaType', function () {
itFailsFirefox('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
expect(
await page.evaluate(() => {
@ -229,10 +229,10 @@ describe('Emulation', () => {
).toBe(false);
});
it('should throw in case of bad argument', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error!: Error;
await page.emulateMediaType('bad').catch((error_) => {
await page.emulateMediaType('bad').catch(error_ => {
return (error = error_);
});
expect(error.message).toBe('Unsupported media type: bad');
@ -241,10 +241,10 @@ describe('Emulation', () => {
describe('Page.emulateMediaFeatures', function () {
itFailsFirefox('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.emulateMediaFeatures([
{ name: 'prefers-reduced-motion', value: 'reduce' },
{name: 'prefers-reduced-motion', value: 'reduce'},
]);
expect(
await page.evaluate(() => {
@ -257,7 +257,7 @@ describe('Emulation', () => {
})
).toBe(false);
await page.emulateMediaFeatures([
{ name: 'prefers-color-scheme', value: 'light' },
{name: 'prefers-color-scheme', value: 'light'},
]);
expect(
await page.evaluate(() => {
@ -270,7 +270,7 @@ describe('Emulation', () => {
})
).toBe(false);
await page.emulateMediaFeatures([
{ name: 'prefers-color-scheme', value: 'dark' },
{name: 'prefers-color-scheme', value: 'dark'},
]);
expect(
await page.evaluate(() => {
@ -283,8 +283,8 @@ describe('Emulation', () => {
})
).toBe(false);
await page.emulateMediaFeatures([
{ name: 'prefers-reduced-motion', value: 'reduce' },
{ name: 'prefers-color-scheme', value: 'light' },
{name: 'prefers-reduced-motion', value: 'reduce'},
{name: 'prefers-color-scheme', value: 'light'},
]);
expect(
await page.evaluate(() => {
@ -306,7 +306,7 @@ describe('Emulation', () => {
return matchMedia('(prefers-color-scheme: dark)').matches;
})
).toBe(false);
await page.emulateMediaFeatures([{ name: 'color-gamut', value: 'srgb' }]);
await page.emulateMediaFeatures([{name: 'color-gamut', value: 'srgb'}]);
expect(
await page.evaluate(() => {
return matchMedia('(color-gamut: p3)').matches;
@ -322,7 +322,7 @@ describe('Emulation', () => {
return matchMedia('(color-gamut: rec2020)').matches;
})
).toBe(false);
await page.emulateMediaFeatures([{ name: 'color-gamut', value: 'p3' }]);
await page.emulateMediaFeatures([{name: 'color-gamut', value: 'p3'}]);
expect(
await page.evaluate(() => {
return matchMedia('(color-gamut: p3)').matches;
@ -339,7 +339,7 @@ describe('Emulation', () => {
})
).toBe(false);
await page.emulateMediaFeatures([
{ name: 'color-gamut', value: 'rec2020' },
{name: 'color-gamut', value: 'rec2020'},
]);
expect(
await page.evaluate(() => {
@ -358,12 +358,12 @@ describe('Emulation', () => {
).toBe(true);
});
it('should throw in case of bad argument', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error!: Error;
await page
.emulateMediaFeatures([{ name: 'bad', value: '' }])
.catch((error_) => {
.emulateMediaFeatures([{name: 'bad', value: ''}])
.catch(error_ => {
return (error = error_);
});
expect(error.message).toBe('Unsupported media feature: bad');
@ -372,7 +372,7 @@ describe('Emulation', () => {
describeFailsFirefox('Page.emulateTimezone', function () {
it('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.evaluate(() => {
(globalThis as any).date = new Date(1479579154987);
@ -411,14 +411,14 @@ describe('Emulation', () => {
});
it('should throw for invalid timezone IDs', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error!: Error;
await page.emulateTimezone('Foo/Bar').catch((error_) => {
await page.emulateTimezone('Foo/Bar').catch(error_ => {
return (error = error_);
});
expect(error.message).toBe('Invalid timezone ID: Foo/Bar');
await page.emulateTimezone('Baz/Qux').catch((error_) => {
await page.emulateTimezone('Baz/Qux').catch(error_ => {
return (error = error_);
});
expect(error.message).toBe('Invalid timezone ID: Baz/Qux');
@ -427,9 +427,9 @@ describe('Emulation', () => {
describeFailsFirefox('Page.emulateVisionDeficiency', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.setViewport({ width: 500, height: 500 });
await page.setViewport({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid.html');
{
@ -476,13 +476,13 @@ describe('Emulation', () => {
});
it('should throw for invalid vision deficiencies', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error!: Error;
await page
// @ts-expect-error deliberately passign invalid deficiency
.emulateVisionDeficiency('invalid')
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error.message).toBe('Unsupported vision deficiency: invalid');
@ -491,7 +491,7 @@ describe('Emulation', () => {
describeFailsFirefox('Page.emulateNetworkConditions', function () {
it('should change navigator.connection.effectiveType', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
const slow3G = puppeteer.networkConditions['Slow 3G']!;
const fast3G = puppeteer.networkConditions['Fast 3G']!;
@ -513,7 +513,7 @@ describe('Emulation', () => {
describeFailsFirefox('Page.emulateCPUThrottling', function () {
it('should change the CPU throttling rate successfully', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.emulateCPUThrottling(100);
await page.emulateCPUThrottling(null);

View File

@ -32,7 +32,7 @@ describe('Evaluation specs', function () {
describe('Page.evaluate', function () {
it('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(() => {
return 7 * 3;
@ -40,7 +40,7 @@ describe('Evaluation specs', function () {
expect(result).toBe(21);
});
(bigint ? it : xit)('should transfer BigInt', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate((a: bigint) => {
return a;
@ -48,42 +48,42 @@ describe('Evaluation specs', function () {
expect(result).toBe(BigInt(42));
});
it('should transfer NaN', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate((a) => {
const result = await page.evaluate(a => {
return a;
}, NaN);
expect(Object.is(result, NaN)).toBe(true);
});
it('should transfer -0', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate((a) => {
const result = await page.evaluate(a => {
return a;
}, -0);
expect(Object.is(result, -0)).toBe(true);
});
it('should transfer Infinity', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate((a) => {
const result = await page.evaluate(a => {
return a;
}, Infinity);
expect(Object.is(result, Infinity)).toBe(true);
});
it('should transfer -Infinity', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate((a) => {
const result = await page.evaluate(a => {
return a;
}, -Infinity);
expect(Object.is(result, -Infinity)).toBe(true);
});
it('should transfer arrays', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(
(a) => {
a => {
return a;
},
[1, 2, 3]
@ -91,10 +91,10 @@ describe('Evaluation specs', function () {
expect(result).toEqual([1, 2, 3]);
});
it('should transfer arrays as arrays, not objects', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(
(a) => {
a => {
return Array.isArray(a);
},
[1, 2, 3]
@ -102,7 +102,7 @@ describe('Evaluation specs', function () {
expect(result).toBe(true);
});
it('should modify global environment', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.evaluate(() => {
return ((globalThis as any).globalVar = 123);
@ -110,7 +110,7 @@ describe('Evaluation specs', function () {
expect(await page.evaluate('globalVar')).toBe(123);
});
it('should evaluate in the page context', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/global-var.html');
expect(await page.evaluate('globalVar')).toBe(123);
@ -118,7 +118,7 @@ describe('Evaluation specs', function () {
itFailsFirefox(
'should return undefined for objects with symbols',
async () => {
const { page } = getTestState();
const {page} = getTestState();
expect(
await page.evaluate(() => {
@ -128,7 +128,7 @@ describe('Evaluation specs', function () {
}
);
it('should work with function shorthands', async () => {
const { page } = getTestState();
const {page} = getTestState();
const a = {
sum(a: number, b: number) {
@ -143,10 +143,10 @@ describe('Evaluation specs', function () {
expect(await page.evaluate(a.mult, 2, 4)).toBe(8);
});
it('should work with unicode chars', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(
(a) => {
a => {
return a['中文字符'];
},
{
@ -156,7 +156,7 @@ describe('Evaluation specs', function () {
expect(result).toBe(42);
});
itFailsFirefox('should throw when evaluation triggers reload', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error!: Error;
await page
@ -164,13 +164,13 @@ describe('Evaluation specs', function () {
location.reload();
return new Promise(() => {});
})
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error.message).toContain('Protocol error');
});
it('should await promise', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(() => {
return Promise.resolve(8 * 7);
@ -178,10 +178,10 @@ describe('Evaluation specs', function () {
expect(result).toBe(56);
});
it('should work right after framenavigated', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
let frameEvaluation = null;
page.on('framenavigated', async (frame) => {
page.on('framenavigated', async frame => {
frameEvaluation = frame.evaluate(() => {
return 6 * 7;
});
@ -190,7 +190,7 @@ describe('Evaluation specs', function () {
expect(await frameEvaluation).toBe(42);
});
itFailsFirefox('should work from-inside an exposed function', async () => {
const { page } = getTestState();
const {page} = getTestState();
// Setup inpage callback, which calls Page.evaluate
await page.exposeFunction(
@ -211,7 +211,7 @@ describe('Evaluation specs', function () {
expect(result).toBe(27);
});
it('should reject promise with exception', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error!: Error;
await page
@ -219,52 +219,52 @@ describe('Evaluation specs', function () {
// @ts-expect-error we know the object doesn't exist
return notExistingObject.property;
})
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error).toBeTruthy();
expect(error.message).toContain('notExistingObject');
});
it('should support thrown strings as error messages', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error!: Error;
await page
.evaluate(() => {
throw 'qwerty';
})
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error).toBeTruthy();
expect(error.message).toContain('qwerty');
});
it('should support thrown numbers as error messages', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error!: Error;
await page
.evaluate(() => {
throw 100500;
})
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error).toBeTruthy();
expect(error.message).toContain('100500');
});
it('should return complex objects', async () => {
const { page } = getTestState();
const {page} = getTestState();
const object = { foo: 'bar!' };
const result = await page.evaluate((a) => {
const object = {foo: 'bar!'};
const result = await page.evaluate(a => {
return a;
}, object);
expect(result).not.toBe(object);
expect(result).toEqual(object);
});
(bigint ? it : xit)('should return BigInt', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(() => {
return BigInt(42);
@ -272,7 +272,7 @@ describe('Evaluation specs', function () {
expect(result).toBe(BigInt(42));
});
it('should return NaN', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(() => {
return NaN;
@ -280,7 +280,7 @@ describe('Evaluation specs', function () {
expect(Object.is(result, NaN)).toBe(true);
});
it('should return -0', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(() => {
return -0;
@ -288,7 +288,7 @@ describe('Evaluation specs', function () {
expect(Object.is(result, -0)).toBe(true);
});
it('should return Infinity', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(() => {
return Infinity;
@ -296,7 +296,7 @@ describe('Evaluation specs', function () {
expect(Object.is(result, Infinity)).toBe(true);
});
it('should return -Infinity', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(() => {
return -Infinity;
@ -304,7 +304,7 @@ describe('Evaluation specs', function () {
expect(Object.is(result, -Infinity)).toBe(true);
});
it('should accept "null" as one of multiple parameters', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(
(a, b) => {
@ -316,18 +316,18 @@ describe('Evaluation specs', function () {
expect(result).toBe(true);
});
it('should properly serialize null fields', async () => {
const { page } = getTestState();
const {page} = getTestState();
expect(
await page.evaluate(() => {
return { a: undefined };
return {a: undefined};
})
).toEqual({});
});
itFailsFirefox(
'should return undefined for non-serializable objects',
async () => {
const { page } = getTestState();
const {page} = getTestState();
expect(
await page.evaluate(() => {
@ -337,66 +337,64 @@ describe('Evaluation specs', function () {
}
);
itFailsFirefox('should fail for circular object', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(() => {
const a: { [x: string]: any } = {};
const b = { a };
const a: {[x: string]: any} = {};
const b = {a};
a['b'] = b;
return a;
});
expect(result).toBe(undefined);
});
itFailsFirefox('should be able to throw a tricky error', async () => {
const { page } = getTestState();
const {page} = getTestState();
const windowHandle = await page.evaluateHandle(() => {
return window;
});
const errorText = await windowHandle
.jsonValue<string>()
.catch((error_) => {
return error_.message;
});
const errorText = await windowHandle.jsonValue<string>().catch(error_ => {
return error_.message;
});
const error = await page
.evaluate<(errorText: string) => Error>((errorText) => {
.evaluate<(errorText: string) => Error>(errorText => {
throw new Error(errorText);
}, errorText)
.catch((error_) => {
.catch(error_ => {
return error_;
});
expect(error.message).toContain(errorText);
});
it('should accept a string', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate('1 + 2');
expect(result).toBe(3);
});
it('should accept a string with semi colons', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate('1 + 5;');
expect(result).toBe(6);
});
it('should accept a string with comments', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate('2 + 5;\n// do some math!');
expect(result).toBe(7);
});
it('should accept element handle as an argument', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent('<section>42</section>');
const element = (await page.$('section'))!;
const text = await page.evaluate((e) => {
const text = await page.evaluate(e => {
return e.textContent;
}, element);
expect(text).toBe('42');
});
it('should throw if underlying element was disposed', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent('<section>39</section>');
const element = (await page.$('section'))!;
@ -407,7 +405,7 @@ describe('Evaluation specs', function () {
.evaluate((e: HTMLElement) => {
return e.textContent;
}, element)
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error.message).toContain('JSHandle is disposed');
@ -415,7 +413,7 @@ describe('Evaluation specs', function () {
itFailsFirefox(
'should throw if elementHandles are from other frames',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
const bodyHandle = await page.frames()[1]!.$('body');
@ -424,7 +422,7 @@ describe('Evaluation specs', function () {
.evaluate((body: HTMLElement) => {
return body.innerHTML;
}, bodyHandle)
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error).toBeTruthy();
@ -434,7 +432,7 @@ describe('Evaluation specs', function () {
}
);
itFailsFirefox('should simulate a user gesture', async () => {
const { page } = getTestState();
const {page} = getTestState();
const result = await page.evaluate(() => {
document.body.appendChild(document.createTextNode('test'));
@ -444,7 +442,7 @@ describe('Evaluation specs', function () {
expect(result).toBe(true);
});
itFailsFirefox('should throw a nice error after a navigation', async () => {
const { page } = getTestState();
const {page} = getTestState();
const executionContext = await page.mainFrame().executionContext();
@ -458,7 +456,7 @@ describe('Evaluation specs', function () {
.evaluate(() => {
return null;
})
.catch((error_) => {
.catch(error_ => {
return error_;
});
expect((error as Error).message).toContain('navigation');
@ -466,7 +464,7 @@ describe('Evaluation specs', function () {
itFailsFirefox(
'should not throw an error when evaluation does a navigation',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/one-style.html');
const result = await page.evaluate(() => {
@ -477,7 +475,7 @@ describe('Evaluation specs', function () {
}
);
it('should transfer 100Mb of data from page to node.js', async function () {
const { page } = getTestState();
const {page} = getTestState();
const a = await page.evaluate<() => string>(() => {
return Array(100 * 1024 * 1024 + 1).join('a');
@ -485,7 +483,7 @@ describe('Evaluation specs', function () {
expect(a.length).toBe(100 * 1024 * 1024);
});
it('should throw error with detailed information on exception inside promise ', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error!: Error;
await page
@ -494,7 +492,7 @@ describe('Evaluation specs', function () {
throw new Error('Error in promise');
});
})
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error.message).toContain('Error in promise');
@ -503,7 +501,7 @@ describe('Evaluation specs', function () {
describeFailsFirefox('Page.evaluateOnNewDocument', function () {
it('should evaluate before anything else on the page', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.evaluateOnNewDocument(function () {
(globalThis as any).injected = 123;
@ -516,7 +514,7 @@ describe('Evaluation specs', function () {
).toBe(123);
});
it('should work with CSP', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
server.setCSP('/empty.html', 'script-src ' + server.PREFIX);
await page.evaluateOnNewDocument(function () {
@ -530,7 +528,7 @@ describe('Evaluation specs', function () {
).toBe(123);
// Make sure CSP works.
await page.addScriptTag({ content: 'window.e = 10;' }).catch((error) => {
await page.addScriptTag({content: 'window.e = 10;'}).catch(error => {
return void error;
});
expect(
@ -543,7 +541,7 @@ describe('Evaluation specs', function () {
describe('Frame.evaluate', function () {
it('should have different execution contexts', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
@ -566,7 +564,7 @@ describe('Evaluation specs', function () {
).toBe('bar');
});
it('should have correct execution contexts', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/frames/one-frame.html');
expect(page.frames().length).toBe(2);
@ -582,7 +580,7 @@ describe('Evaluation specs', function () {
).toBe(`Hi, I'm frame`);
});
it('should execute after cross-site navigation', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
const mainFrame = page.mainFrame();

View File

@ -17,16 +17,16 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import expect from 'expect';
import { getTestState, itHeadlessOnly } from './mocha-utils.js';
import {getTestState, itHeadlessOnly} from './mocha-utils.js';
import path from 'path';
describe('Fixtures', function () {
itHeadlessOnly('dumpio option should work with pipe option ', async () => {
const { defaultBrowserOptions, puppeteerPath } = getTestState();
const {defaultBrowserOptions, puppeteerPath} = getTestState();
let dumpioData = '';
const { spawn } = await import('child_process');
const {spawn} = await import('child_process');
const options = Object.assign({}, defaultBrowserOptions, {
pipe: true,
dumpio: true,
@ -36,37 +36,37 @@ describe('Fixtures', function () {
puppeteerPath,
JSON.stringify(options),
]);
res.stderr.on('data', (data) => {
res.stderr.on('data', data => {
return (dumpioData += data.toString('utf8'));
});
await new Promise((resolve) => {
await new Promise(resolve => {
return res.on('close', resolve);
});
expect(dumpioData).toContain('message from dumpio');
});
it('should dump browser process stderr', async () => {
const { defaultBrowserOptions, puppeteerPath } = getTestState();
const {defaultBrowserOptions, puppeteerPath} = getTestState();
let dumpioData = '';
const { spawn } = await import('child_process');
const options = Object.assign({}, defaultBrowserOptions, { dumpio: true });
const {spawn} = await import('child_process');
const options = Object.assign({}, defaultBrowserOptions, {dumpio: true});
const res = spawn('node', [
path.join(__dirname, '../fixtures', 'dumpio.js'),
puppeteerPath,
JSON.stringify(options),
]);
res.stderr.on('data', (data) => {
res.stderr.on('data', data => {
return (dumpioData += data.toString('utf8'));
});
await new Promise((resolve) => {
await new Promise(resolve => {
return res.on('close', resolve);
});
expect(dumpioData).toContain('DevTools listening on ws://');
});
it('should close the browser when the node process closes', async () => {
const { defaultBrowserOptions, puppeteerPath, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteerPath, puppeteer} = getTestState();
const { spawn, execSync } = await import('child_process');
const {spawn, execSync} = await import('child_process');
const options = Object.assign({}, defaultBrowserOptions, {
// Disable DUMPIO to cleanly read stdout.
dumpio: false,
@ -77,11 +77,11 @@ describe('Fixtures', function () {
JSON.stringify(options),
]);
let wsEndPointCallback: (value: string) => void;
const wsEndPointPromise = new Promise<string>((x) => {
const wsEndPointPromise = new Promise<string>(x => {
return (wsEndPointCallback = x);
});
let output = '';
res.stdout.on('data', (data) => {
res.stdout.on('data', data => {
output += data;
if (output.indexOf('\n')) {
wsEndPointCallback(output.substring(0, output.indexOf('\n')));
@ -91,10 +91,10 @@ describe('Fixtures', function () {
browserWSEndpoint: await wsEndPointPromise,
});
const promises = [
new Promise((resolve) => {
new Promise(resolve => {
return browser.once('disconnected', resolve);
}),
new Promise((resolve) => {
new Promise(resolve => {
return res.on('close', resolve);
}),
];

View File

@ -15,15 +15,15 @@
*/
import expect from 'expect';
import { CDPSession } from '../../lib/cjs/puppeteer/common/Connection.js';
import { Frame } from '../../lib/cjs/puppeteer/common/FrameManager.js';
import {CDPSession} from '../../lib/cjs/puppeteer/common/Connection.js';
import {Frame} from '../../lib/cjs/puppeteer/common/FrameManager.js';
import {
getTestState,
itFailsFirefox,
setupTestBrowserHooks,
setupTestPageAndContextHooks,
} from './mocha-utils.js';
import utils, { dumpFrames } from './utils.js';
import utils, {dumpFrames} from './utils.js';
describe('Frame specs', function () {
setupTestBrowserHooks();
@ -31,7 +31,7 @@ describe('Frame specs', function () {
describe('Frame.executionContext', function () {
itFailsFirefox('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
@ -68,7 +68,7 @@ describe('Frame specs', function () {
describe('Frame.evaluateHandle', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
const mainFrame = page.mainFrame();
@ -81,7 +81,7 @@ describe('Frame specs', function () {
describe('Frame.evaluate', function () {
itFailsFirefox('should throw for detached frames', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const frame1 = (await utils.attachFrame(
page,
@ -94,7 +94,7 @@ describe('Frame specs', function () {
.evaluate(() => {
return 7 * 8;
})
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error.message).toContain(
@ -103,14 +103,14 @@ describe('Frame specs', function () {
});
it('allows readonly array to be an argument', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
const mainFrame = page.mainFrame();
// This test checks if Frame.evaluate allows a readonly array to be an argument.
// See https://github.com/puppeteer/puppeteer/issues/6953.
const readonlyArray: readonly string[] = ['a', 'b', 'c'];
await mainFrame.evaluate((arr) => {
await mainFrame.evaluate(arr => {
return arr;
}, readonlyArray);
});
@ -118,7 +118,7 @@ describe('Frame specs', function () {
describe('Frame Management', function () {
itFailsFirefox('should handle nested frames', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/frames/nested-frames.html');
expect(dumpFrames(page.mainFrame())).toEqual([
@ -132,12 +132,12 @@ describe('Frame specs', function () {
itFailsFirefox(
'should send events when frames are manipulated dynamically',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
// validate frameattached events
const attachedFrames: Frame[] = [];
page.on('frameattached', (frame) => {
page.on('frameattached', frame => {
return attachedFrames.push(frame);
});
await utils.attachFrame(page, 'frame1', './assets/frame.html');
@ -146,7 +146,7 @@ describe('Frame specs', function () {
// validate framenavigated events
const navigatedFrames: Frame[] = [];
page.on('framenavigated', (frame) => {
page.on('framenavigated', frame => {
return navigatedFrames.push(frame);
});
await utils.navigateFrame(page, 'frame1', './empty.html');
@ -155,7 +155,7 @@ describe('Frame specs', function () {
// validate framedetached events
const detachedFrames: Frame[] = [];
page.on('framedetached', (frame) => {
page.on('framedetached', frame => {
return detachedFrames.push(frame);
});
await utils.detachFrame(page, 'frame1');
@ -164,7 +164,7 @@ describe('Frame specs', function () {
}
);
it('should send "framenavigated" when navigating on anchor URLs', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await Promise.all([
@ -174,7 +174,7 @@ describe('Frame specs', function () {
expect(page.url()).toBe(server.EMPTY_PAGE + '#foo');
});
it('should persist mainFrame on cross-process navigation', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
const mainFrame = page.mainFrame();
@ -182,7 +182,7 @@ describe('Frame specs', function () {
expect(page.mainFrame() === mainFrame).toBeTruthy();
});
it('should not send attach/detach events for main frame', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
let hasEvents = false;
page.on('frameattached', () => {
@ -195,18 +195,18 @@ describe('Frame specs', function () {
expect(hasEvents).toBe(false);
});
it('should detach child frames on navigation', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
let attachedFrames = [];
let detachedFrames = [];
let navigatedFrames = [];
page.on('frameattached', (frame) => {
page.on('frameattached', frame => {
return attachedFrames.push(frame);
});
page.on('framedetached', (frame) => {
page.on('framedetached', frame => {
return detachedFrames.push(frame);
});
page.on('framenavigated', (frame) => {
page.on('framenavigated', frame => {
return navigatedFrames.push(frame);
});
await page.goto(server.PREFIX + '/frames/nested-frames.html');
@ -223,18 +223,18 @@ describe('Frame specs', function () {
expect(navigatedFrames.length).toBe(1);
});
it('should support framesets', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
let attachedFrames = [];
let detachedFrames = [];
let navigatedFrames = [];
page.on('frameattached', (frame) => {
page.on('frameattached', frame => {
return attachedFrames.push(frame);
});
page.on('framedetached', (frame) => {
page.on('framedetached', frame => {
return detachedFrames.push(frame);
});
page.on('framenavigated', (frame) => {
page.on('framenavigated', frame => {
return navigatedFrames.push(frame);
});
await page.goto(server.PREFIX + '/frames/frameset.html');
@ -251,14 +251,14 @@ describe('Frame specs', function () {
expect(navigatedFrames.length).toBe(1);
});
itFailsFirefox('should report frame from-inside shadow DOM', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/shadow.html');
await page.evaluate(async (url: string) => {
const frame = document.createElement('iframe');
frame.src = url;
document.body.shadowRoot!.appendChild(frame);
await new Promise((x) => {
await new Promise(x => {
return (frame.onload = x);
});
}, server.EMPTY_PAGE);
@ -266,7 +266,7 @@ describe('Frame specs', function () {
expect(page.frames()[1]!.url()).toBe(server.EMPTY_PAGE);
});
itFailsFirefox('should report frame.name()', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await utils.attachFrame(page, 'theFrameId', server.EMPTY_PAGE);
await page.evaluate((url: string) => {
@ -274,7 +274,7 @@ describe('Frame specs', function () {
frame.name = 'theFrameName';
frame.src = url;
document.body.appendChild(frame);
return new Promise((x) => {
return new Promise(x => {
return (frame.onload = x);
});
}, server.EMPTY_PAGE);
@ -283,7 +283,7 @@ describe('Frame specs', function () {
expect(page.frames()[2]!.name()).toBe('theFrameName');
});
itFailsFirefox('should report frame.parent()', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
await utils.attachFrame(page, 'frame2', server.EMPTY_PAGE);
@ -294,7 +294,7 @@ describe('Frame specs', function () {
itFailsFirefox(
'should report different frame instance when frame re-attaches',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const frame1 = await utils.attachFrame(
page,
@ -317,7 +317,7 @@ describe('Frame specs', function () {
}
);
it('should support url fragment', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/frames/one-frame-url-fragment.html');
@ -327,13 +327,13 @@ describe('Frame specs', function () {
);
});
itFailsFirefox('should support lazy frames', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.setViewport({ width: 1000, height: 1000 });
await page.setViewport({width: 1000, height: 1000});
await page.goto(server.PREFIX + '/frames/lazy-frame.html');
expect(
page.frames().map((frame) => {
page.frames().map(frame => {
return frame._hasStartedLoading;
})
).toEqual([true, true, false]);
@ -342,7 +342,7 @@ describe('Frame specs', function () {
describe('Frame.client', function () {
it('should return the client instance', async () => {
const { page } = getTestState();
const {page} = getTestState();
expect(page.mainFrame()._client()).toBeInstanceOf(CDPSession);
});
});

View File

@ -20,7 +20,7 @@ import jpeg from 'jpeg-js';
import mime from 'mime';
import path from 'path';
import pixelmatch from 'pixelmatch';
import { PNG } from 'pngjs';
import {PNG} from 'pngjs';
interface DiffFile {
diff: string | Buffer;
@ -69,16 +69,16 @@ const compareImages = (
`Sizes differ: expected image ${expected.width}px X ${expected.height}px, but got ${actual.width}px X ${actual.height}px.`
);
}
const diff = new PNG({ width: expected.width, height: expected.height });
const diff = new PNG({width: expected.width, height: expected.height});
const count = pixelmatch(
expected.data,
actual.data,
diff.data,
expected.width,
expected.height,
{ threshold: 0.1 }
{threshold: 0.1}
);
return count > 0 ? { diff: PNG.sync.write(diff) } : undefined;
return count > 0 ? {diff: PNG.sync.write(diff)} : undefined;
};
const compareText = (
@ -114,7 +114,7 @@ export const compare = (
outputPath: string,
actual: string | Buffer,
goldenName: string
): { pass: true } | { pass: false; message: string } => {
): {pass: true} | {pass: false; message: string} => {
goldenPath = path.normalize(goldenPath);
outputPath = path.normalize(outputPath);
const expectedPath = path.join(goldenPath, goldenName);
@ -144,7 +144,7 @@ export const compare = (
}
const result = comparator(actual, expected, mimeType);
if (!result) {
return { pass: true };
return {pass: true};
}
ensureOutputDir();
if (goldenPath === outputPath) {

View File

@ -19,7 +19,7 @@ import fs from 'fs';
import os from 'os';
import path from 'path';
import rimraf from 'rimraf';
import { promisify } from 'util';
import {promisify} from 'util';
import {
PuppeteerLaunchOptions,
PuppeteerNode,
@ -44,7 +44,7 @@ describeChromeOnly('headful tests', function () {
this.timeout(20 * 1000);
let headfulOptions: PuppeteerLaunchOptions | undefined;
let headlessOptions: PuppeteerLaunchOptions & { headless: boolean };
let headlessOptions: PuppeteerLaunchOptions & {headless: boolean};
let extensionOptions: PuppeteerLaunchOptions & {
headless: boolean;
args: string[];
@ -61,7 +61,7 @@ describeChromeOnly('headful tests', function () {
const browsers: any[] = [];
beforeEach(() => {
const { server, defaultBrowserOptions } = getTestState();
const {server, defaultBrowserOptions} = getTestState();
headfulOptions = Object.assign({}, defaultBrowserOptions, {
headless: false,
});
@ -113,14 +113,14 @@ describeChromeOnly('headful tests', function () {
describe('HEADFUL', function () {
it('background_page target type should be available', async () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const browserWithExtension = await launchBrowser(
puppeteer,
extensionOptions
);
const page = await browserWithExtension.newPage();
const backgroundPageTarget = await browserWithExtension.waitForTarget(
(target: { type: () => string }) => {
(target: {type: () => string}) => {
return target.type() === 'background_page';
}
);
@ -129,13 +129,13 @@ describeChromeOnly('headful tests', function () {
expect(backgroundPageTarget).toBeTruthy();
});
it('target.page() should return a background_page', async function () {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const browserWithExtension = await launchBrowser(
puppeteer,
extensionOptions
);
const backgroundPageTarget = await browserWithExtension.waitForTarget(
(target: { type: () => string }) => {
(target: {type: () => string}) => {
return target.type() === 'background_page';
}
);
@ -153,7 +153,7 @@ describeChromeOnly('headful tests', function () {
await browserWithExtension.close();
});
it('target.page() should return a DevTools page if custom isPageTarget is provided', async function () {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const originalBrowser = await launchBrowser(puppeteer, devtoolsOptions);
const browserWSEndpoint = originalBrowser.wsEndpoint();
@ -166,7 +166,7 @@ describeChromeOnly('headful tests', function () {
);
},
});
const devtoolsPageTarget = await browser.waitForTarget((target) => {
const devtoolsPageTarget = await browser.waitForTarget(target => {
return target.type() === 'other';
});
const page = (await devtoolsPageTarget.page())!;
@ -179,9 +179,9 @@ describeChromeOnly('headful tests', function () {
await browser.close();
});
it('should have default url when launching browser', async function () {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const browser = await launchBrowser(puppeteer, extensionOptions);
const pages = (await browser.pages()).map((page: { url: () => any }) => {
const pages = (await browser.pages()).map((page: {url: () => any}) => {
return page.url();
});
expect(pages).toEqual(['about:blank']);
@ -191,13 +191,13 @@ describeChromeOnly('headful tests', function () {
'headless should be able to read cookies written by headful',
async () => {
/* Needs investigation into why but this fails consistently on Windows CI. */
const { server, puppeteer } = getTestState();
const {server, puppeteer} = getTestState();
const userDataDir = await mkdtempAsync(TMP_FOLDER);
// Write a cookie in headful chrome
const headfulBrowser = await launchBrowser(
puppeteer,
Object.assign({ userDataDir }, headfulOptions)
Object.assign({userDataDir}, headfulOptions)
);
const headfulPage = await headfulBrowser.newPage();
await headfulPage.goto(server.EMPTY_PAGE);
@ -209,7 +209,7 @@ describeChromeOnly('headful tests', function () {
// Read the cookie from headless chrome
const headlessBrowser = await launchBrowser(
puppeteer,
Object.assign({ userDataDir }, headlessOptions)
Object.assign({userDataDir}, headlessOptions)
);
const headlessPage = await headlessBrowser.newPage();
await headlessPage.goto(server.EMPTY_PAGE);
@ -224,28 +224,28 @@ describeChromeOnly('headful tests', function () {
);
// TODO: Support OOOPIF. @see https://github.com/puppeteer/puppeteer/issues/2548
xit('OOPIF: should report google.com frame', async () => {
const { server, puppeteer } = getTestState();
const {server, puppeteer} = getTestState();
// https://google.com is isolated by default in Chromium embedder.
const browser = await launchBrowser(puppeteer, headfulOptions);
const page = await browser.newPage();
await page.goto(server.EMPTY_PAGE);
await page.setRequestInterception(true);
page.on('request', (r: { respond: (arg0: { body: string }) => any }) => {
return r.respond({ body: 'YO, GOOGLE.COM' });
page.on('request', (r: {respond: (arg0: {body: string}) => any}) => {
return r.respond({body: 'YO, GOOGLE.COM'});
});
await page.evaluate(() => {
const frame = document.createElement('iframe');
frame.setAttribute('src', 'https://google.com/');
document.body.appendChild(frame);
return new Promise((x) => {
return new Promise(x => {
return (frame.onload = x);
});
});
await page.waitForSelector('iframe[src="https://google.com/"]');
const urls = page
.frames()
.map((frame: { url: () => any }) => {
.map((frame: {url: () => any}) => {
return frame.url();
})
.sort();
@ -253,7 +253,7 @@ describeChromeOnly('headful tests', function () {
await browser.close();
});
it('OOPIF: should expose events within OOPIFs', async () => {
const { server, puppeteer } = getTestState();
const {server, puppeteer} = getTestState();
const browser = await launchBrowser(puppeteer, forcedOopifOptions);
const page = await browser.newPage();
@ -307,13 +307,13 @@ describeChromeOnly('headful tests', function () {
});
await browser.close();
const requests = networkEvents.map((event) => {
const requests = networkEvents.map(event => {
return event.request.url;
});
expect(requests).toContain(`http://oopifdomain:${server.PORT}/fetch`);
});
it('should close browser with beforeunload page', async () => {
const { server, puppeteer } = getTestState();
const {server, puppeteer} = getTestState();
const browser = await launchBrowser(puppeteer, headfulOptions);
const page = await browser.newPage();
@ -324,16 +324,16 @@ describeChromeOnly('headful tests', function () {
await browser.close();
});
it('should open devtools when "devtools: true" option is given', async () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const browser = await launchBrowser(
puppeteer,
Object.assign({ devtools: true }, headfulOptions)
Object.assign({devtools: true}, headfulOptions)
);
const context = await browser.createIncognitoBrowserContext();
await Promise.all([
context.newPage(),
browser.waitForTarget((target: { url: () => string | string[] }) => {
browser.waitForTarget((target: {url: () => string | string[]}) => {
return target.url().includes('devtools://');
}),
]);
@ -343,7 +343,7 @@ describeChromeOnly('headful tests', function () {
describe('Page.bringToFront', function () {
it('should work', async () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const browser = await launchBrowser(puppeteer, headfulOptions);
const page1 = await browser.newPage();
const page2 = await browser.newPage();
@ -380,7 +380,7 @@ describeChromeOnly('headful tests', function () {
describe('Page.screenshot', function () {
it('should run in parallel in multiple pages', async () => {
const { server, puppeteer } = getTestState();
const {server, puppeteer} = getTestState();
const browser = await puppeteer.launch(headfulOptions);
const context = await browser.createIncognitoBrowserContext();
@ -398,7 +398,7 @@ describeChromeOnly('headful tests', function () {
for (let i = 0; i < N; ++i) {
promises.push(
pages[i]!.screenshot({
clip: { x: 50 * i, y: 0, width: 50, height: 50 },
clip: {x: 50 * i, y: 0, width: 50, height: 50},
})
);
}
@ -407,7 +407,7 @@ describeChromeOnly('headful tests', function () {
expect(screenshots[i]).toBeGolden(`grid-cell-${i}.png`);
}
await Promise.all(
pages.map((page) => {
pages.map(page => {
return page.close();
})
);

View File

@ -27,7 +27,7 @@ describeFailsFirefox('Emulate idle state', () => {
setupTestPageAndContextHooks();
async function getIdleState() {
const { page } = getTestState();
const {page} = getTestState();
const stateElement = (await page.$('#state'))!;
return await page.evaluate((element: HTMLElement) => {
@ -41,7 +41,7 @@ describeFailsFirefox('Emulate idle state', () => {
}
it('changing idle state emulation causes change of the IdleDetector state', async () => {
const { page, server, context } = getTestState();
const {page, server, context} = getTestState();
await context.overridePermissions(server.PREFIX + '/idle-detector.html', [
'idle-detection',
]);

View File

@ -15,13 +15,13 @@
*/
import expect from 'expect';
import { TLSSocket } from 'tls';
import {TLSSocket} from 'tls';
import {
Browser,
BrowserContext,
} from '../../lib/cjs/puppeteer/common/Browser.js';
import { Page } from '../../lib/cjs/puppeteer/common/Page.js';
import { HTTPResponse } from '../../lib/cjs/puppeteer/common/HTTPResponse.js';
import {Page} from '../../lib/cjs/puppeteer/common/Page.js';
import {HTTPResponse} from '../../lib/cjs/puppeteer/common/HTTPResponse.js';
import {
getTestState,
describeFailsFirefox,
@ -38,9 +38,9 @@ describe('ignoreHTTPSErrors', function () {
let page!: Page;
before(async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const options = Object.assign(
{ ignoreHTTPSErrors: true },
{ignoreHTTPSErrors: true},
defaultBrowserOptions
);
browser = await puppeteer.launch(options);
@ -61,7 +61,7 @@ describe('ignoreHTTPSErrors', function () {
describeFailsFirefox('Response.securityDetails', function () {
it('should work', async () => {
const { httpsServer } = getTestState();
const {httpsServer} = getTestState();
const [serverRequest, response] = await Promise.all([
httpsServer.waitForRequest('/empty.html'),
@ -82,17 +82,17 @@ describe('ignoreHTTPSErrors', function () {
]);
});
it('should be |null| for non-secure requests', async () => {
const { server } = getTestState();
const {server} = getTestState();
const response = (await page.goto(server.EMPTY_PAGE))!;
expect(response.securityDetails()).toBe(null);
});
it('Network redirects should report SecurityDetails', async () => {
const { httpsServer } = getTestState();
const {httpsServer} = getTestState();
httpsServer.setRedirect('/plzredirect', '/empty.html');
const responses: HTTPResponse[] = [];
page.on('response', (response) => {
page.on('response', response => {
return responses.push(response);
});
const [serverRequest] = await Promise.all([
@ -110,27 +110,27 @@ describe('ignoreHTTPSErrors', function () {
});
it('should work', async () => {
const { httpsServer } = getTestState();
const {httpsServer} = getTestState();
let error!: Error;
const response = await page.goto(httpsServer.EMPTY_PAGE).catch((error_) => {
const response = await page.goto(httpsServer.EMPTY_PAGE).catch(error_ => {
return (error = error_);
});
expect(error).toBeUndefined();
expect(response.ok()).toBe(true);
});
itFailsFirefox('should work with request interception', async () => {
const { httpsServer } = getTestState();
const {httpsServer} = getTestState();
await page.setRequestInterception(true);
page.on('request', (request) => {
page.on('request', request => {
return request.continue();
});
const response = (await page.goto(httpsServer.EMPTY_PAGE))!;
expect(response.status()).toBe(200);
});
itFailsFirefox('should work with mixed content', async () => {
const { server, httpsServer } = getTestState();
const {server, httpsServer} = getTestState();
httpsServer.setRoute('/mixedcontent.html', (_req, res) => {
res.end(`<iframe src=${server.EMPTY_PAGE}></iframe>`);

View File

@ -31,17 +31,17 @@ describe('input tests', function () {
describeFailsFirefox('input', function () {
it('should upload the file', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/fileupload.html');
const filePath = path.relative(process.cwd(), FILE_TO_UPLOAD);
const input = (await page.$('input'))!;
await page.evaluate((e: HTMLElement) => {
(globalThis as any)._inputEvents = [];
e.addEventListener('change', (ev) => {
e.addEventListener('change', ev => {
return (globalThis as any)._inputEvents.push(ev.type);
});
e.addEventListener('input', (ev) => {
e.addEventListener('input', ev => {
return (globalThis as any)._inputEvents.push(ev.type);
});
}, input);
@ -64,7 +64,7 @@ describe('input tests', function () {
expect(
await page.evaluate((e: HTMLInputElement) => {
const reader = new FileReader();
const promise = new Promise((fulfill) => {
const promise = new Promise(fulfill => {
return (reader.onload = fulfill);
});
reader.readAsText(e.files![0]!);
@ -78,7 +78,7 @@ describe('input tests', function () {
describeFailsFirefox('Page.waitForFileChooser', function () {
it('should work when file input is attached to DOM', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input type=file>`);
const [chooser] = await Promise.all([
@ -88,7 +88,7 @@ describe('input tests', function () {
expect(chooser).toBeTruthy();
});
it('should work when file input is not attached to DOM', async () => {
const { page } = getTestState();
const {page} = getTestState();
const [chooser] = await Promise.all([
page.waitForFileChooser(),
@ -101,39 +101,39 @@ describe('input tests', function () {
expect(chooser).toBeTruthy();
});
it('should respect timeout', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
let error!: Error;
await page.waitForFileChooser({ timeout: 1 }).catch((error_) => {
await page.waitForFileChooser({timeout: 1}).catch(error_ => {
return (error = error_);
});
expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);
});
it('should respect default timeout when there is no custom timeout', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
page.setDefaultTimeout(1);
let error!: Error;
await page.waitForFileChooser().catch((error_) => {
await page.waitForFileChooser().catch(error_ => {
return (error = error_);
});
expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);
});
it('should prioritize exact timeout over default timeout', async () => {
const { page, puppeteer } = getTestState();
const {page, puppeteer} = getTestState();
page.setDefaultTimeout(0);
let error!: Error;
await page.waitForFileChooser({ timeout: 1 }).catch((error_) => {
await page.waitForFileChooser({timeout: 1}).catch(error_ => {
return (error = error_);
});
expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);
});
it('should work with no timeout', async () => {
const { page } = getTestState();
const {page} = getTestState();
const [chooser] = await Promise.all([
page.waitForFileChooser({ timeout: 0 }),
page.waitForFileChooser({timeout: 0}),
page.evaluate(() => {
return setTimeout(() => {
const el = document.createElement('input');
@ -145,13 +145,13 @@ describe('input tests', function () {
expect(chooser).toBeTruthy();
});
it('should return the same file chooser when there are many watchdogs simultaneously', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input type=file>`);
const [fileChooser1, fileChooser2] = await Promise.all([
page.waitForFileChooser(),
page.waitForFileChooser(),
page.$eval('input', (input) => {
page.$eval('input', input => {
return (input as HTMLInputElement).click();
}),
]);
@ -161,7 +161,7 @@ describe('input tests', function () {
describeFailsFirefox('FileChooser.accept', function () {
it('should accept single file', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(
`<input type=file oninput='javascript:console.timeStamp()'>`
@ -172,37 +172,37 @@ describe('input tests', function () {
]);
await Promise.all([
chooser.accept([FILE_TO_UPLOAD]),
new Promise((x) => {
new Promise(x => {
return page.once('metrics', x);
}),
]);
expect(
await page.$eval('input', (input) => {
await page.$eval('input', input => {
return (input as HTMLInputElement).files!.length;
})
).toBe(1);
expect(
await page.$eval('input', (input) => {
await page.$eval('input', input => {
return (input as HTMLInputElement).files![0]!.name;
})
).toBe('file-to-upload.txt');
});
it('should be able to read selected file', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input type=file>`);
page.waitForFileChooser().then((chooser) => {
page.waitForFileChooser().then(chooser => {
return chooser.accept([FILE_TO_UPLOAD]);
});
expect(
await page.$eval('input', async (picker) => {
await page.$eval('input', async picker => {
const pick = picker as HTMLInputElement;
pick.click();
await new Promise((x) => {
await new Promise(x => {
return (pick.oninput = x);
});
const reader = new FileReader();
const promise = new Promise((fulfill) => {
const promise = new Promise(fulfill => {
return (reader.onload = fulfill);
});
reader.readAsText(pick.files![0]!);
@ -213,30 +213,30 @@ describe('input tests', function () {
).toBe('contents of the file');
});
it('should be able to reset selected files with empty file list', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input type=file>`);
page.waitForFileChooser().then((chooser) => {
page.waitForFileChooser().then(chooser => {
return chooser.accept([FILE_TO_UPLOAD]);
});
expect(
await page.$eval('input', async (picker) => {
await page.$eval('input', async picker => {
const pick = picker as HTMLInputElement;
pick.click();
await new Promise((x) => {
await new Promise(x => {
return (pick.oninput = x);
});
return pick.files!.length;
})
).toBe(1);
page.waitForFileChooser().then((chooser) => {
page.waitForFileChooser().then(chooser => {
return chooser.accept([]);
});
expect(
await page.$eval('input', async (picker) => {
await page.$eval('input', async picker => {
const pick = picker as HTMLInputElement;
pick.click();
await new Promise((x) => {
await new Promise(x => {
return (pick.oninput = x);
});
return pick.files!.length;
@ -244,7 +244,7 @@ describe('input tests', function () {
).toBe(0);
});
it('should not accept multiple files for single-file input', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input type=file>`);
const [chooser] = await Promise.all([
@ -260,13 +260,13 @@ describe('input tests', function () {
),
path.relative(process.cwd(), __dirname + '/../assets/pptr.png'),
])
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error).not.toBe(null);
});
it('should succeed even for non-existent files', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input type=file>`);
const [chooser] = await Promise.all([
@ -274,27 +274,27 @@ describe('input tests', function () {
page.click('input'),
]);
let error!: Error;
await chooser.accept(['file-does-not-exist.txt']).catch((error_) => {
await chooser.accept(['file-does-not-exist.txt']).catch(error_ => {
return (error = error_);
});
expect(error).toBeUndefined();
});
it('should error on read of non-existent files', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input type=file>`);
page.waitForFileChooser().then((chooser) => {
page.waitForFileChooser().then(chooser => {
return chooser.accept(['file-does-not-exist.txt']);
});
expect(
await page.$eval('input', async (picker) => {
await page.$eval('input', async picker => {
const pick = picker as HTMLInputElement;
pick.click();
await new Promise((x) => {
await new Promise(x => {
return (pick.oninput = x);
});
const reader = new FileReader();
const promise = new Promise((fulfill) => {
const promise = new Promise(fulfill => {
return (reader.onerror = fulfill);
});
reader.readAsText(pick.files![0]!);
@ -305,18 +305,18 @@ describe('input tests', function () {
).toBeFalsy();
});
it('should fail when accepting file chooser twice', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input type=file>`);
const [fileChooser] = await Promise.all([
page.waitForFileChooser(),
page.$eval('input', (input) => {
page.$eval('input', input => {
return (input as HTMLInputElement).click();
}),
]);
await fileChooser.accept([]);
let error!: Error;
await fileChooser.accept([]).catch((error_) => {
await fileChooser.accept([]).catch(error_ => {
return (error = error_);
});
expect(error.message).toBe(
@ -327,7 +327,7 @@ describe('input tests', function () {
describeFailsFirefox('FileChooser.cancel', function () {
it('should cancel dialog', async () => {
const { page } = getTestState();
const {page} = getTestState();
// Consider file chooser canceled if we can summon another one.
// There's no reliable way in WebPlatform to see that FileChooser was
@ -335,7 +335,7 @@ describe('input tests', function () {
await page.setContent(`<input type=file>`);
const [fileChooser1] = await Promise.all([
page.waitForFileChooser(),
page.$eval('input', (input) => {
page.$eval('input', input => {
return (input as HTMLInputElement).click();
}),
]);
@ -343,18 +343,18 @@ describe('input tests', function () {
// If this resolves, than we successfully canceled file chooser.
await Promise.all([
page.waitForFileChooser(),
page.$eval('input', (input) => {
page.$eval('input', input => {
return (input as HTMLInputElement).click();
}),
]);
});
it('should fail when canceling file chooser twice', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input type=file>`);
const [fileChooser] = await Promise.all([
page.waitForFileChooser(),
page.$eval('input', (input) => {
page.$eval('input', input => {
return (input as HTMLElement).click();
}),
]);
@ -375,7 +375,7 @@ describe('input tests', function () {
describeFailsFirefox('FileChooser.isMultiple', () => {
it('should work for single file pick', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input type=file>`);
const [chooser] = await Promise.all([
@ -385,7 +385,7 @@ describe('input tests', function () {
expect(chooser.isMultiple()).toBe(false);
});
it('should work for "multiple"', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input multiple type=file>`);
const [chooser] = await Promise.all([
@ -395,7 +395,7 @@ describe('input tests', function () {
expect(chooser.isMultiple()).toBe(true);
});
it('should work for "webkitdirectory"', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent(`<input multiple webkitdirectory type=file>`);
const [chooser] = await Promise.all([

View File

@ -15,7 +15,7 @@
*/
import expect from 'expect';
import { JSHandle } from '../../lib/cjs/puppeteer/common/JSHandle.js';
import {JSHandle} from '../../lib/cjs/puppeteer/common/JSHandle.js';
import {
getTestState,
setupTestBrowserHooks,
@ -30,7 +30,7 @@ describe('JSHandle', function () {
describe('Page.evaluateHandle', function () {
it('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
const windowHandle = await page.evaluateHandle(() => {
return window;
@ -38,7 +38,7 @@ describe('JSHandle', function () {
expect(windowHandle).toBeTruthy();
});
it('should accept object handle as an argument', async () => {
const { page } = getTestState();
const {page} = getTestState();
const navigatorHandle = await page.evaluateHandle(() => {
return navigator;
@ -49,56 +49,56 @@ describe('JSHandle', function () {
expect(text).toContain('Mozilla');
});
it('should accept object handle to primitive types', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
return 5;
});
const isFive = await page.evaluate((e) => {
const isFive = await page.evaluate(e => {
return Object.is(e, 5);
}, aHandle);
expect(isFive).toBeTruthy();
});
it('should warn about recursive objects', async () => {
const { page } = getTestState();
const {page} = getTestState();
const test: { obj?: unknown } = {};
const test: {obj?: unknown} = {};
test.obj = test;
let error!: Error;
await page
.evaluateHandle(
(opts) => {
opts => {
return opts.elem;
},
// @ts-expect-error we are deliberately passing a bad type here (nested object)
{ test }
{test}
)
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error.message).toContain('Recursive objects are not allowed.');
});
it('should accept object handle to unserializable value', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
return Infinity;
});
expect(
await page.evaluate((e) => {
await page.evaluate(e => {
return Object.is(e, Infinity);
}, aHandle)
).toBe(true);
});
it('should use the same JS wrappers', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
(globalThis as any).FOO = 123;
return window;
});
expect(
await page.evaluate((e: { FOO: number }) => {
await page.evaluate((e: {FOO: number}) => {
return e.FOO;
}, aHandle)
).toBe(123);
@ -107,7 +107,7 @@ describe('JSHandle', function () {
describe('JSHandle.getProperty', function () {
it('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
return {
@ -121,7 +121,7 @@ describe('JSHandle', function () {
});
it('should return a JSHandle even if the property does not exist', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
return {
@ -138,17 +138,17 @@ describe('JSHandle', function () {
describe('JSHandle.jsonValue', function () {
it('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
return { foo: 'bar' };
return {foo: 'bar'};
});
const json = await aHandle.jsonValue<Record<string, string>>();
expect(json).toEqual({ foo: 'bar' });
expect(json).toEqual({foo: 'bar'});
});
it('works with jsonValues that are not objects', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
return ['a', 'b'];
@ -158,7 +158,7 @@ describe('JSHandle', function () {
});
it('works with jsonValues that are primitives', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
return 'foo';
@ -168,7 +168,7 @@ describe('JSHandle', function () {
});
itFailsFirefox('should not work with dates', async () => {
const { page } = getTestState();
const {page} = getTestState();
const dateHandle = await page.evaluateHandle(() => {
return new Date('2017-09-26T00:00:00.000Z');
@ -177,11 +177,11 @@ describe('JSHandle', function () {
expect(json).toEqual({});
});
it('should throw for circular objects', async () => {
const { page, isChrome } = getTestState();
const {page, isChrome} = getTestState();
const windowHandle = await page.evaluateHandle('window');
let error!: Error;
await windowHandle.jsonValue().catch((error_) => {
await windowHandle.jsonValue().catch(error_ => {
return (error = error_);
});
if (isChrome) {
@ -194,7 +194,7 @@ describe('JSHandle', function () {
describe('JSHandle.getProperties', function () {
it('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
return {
@ -207,7 +207,7 @@ describe('JSHandle', function () {
expect(await foo.jsonValue()).toBe('bar');
});
it('should return even non-own properties', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
class A {
@ -233,7 +233,7 @@ describe('JSHandle', function () {
describe('JSHandle.asElement', function () {
it('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
return document.body;
@ -242,7 +242,7 @@ describe('JSHandle', function () {
expect(element).toBeTruthy();
});
it('should return null for non-elements', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
return 2;
@ -251,7 +251,7 @@ describe('JSHandle', function () {
expect(element).toBeFalsy();
});
it('should return ElementHandle for TextNodes', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.setContent('<div>ee!</div>');
const aHandle = await page.evaluateHandle(() => {
@ -269,7 +269,7 @@ describe('JSHandle', function () {
describe('JSHandle.toString', function () {
it('should work for primitives', async () => {
const { page } = getTestState();
const {page} = getTestState();
const numberHandle = await page.evaluateHandle(() => {
return 2;
@ -281,7 +281,7 @@ describe('JSHandle', function () {
expect(stringHandle.toString()).toBe('JSHandle:a');
});
it('should work for complicated objects', async () => {
const { page } = getTestState();
const {page} = getTestState();
const aHandle = await page.evaluateHandle(() => {
return window;
@ -289,7 +289,7 @@ describe('JSHandle', function () {
expect(aHandle.toString()).toBe('JSHandle@object');
});
it('should work with different subtypes', async () => {
const { page } = getTestState();
const {page} = getTestState();
expect((await page.evaluateHandle('(function(){})')).toString()).toBe(
'JSHandle@function'
@ -348,7 +348,7 @@ describe('JSHandle', function () {
describe('JSHandle.clickablePoint', function () {
it('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.evaluate(() => {
document.body.style.padding = '0';
@ -358,7 +358,7 @@ describe('JSHandle', function () {
`;
});
await page.evaluate(async () => {
return new Promise((resolve) => {
return new Promise(resolve => {
return window.requestAnimationFrame(resolve);
});
});
@ -379,7 +379,7 @@ describe('JSHandle', function () {
});
it('should work for iframes', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.evaluate(() => {
document.body.style.padding = '10px';
document.body.style.margin = '10px';
@ -388,7 +388,7 @@ describe('JSHandle', function () {
`;
});
await page.evaluate(async () => {
return new Promise((resolve) => {
return new Promise(resolve => {
return window.requestAnimationFrame(resolve);
});
});
@ -412,7 +412,7 @@ describe('JSHandle', function () {
describe('JSHandle.click', function () {
itFailsFirefox('should work', async () => {
const { page } = getTestState();
const {page} = getTestState();
const clicks: [x: number, y: number][] = [];
@ -426,7 +426,7 @@ describe('JSHandle', function () {
document.body.innerHTML = `
<div style="cursor: pointer; width: 120px; height: 60px; margin: 30px; padding: 15px;"></div>
`;
document.body.addEventListener('click', (e) => {
document.body.addEventListener('click', e => {
(window as any).reportClick(e.clientX, e.clientY);
});
});

View File

@ -23,14 +23,14 @@ import {
setupTestPageAndContextHooks,
itFailsFirefox,
} from './mocha-utils.js';
import { KeyInput } from '../../lib/cjs/puppeteer/common/USKeyboardLayout.js';
import {KeyInput} from '../../lib/cjs/puppeteer/common/USKeyboardLayout.js';
describe('Keyboard', function () {
setupTestBrowserHooks();
setupTestPageAndContextHooks();
it('should type into a textarea', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.evaluate(() => {
const textarea = document.createElement('textarea');
@ -46,11 +46,11 @@ describe('Keyboard', function () {
).toBe(text);
});
itFailsFirefox('should press the metaKey', async () => {
const { page, isFirefox } = getTestState();
const {page, isFirefox} = getTestState();
await page.evaluate(() => {
(window as any).keyPromise = new Promise((resolve) => {
return document.addEventListener('keydown', (event) => {
(window as any).keyPromise = new Promise(resolve => {
return document.addEventListener('keydown', event => {
return resolve(event.key);
});
});
@ -61,7 +61,7 @@ describe('Keyboard', function () {
);
});
it('should move with the arrow keys', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
await page.type('textarea', 'Hello World!');
@ -92,7 +92,7 @@ describe('Keyboard', function () {
).toBe('Hello World!');
});
it('should send a character with ElementHandle.press', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
const textarea = (await page.$('textarea'))!;
@ -106,7 +106,7 @@ describe('Keyboard', function () {
await page.evaluate(() => {
return window.addEventListener(
'keydown',
(e) => {
e => {
return e.preventDefault();
},
true
@ -123,11 +123,11 @@ describe('Keyboard', function () {
itFailsFirefox(
'ElementHandle.press should support |text| option',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
const textarea = (await page.$('textarea'))!;
await textarea.press('a', { text: 'ё' });
await textarea.press('a', {text: 'ё'});
expect(
await page.evaluate(() => {
return document.querySelector('textarea')!.value;
@ -136,7 +136,7 @@ describe('Keyboard', function () {
}
);
itFailsFirefox('should send a character with sendCharacter', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
await page.focus('textarea');
@ -149,7 +149,7 @@ describe('Keyboard', function () {
await page.evaluate(() => {
return window.addEventListener(
'keydown',
(e) => {
e => {
return e.preventDefault();
},
true
@ -163,7 +163,7 @@ describe('Keyboard', function () {
).toBe('嗨a');
});
itFailsFirefox('should report shiftKey', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/keyboard.html');
const keyboard = page.keyboard;
@ -234,7 +234,7 @@ describe('Keyboard', function () {
}
});
it('should report multiple modifiers', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/keyboard.html');
const keyboard = page.keyboard;
@ -276,7 +276,7 @@ describe('Keyboard', function () {
).toBe('Keyup: Alt AltLeft 18 []');
});
it('should send proper codes while typing', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/keyboard.html');
await page.keyboard.type('!');
@ -305,7 +305,7 @@ describe('Keyboard', function () {
);
});
it('should send proper codes while typing with shift', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/keyboard.html');
const keyboard = page.keyboard;
@ -326,14 +326,14 @@ describe('Keyboard', function () {
await keyboard.up('Shift');
});
it('should not type canceled events', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
await page.focus('textarea');
await page.evaluate(() => {
window.addEventListener(
'keydown',
(event) => {
event => {
event.stopPropagation();
event.stopImmediatePropagation();
if (event.key === 'l') {
@ -354,14 +354,14 @@ describe('Keyboard', function () {
).toBe('He Wrd!');
});
itFailsFirefox('should specify repeat property', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
await page.focus('textarea');
await page.evaluate(() => {
return document.querySelector('textarea')!.addEventListener(
'keydown',
(e) => {
e => {
return ((globalThis as any).lastEvent = e);
},
true
@ -402,7 +402,7 @@ describe('Keyboard', function () {
).toBe(false);
});
itFailsFirefox('should type all kinds of characters', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
await page.focus('textarea');
@ -411,13 +411,13 @@ describe('Keyboard', function () {
expect(await page.evaluate('result')).toBe(text);
});
itFailsFirefox('should specify location', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
await page.evaluate(() => {
window.addEventListener(
'keydown',
(event) => {
event => {
return ((globalThis as any).keyLocation = event.location);
},
true
@ -438,41 +438,41 @@ describe('Keyboard', function () {
expect(await page.evaluate('keyLocation')).toBe(3);
});
it('should throw on unknown keys', async () => {
const { page } = getTestState();
const {page} = getTestState();
let error = await page.keyboard
// @ts-expect-error bad input
.press('NotARealKey')
.catch((error_) => {
.catch(error_ => {
return error_;
});
expect(error.message).toBe('Unknown key: "NotARealKey"');
// @ts-expect-error bad input
error = await page.keyboard.press('ё').catch((error_) => {
error = await page.keyboard.press('ё').catch(error_ => {
return error_;
});
expect(error && error.message).toBe('Unknown key: "ё"');
// @ts-expect-error bad input
error = await page.keyboard.press('😊').catch((error_) => {
error = await page.keyboard.press('😊').catch(error_ => {
return error_;
});
expect(error && error.message).toBe('Unknown key: "😊"');
});
itFailsFirefox('should type emoji', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
await page.type('textarea', '👹 Tokyo street Japan 🇯🇵');
expect(
await page.$eval('textarea', (textarea) => {
await page.$eval('textarea', textarea => {
return (textarea as HTMLInputElement).value;
})
).toBe('👹 Tokyo street Japan 🇯🇵');
});
itFailsFirefox('should type emoji into an iframe', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await utils.attachFrame(
@ -484,17 +484,17 @@ describe('Keyboard', function () {
const textarea = (await frame.$('textarea'))!;
await textarea.type('👹 Tokyo street Japan 🇯🇵');
expect(
await frame.$eval('textarea', (textarea) => {
await frame.$eval('textarea', textarea => {
return (textarea as HTMLInputElement).value;
})
).toBe('👹 Tokyo street Japan 🇯🇵');
});
itFailsFirefox('should press the meta key', async () => {
const { page, isFirefox } = getTestState();
const {page, isFirefox} = getTestState();
await page.evaluate(() => {
(globalThis as any).result = null;
document.addEventListener('keydown', (event) => {
document.addEventListener('keydown', event => {
(globalThis as any).result = [event.key, event.code, event.metaKey];
});
});

View File

@ -20,10 +20,10 @@ import os from 'os';
import path from 'path';
import rimraf from 'rimraf';
import sinon from 'sinon';
import { TLSSocket } from 'tls';
import { promisify } from 'util';
import { Page } from '../../lib/cjs/puppeteer/common/Page.js';
import { Product } from '../../lib/cjs/puppeteer/common/Product.js';
import {TLSSocket} from 'tls';
import {promisify} from 'util';
import {Page} from '../../lib/cjs/puppeteer/common/Page.js';
import {Product} from '../../lib/cjs/puppeteer/common/Product.js';
import {
getTestState,
itChromeOnly,
@ -50,7 +50,7 @@ describe('Launcher specs', function () {
describe('Puppeteer', function () {
describe('BrowserFetcher', function () {
it('should download and extract chrome linux binary', async () => {
const { server, puppeteer } = getTestState();
const {server, puppeteer} = getTestState();
const downloadsFolder = await mkdtempAsync(TMP_FOLDER);
const browserFetcher = puppeteer.createBrowserFetcher({
@ -91,7 +91,7 @@ describe('Launcher specs', function () {
await rmAsync(downloadsFolder);
});
it('should download and extract firefox linux binary', async () => {
const { server, puppeteer } = getTestState();
const {server, puppeteer} = getTestState();
const downloadsFolder = await mkdtempAsync(TMP_FOLDER);
const browserFetcher = puppeteer.createBrowserFetcher({
@ -139,7 +139,7 @@ describe('Launcher specs', function () {
describe('Browser.disconnect', function () {
it('should reject navigation when browser closes', async () => {
const { server, puppeteer, defaultBrowserOptions } = getTestState();
const {server, puppeteer, defaultBrowserOptions} = getTestState();
server.setRoute('/one-style.css', () => {});
const browser = await puppeteer.launch(defaultBrowserOptions);
const remote = await puppeteer.connect({
@ -147,8 +147,8 @@ describe('Launcher specs', function () {
});
const page = await remote.newPage();
const navigationPromise = page
.goto(server.PREFIX + '/one-style.html', { timeout: 60000 })
.catch((error_) => {
.goto(server.PREFIX + '/one-style.html', {timeout: 60000})
.catch(error_ => {
return error_;
});
await server.waitForRequest('/one-style.css');
@ -163,7 +163,7 @@ describe('Launcher specs', function () {
await browser.close();
});
it('should reject waitForSelector when browser closes', async () => {
const { server, puppeteer, defaultBrowserOptions } = getTestState();
const {server, puppeteer, defaultBrowserOptions} = getTestState();
server.setRoute('/empty.html', () => {});
const browser = await puppeteer.launch(defaultBrowserOptions);
@ -172,8 +172,8 @@ describe('Launcher specs', function () {
});
const page = await remote.newPage();
const watchdog = page
.waitForSelector('div', { timeout: 60000 })
.catch((error_) => {
.waitForSelector('div', {timeout: 60000})
.catch(error_ => {
return error_;
});
remote.disconnect();
@ -184,7 +184,7 @@ describe('Launcher specs', function () {
});
describe('Browser.close', function () {
it('should terminate network waiters', async () => {
const { server, puppeteer, defaultBrowserOptions } = getTestState();
const {server, puppeteer, defaultBrowserOptions} = getTestState();
const browser = await puppeteer.launch(defaultBrowserOptions);
const remote = await puppeteer.connect({
@ -192,10 +192,10 @@ describe('Launcher specs', function () {
});
const newPage = await remote.newPage();
const results = await Promise.all([
newPage.waitForRequest(server.EMPTY_PAGE).catch((error) => {
newPage.waitForRequest(server.EMPTY_PAGE).catch(error => {
return error;
}),
newPage.waitForResponse(server.EMPTY_PAGE).catch((error) => {
newPage.waitForResponse(server.EMPTY_PAGE).catch(error => {
return error;
}),
browser.close(),
@ -210,7 +210,7 @@ describe('Launcher specs', function () {
});
describe('Puppeteer.launch', function () {
it('should reject all promises when browser is closed', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const browser = await puppeteer.launch(defaultBrowserOptions);
const page = await browser.newPage();
let error!: Error;
@ -218,7 +218,7 @@ describe('Launcher specs', function () {
.evaluate(() => {
return new Promise(() => {});
})
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
await browser.close();
@ -226,22 +226,22 @@ describe('Launcher specs', function () {
expect(error.message).toContain('Protocol error');
});
it('should reject if executable path is invalid', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
let waitError!: Error;
const options = Object.assign({}, defaultBrowserOptions, {
executablePath: 'random-invalid-path',
});
await puppeteer.launch(options).catch((error) => {
await puppeteer.launch(options).catch(error => {
return (waitError = error);
});
expect(waitError.message).toContain('Failed to launch');
});
it('userDataDir option', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const userDataDir = await mkdtempAsync(TMP_FOLDER);
const options = Object.assign({ userDataDir }, defaultBrowserOptions);
const options = Object.assign({userDataDir}, defaultBrowserOptions);
const browser = await puppeteer.launch(options);
// Open a page to make sure its functional.
await browser.newPage();
@ -252,7 +252,7 @@ describe('Launcher specs', function () {
await rmAsync(userDataDir).catch(() => {});
});
itFirefoxOnly('userDataDir option restores preferences', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const userDataDir = await mkdtempAsync(TMP_FOLDER);
@ -260,7 +260,7 @@ describe('Launcher specs', function () {
const prefsJSContent = 'user_pref("browser.warnOnQuit", true)';
await writeFileAsync(prefsJSPath, prefsJSContent);
const options = Object.assign({ userDataDir }, defaultBrowserOptions);
const options = Object.assign({userDataDir}, defaultBrowserOptions);
const browser = await puppeteer.launch(options);
// Open a page to make sure its functional.
await browser.newPage();
@ -274,7 +274,7 @@ describe('Launcher specs', function () {
await rmAsync(userDataDir).catch(() => {});
});
it('userDataDir argument', async () => {
const { isChrome, puppeteer, defaultBrowserOptions } = getTestState();
const {isChrome, puppeteer, defaultBrowserOptions} = getTestState();
const userDataDir = await mkdtempAsync(TMP_FOLDER);
const options = Object.assign({}, defaultBrowserOptions);
@ -298,7 +298,7 @@ describe('Launcher specs', function () {
await rmAsync(userDataDir).catch(() => {});
});
itChromeOnly('userDataDir argument with non-existent dir', async () => {
const { isChrome, puppeteer, defaultBrowserOptions } = getTestState();
const {isChrome, puppeteer, defaultBrowserOptions} = getTestState();
const userDataDir = await mkdtempAsync(TMP_FOLDER);
await rmAsync(userDataDir);
@ -323,10 +323,10 @@ describe('Launcher specs', function () {
await rmAsync(userDataDir).catch(() => {});
});
it('userDataDir option should restore state', async () => {
const { server, puppeteer, defaultBrowserOptions } = getTestState();
const {server, puppeteer, defaultBrowserOptions} = getTestState();
const userDataDir = await mkdtempAsync(TMP_FOLDER);
const options = Object.assign({ userDataDir }, defaultBrowserOptions);
const options = Object.assign({userDataDir}, defaultBrowserOptions);
const browser = await puppeteer.launch(options);
const page = await browser.newPage();
await page.goto(server.EMPTY_PAGE);
@ -350,10 +350,10 @@ describe('Launcher specs', function () {
// This mysteriously fails on Windows on AppVeyor. See
// https://github.com/puppeteer/puppeteer/issues/4111
xit('userDataDir option should restore cookies', async () => {
const { server, puppeteer, defaultBrowserOptions } = getTestState();
const {server, puppeteer, defaultBrowserOptions} = getTestState();
const userDataDir = await mkdtempAsync(TMP_FOLDER);
const options = Object.assign({ userDataDir }, defaultBrowserOptions);
const options = Object.assign({userDataDir}, defaultBrowserOptions);
const browser = await puppeteer.launch(options);
const page = await browser.newPage();
await page.goto(server.EMPTY_PAGE);
@ -376,15 +376,15 @@ describe('Launcher specs', function () {
await rmAsync(userDataDir).catch(() => {});
});
it('should return the default arguments', async () => {
const { isChrome, isFirefox, puppeteer } = getTestState();
const {isChrome, isFirefox, puppeteer} = getTestState();
if (isChrome) {
expect(puppeteer.defaultArgs()).toContain('--no-first-run');
expect(puppeteer.defaultArgs()).toContain('--headless');
expect(puppeteer.defaultArgs({ headless: false })).not.toContain(
expect(puppeteer.defaultArgs({headless: false})).not.toContain(
'--headless'
);
expect(puppeteer.defaultArgs({ userDataDir: 'foo' })).toContain(
expect(puppeteer.defaultArgs({userDataDir: 'foo'})).toContain(
`--user-data-dir=${path.resolve('foo')}`
);
} else if (isFirefox) {
@ -395,30 +395,28 @@ describe('Launcher specs', function () {
} else {
expect(puppeteer.defaultArgs()).not.toContain('--foreground');
}
expect(puppeteer.defaultArgs({ headless: false })).not.toContain(
expect(puppeteer.defaultArgs({headless: false})).not.toContain(
'--headless'
);
expect(puppeteer.defaultArgs({ userDataDir: 'foo' })).toContain(
expect(puppeteer.defaultArgs({userDataDir: 'foo'})).toContain(
'--profile'
);
expect(puppeteer.defaultArgs({ userDataDir: 'foo' })).toContain(
'foo'
);
expect(puppeteer.defaultArgs({userDataDir: 'foo'})).toContain('foo');
} else {
expect(puppeteer.defaultArgs()).toContain('-headless');
expect(puppeteer.defaultArgs({ headless: false })).not.toContain(
expect(puppeteer.defaultArgs({headless: false})).not.toContain(
'-headless'
);
expect(puppeteer.defaultArgs({ userDataDir: 'foo' })).toContain(
expect(puppeteer.defaultArgs({userDataDir: 'foo'})).toContain(
'-profile'
);
expect(puppeteer.defaultArgs({ userDataDir: 'foo' })).toContain(
expect(puppeteer.defaultArgs({userDataDir: 'foo'})).toContain(
path.resolve('foo')
);
}
});
it('should report the correct product', async () => {
const { isChrome, isFirefox, puppeteer } = getTestState();
const {isChrome, isFirefox, puppeteer} = getTestState();
if (isChrome) {
expect(puppeteer.product).toBe('chrome');
} else if (isFirefox) {
@ -426,7 +424,7 @@ describe('Launcher specs', function () {
}
});
it('should work with no default arguments', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const options = Object.assign({}, defaultBrowserOptions);
options.ignoreDefaultArgs = true;
const browser = await puppeteer.launch(options);
@ -438,7 +436,7 @@ describe('Launcher specs', function () {
itChromeOnly(
'should filter out ignored default arguments in Chrome',
async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
// Make sure we launch with `--enable-automation` by default.
const defaultArgs = puppeteer.defaultArgs();
const browser = await puppeteer.launch(
@ -460,7 +458,7 @@ describe('Launcher specs', function () {
itFirefoxOnly(
'should filter out ignored default argument in Firefox',
async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const defaultArgs = puppeteer.defaultArgs();
const browser = await puppeteer.launch(
@ -479,9 +477,9 @@ describe('Launcher specs', function () {
}
);
it('should have default URL when launching browser', async function () {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const browser = await puppeteer.launch(defaultBrowserOptions);
const pages = (await browser.pages()).map((page) => {
const pages = (await browser.pages()).map(page => {
return page.url();
});
expect(pages).toEqual(['about:blank']);
@ -490,7 +488,7 @@ describe('Launcher specs', function () {
itFailsFirefox(
'should have custom URL when launching browser',
async () => {
const { server, puppeteer, defaultBrowserOptions } = getTestState();
const {server, puppeteer, defaultBrowserOptions} = getTestState();
const options = Object.assign({}, defaultBrowserOptions);
options.args = [server.EMPTY_PAGE].concat(options.args || []);
@ -506,18 +504,18 @@ describe('Launcher specs', function () {
}
);
it('should pass the timeout parameter to browser.waitForTarget', async () => {
const { puppeteer, defaultBrowserOptions } = getTestState();
const {puppeteer, defaultBrowserOptions} = getTestState();
const options = Object.assign({}, defaultBrowserOptions, {
timeout: 1,
});
let error!: Error;
await puppeteer.launch(options).catch((error_) => {
await puppeteer.launch(options).catch(error_ => {
return (error = error_);
});
expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);
});
it('should set the default viewport', async () => {
const { puppeteer, defaultBrowserOptions } = getTestState();
const {puppeteer, defaultBrowserOptions} = getTestState();
const options = Object.assign({}, defaultBrowserOptions, {
defaultViewport: {
width: 456,
@ -531,7 +529,7 @@ describe('Launcher specs', function () {
await browser.close();
});
it('should disable the default viewport', async () => {
const { puppeteer, defaultBrowserOptions } = getTestState();
const {puppeteer, defaultBrowserOptions} = getTestState();
const options = Object.assign({}, defaultBrowserOptions, {
defaultViewport: null,
});
@ -541,7 +539,7 @@ describe('Launcher specs', function () {
await browser.close();
});
it('should take fullPage screenshots when defaultViewport is null', async () => {
const { server, puppeteer, defaultBrowserOptions } = getTestState();
const {server, puppeteer, defaultBrowserOptions} = getTestState();
const options = Object.assign({}, defaultBrowserOptions, {
defaultViewport: null,
@ -556,7 +554,7 @@ describe('Launcher specs', function () {
await browser.close();
});
it('should set the debugging port', async () => {
const { puppeteer, defaultBrowserOptions } = getTestState();
const {puppeteer, defaultBrowserOptions} = getTestState();
const options = Object.assign({}, defaultBrowserOptions, {
defaultViewport: null,
@ -568,7 +566,7 @@ describe('Launcher specs', function () {
expect(url.port).toBe('9999');
});
it('should not allow setting debuggingPort and pipe', async () => {
const { puppeteer, defaultBrowserOptions } = getTestState();
const {puppeteer, defaultBrowserOptions} = getTestState();
const options = Object.assign({}, defaultBrowserOptions, {
defaultViewport: null,
@ -577,7 +575,7 @@ describe('Launcher specs', function () {
});
let error!: Error;
await puppeteer.launch(options).catch((error_) => {
await puppeteer.launch(options).catch(error_ => {
return (error = error_);
});
expect(error.message).toContain('either pipe or debugging port');
@ -585,7 +583,7 @@ describe('Launcher specs', function () {
itChromeOnly(
'should launch Chrome properly with --no-startup-window and waitForInitialPage=false',
async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const options = {
waitForInitialPage: false,
// This is needed to prevent Puppeteer from adding an initial blank page.
@ -606,12 +604,12 @@ describe('Launcher specs', function () {
let productName!: Product;
before(async () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
productName = puppeteer._productName!;
});
after(async () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
// @ts-expect-error launcher is a private property that users can't
// touch, but for testing purposes we need to reset it.
puppeteer._lazyLauncher = undefined;
@ -619,8 +617,8 @@ describe('Launcher specs', function () {
});
itOnlyRegularInstall('should be able to launch Chrome', async () => {
const { puppeteer } = getTestState();
const browser = await puppeteer.launch({ product: 'chrome' });
const {puppeteer} = getTestState();
const browser = await puppeteer.launch({product: 'chrome'});
const userAgent = await browser.userAgent();
await browser.close();
expect(userAgent).toContain('Chrome');
@ -629,7 +627,7 @@ describe('Launcher specs', function () {
itOnlyRegularInstall(
'falls back to launching chrome if there is an unknown product but logs a warning',
async () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const consoleStub = sinon.stub(console, 'warn');
const browser = await puppeteer.launch({
// @ts-expect-error purposeful bad input
@ -649,8 +647,8 @@ describe('Launcher specs', function () {
'should be able to launch Firefox',
async function () {
this.timeout(FIREFOX_TIMEOUT);
const { puppeteer } = getTestState();
const browser = await puppeteer.launch({ product: 'firefox' });
const {puppeteer} = getTestState();
const browser = await puppeteer.launch({product: 'firefox'});
const userAgent = await browser.userAgent();
await browser.close();
expect(userAgent).toContain('Firefox');
@ -660,7 +658,7 @@ describe('Launcher specs', function () {
describe('Puppeteer.connect', function () {
it('should be able to connect multiple times to the same browser', async () => {
const { puppeteer, defaultBrowserOptions } = getTestState();
const {puppeteer, defaultBrowserOptions} = getTestState();
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
const otherBrowser = await puppeteer.connect({
@ -683,7 +681,7 @@ describe('Launcher specs', function () {
await originalBrowser.close();
});
it('should be able to close remote browser', async () => {
const { defaultBrowserOptions, puppeteer } = getTestState();
const {defaultBrowserOptions, puppeteer} = getTestState();
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
const remoteBrowser = await puppeteer.connect({
@ -695,8 +693,7 @@ describe('Launcher specs', function () {
]);
});
it('should support ignoreHTTPSErrors option', async () => {
const { httpsServer, puppeteer, defaultBrowserOptions } =
getTestState();
const {httpsServer, puppeteer, defaultBrowserOptions} = getTestState();
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
const browserWSEndpoint = originalBrowser.wsEndpoint();
@ -709,7 +706,7 @@ describe('Launcher specs', function () {
let error!: Error;
const [serverRequest, response] = await Promise.all([
httpsServer.waitForRequest('/empty.html'),
page.goto(httpsServer.EMPTY_PAGE).catch((error_) => {
page.goto(httpsServer.EMPTY_PAGE).catch(error_ => {
return (error = error_);
}),
]);
@ -725,7 +722,7 @@ describe('Launcher specs', function () {
});
// @see https://github.com/puppeteer/puppeteer/issues/4197
itFailsFirefox('should support targetFilter option', async () => {
const { server, puppeteer, defaultBrowserOptions } = getTestState();
const {server, puppeteer, defaultBrowserOptions} = getTestState();
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
const browserWSEndpoint = originalBrowser.wsEndpoint();
@ -761,7 +758,7 @@ describe('Launcher specs', function () {
itFailsFirefox(
'should be able to reconnect to a disconnected browser',
async () => {
const { server, puppeteer, defaultBrowserOptions } = getTestState();
const {server, puppeteer, defaultBrowserOptions} = getTestState();
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
const browserWSEndpoint = originalBrowser.wsEndpoint();
@ -769,9 +766,9 @@ describe('Launcher specs', function () {
await page.goto(server.PREFIX + '/frames/nested-frames.html');
originalBrowser.disconnect();
const browser = await puppeteer.connect({ browserWSEndpoint });
const browser = await puppeteer.connect({browserWSEndpoint});
const pages = await browser.pages();
const restoredPage = pages.find((page) => {
const restoredPage = pages.find(page => {
return page.url() === server.PREFIX + '/frames/nested-frames.html';
})!;
expect(utils.dumpFrames(restoredPage.mainFrame())).toEqual([
@ -793,15 +790,15 @@ describe('Launcher specs', function () {
itFailsFirefox(
'should be able to connect to the same page simultaneously',
async () => {
const { puppeteer, defaultBrowserOptions } = getTestState();
const {puppeteer, defaultBrowserOptions} = getTestState();
const browserOne = await puppeteer.launch(defaultBrowserOptions);
const browserTwo = await puppeteer.connect({
browserWSEndpoint: browserOne.wsEndpoint(),
});
const [page1, page2] = await Promise.all([
new Promise<Page>((x) => {
return browserOne.once('targetcreated', (target) => {
new Promise<Page>(x => {
return browserOne.once('targetcreated', target => {
return x(target.page());
});
}),
@ -821,16 +818,16 @@ describe('Launcher specs', function () {
}
);
it('should be able to reconnect', async () => {
const { puppeteer, server, defaultBrowserOptions } = getTestState();
const {puppeteer, server, defaultBrowserOptions} = getTestState();
const browserOne = await puppeteer.launch(defaultBrowserOptions);
const browserWSEndpoint = browserOne.wsEndpoint();
const pageOne = await browserOne.newPage();
await pageOne.goto(server.EMPTY_PAGE);
browserOne.disconnect();
const browserTwo = await puppeteer.connect({ browserWSEndpoint });
const browserTwo = await puppeteer.connect({browserWSEndpoint});
const pages = await browserTwo.pages();
const pageTwo = pages.find((page) => {
const pageTwo = pages.find(page => {
return page.url() === server.EMPTY_PAGE;
})!;
await pageTwo.reload();
@ -843,14 +840,14 @@ describe('Launcher specs', function () {
});
describe('Puppeteer.executablePath', function () {
itOnlyRegularInstall('should work', async () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const executablePath = puppeteer.executablePath();
expect(fs.existsSync(executablePath)).toBe(true);
expect(fs.realpathSync(executablePath)).toBe(executablePath);
});
it('returns executablePath for channel', () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const executablePath = puppeteer.executablePath('chrome');
expect(executablePath).toBeTruthy();
@ -870,7 +867,7 @@ describe('Launcher specs', function () {
});
it('its value is returned', async () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const executablePath = puppeteer.executablePath();
@ -881,7 +878,7 @@ describe('Launcher specs', function () {
describe('when the product is chrome, platform is not darwin, and arch is arm64', () => {
describe('and the executable exists', () => {
itChromeOnly('returns /usr/bin/chromium-browser', async () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const osPlatformStub = sinon.stub(os, 'platform').returns('linux');
const osArchStub = sinon.stub(os, 'arch').returns('arm64');
const fsExistsStub = sinon.stub(fs, 'existsSync');
@ -910,7 +907,7 @@ describe('Launcher specs', function () {
});
it('its value is returned', async () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const executablePath = puppeteer.executablePath();
@ -922,7 +919,7 @@ describe('Launcher specs', function () {
itChromeOnly(
'does not return /usr/bin/chromium-browser',
async () => {
const { puppeteer } = getTestState();
const {puppeteer} = getTestState();
const osPlatformStub = sinon
.stub(os, 'platform')
.returns('linux');
@ -946,7 +943,7 @@ describe('Launcher specs', function () {
describe('Browser target events', function () {
itFailsFirefox('should work', async () => {
const { server, puppeteer, defaultBrowserOptions } = getTestState();
const {server, puppeteer, defaultBrowserOptions} = getTestState();
const browser = await puppeteer.launch(defaultBrowserOptions);
const events: string[] = [];
@ -969,11 +966,11 @@ describe('Launcher specs', function () {
describe('Browser.Events.disconnected', function () {
it('should be emitted when: browser gets closed, disconnected or underlying websocket gets closed', async () => {
const { puppeteer, defaultBrowserOptions } = getTestState();
const {puppeteer, defaultBrowserOptions} = getTestState();
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
const browserWSEndpoint = originalBrowser.wsEndpoint();
const remoteBrowser1 = await puppeteer.connect({ browserWSEndpoint });
const remoteBrowser2 = await puppeteer.connect({ browserWSEndpoint });
const remoteBrowser1 = await puppeteer.connect({browserWSEndpoint});
const remoteBrowser2 = await puppeteer.connect({browserWSEndpoint});
let disconnectedOriginal = 0;
let disconnectedRemote1 = 0;

View File

@ -25,15 +25,15 @@ import {
Browser,
BrowserContext,
} from '../../lib/cjs/puppeteer/common/Browser.js';
import { Page } from '../../lib/cjs/puppeteer/common/Page.js';
import { isErrorLike } from '../../lib/cjs/puppeteer/common/util.js';
import {Page} from '../../lib/cjs/puppeteer/common/Page.js';
import {isErrorLike} from '../../lib/cjs/puppeteer/common/util.js';
import {
PuppeteerLaunchOptions,
PuppeteerNode,
} from '../../lib/cjs/puppeteer/node/Puppeteer.js';
import puppeteer from '../../lib/cjs/puppeteer/puppeteer.js';
import { TestServer } from '../../utils/testserver/lib/index.js';
import { extendExpectWithToBeGolden } from './utils.js';
import {TestServer} from '../../utils/testserver/lib/index.js';
import {extendExpectWithToBeGolden} from './utils.js';
const setupServer = async () => {
const assetsPath = path.join(__dirname, '../assets');
@ -55,7 +55,7 @@ const setupServer = async () => {
httpsServer.CROSS_PROCESS_PREFIX = `https://127.0.0.1:${httpsPort}`;
httpsServer.EMPTY_PAGE = `https://localhost:${httpsPort}/empty.html`;
return { server, httpsServer };
return {server, httpsServer};
};
export const getTestState = (): PuppeteerTestState => {
@ -259,7 +259,7 @@ console.log(
}`
);
process.on('unhandledRejection', (reason) => {
process.on('unhandledRejection', reason => {
throw reason;
});
@ -291,7 +291,7 @@ export const setupTestPageAndContextHooks = (): void => {
export const mochaHooks = {
beforeAll: [
async (): Promise<void> => {
const { server, httpsServer } = await setupServer();
const {server, httpsServer} = await setupServer();
state.puppeteer = puppeteer;
state.defaultBrowserOptions = defaultBrowserOptions;
@ -328,10 +328,10 @@ export const expectCookieEquals = (
cookies: Protocol.Network.Cookie[],
expectedCookies: Array<Partial<Protocol.Network.Cookie>>
): void => {
const { isChrome } = getTestState();
const {isChrome} = getTestState();
if (!isChrome) {
// Only keep standard properties when testing on a browser other than Chrome.
expectedCookies = expectedCookies.map((cookie) => {
expectedCookies = expectedCookies.map(cookie => {
return {
domain: cookie.domain,
expires: cookie.expires,
@ -359,7 +359,7 @@ export const shortWaitForArrayToHaveAtLeastNElements = async (
if (data.length >= minLength) {
break;
}
await new Promise((resolve) => {
await new Promise(resolve => {
return setTimeout(resolve, timeout);
});
}

View File

@ -21,7 +21,7 @@ import {
setupTestPageAndContextHooks,
itFailsFirefox,
} from './mocha-utils.js';
import { KeyInput } from '../../lib/cjs/puppeteer/common/USKeyboardLayout.js';
import {KeyInput} from '../../lib/cjs/puppeteer/common/USKeyboardLayout.js';
interface Dimensions {
x: number;
@ -44,11 +44,11 @@ describe('Mouse', function () {
setupTestBrowserHooks();
setupTestPageAndContextHooks();
it('should click the document', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.evaluate(() => {
(globalThis as any).clickPromise = new Promise((resolve) => {
document.addEventListener('click', (event) => {
(globalThis as any).clickPromise = new Promise(resolve => {
document.addEventListener('click', event => {
resolve({
type: event.type,
detail: event.detail,
@ -72,10 +72,10 @@ describe('Mouse', function () {
expect(event.button).toBe(0);
});
it('should resize the textarea', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
const { x, y, width, height } = await page.evaluate<() => Dimensions>(
const {x, y, width, height} = await page.evaluate<() => Dimensions>(
dimensions
);
const mouse = page.mouse;
@ -88,7 +88,7 @@ describe('Mouse', function () {
expect(newDimensions.height).toBe(Math.round(height + 104));
});
it('should select the text with mouse', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/textarea.html');
await page.focus('textarea');
@ -102,7 +102,7 @@ describe('Mouse', function () {
await page.evaluate(() => {
return (document.querySelector('textarea')!.scrollTop = 0);
});
const { x, y } = await page.evaluate(dimensions);
const {x, y} = await page.evaluate(dimensions);
await page.mouse.move(x + 2, y + 2);
await page.mouse.down();
await page.mouse.move(100, 100);
@ -118,7 +118,7 @@ describe('Mouse', function () {
).toBe(text);
});
itFailsFirefox('should trigger hover state', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/scrollable.html');
await page.hover('#button-6');
@ -143,7 +143,7 @@ describe('Mouse', function () {
itFailsFirefox(
'should trigger hover state with removed window.Node',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/scrollable.html');
await page.evaluate(() => {
@ -159,13 +159,13 @@ describe('Mouse', function () {
}
);
it('should set modifier keys on click', async () => {
const { page, server, isFirefox } = getTestState();
const {page, server, isFirefox} = getTestState();
await page.goto(server.PREFIX + '/input/scrollable.html');
await page.evaluate(() => {
return document.querySelector('#button-3')!.addEventListener(
'mousedown',
(e) => {
e => {
return ((globalThis as any).lastEvent = e);
},
true
@ -205,7 +205,7 @@ describe('Mouse', function () {
}
});
itFailsFirefox('should send mouse wheel events', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/input/wheel.html');
const elem = (await page.$('div'))!;
@ -220,7 +220,7 @@ describe('Mouse', function () {
boundingBoxBefore.y + boundingBoxBefore.height / 2
);
await page.mouse.wheel({ deltaY: -100 });
await page.mouse.wheel({deltaY: -100});
const boundingBoxAfter = await elem.boundingBox();
expect(boundingBoxAfter).toMatchObject({
width: 230,
@ -228,16 +228,16 @@ describe('Mouse', function () {
});
});
itFailsFirefox('should tween mouse movement', async () => {
const { page } = getTestState();
const {page} = getTestState();
await page.mouse.move(100, 100);
await page.evaluate(() => {
(globalThis as any).result = [];
document.addEventListener('mousemove', (event) => {
document.addEventListener('mousemove', event => {
(globalThis as any).result.push([event.clientX, event.clientY]);
});
});
await page.mouse.move(200, 300, { steps: 5 });
await page.mouse.move(200, 300, {steps: 5});
expect(await page.evaluate('result')).toEqual([
[120, 140],
[140, 180],
@ -248,19 +248,19 @@ describe('Mouse', function () {
});
// @see https://crbug.com/929806
it('should work with mobile viewports and cross process navigations', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setViewport({ width: 360, height: 640, isMobile: true });
await page.setViewport({width: 360, height: 640, isMobile: true});
await page.goto(server.CROSS_PROCESS_PREFIX + '/mobile.html');
await page.evaluate(() => {
document.addEventListener('click', (event) => {
(globalThis as any).result = { x: event.clientX, y: event.clientY };
document.addEventListener('click', event => {
(globalThis as any).result = {x: event.clientX, y: event.clientY};
});
});
await page.mouse.click(30, 40);
expect(await page.evaluate('result')).toEqual({ x: 30, y: 40 });
expect(await page.evaluate('result')).toEqual({x: 30, y: 40});
});
});

View File

@ -24,21 +24,21 @@ import {
describeFailsFirefox,
} from './mocha-utils.js';
import os from 'os';
import { ServerResponse } from 'http';
import { HTTPRequest } from '../../lib/cjs/puppeteer/common/HTTPRequest.js';
import {ServerResponse} from 'http';
import {HTTPRequest} from '../../lib/cjs/puppeteer/common/HTTPRequest.js';
describe('navigation', function () {
setupTestBrowserHooks();
setupTestPageAndContextHooks();
describe('Page.goto', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
expect(page.url()).toBe(server.EMPTY_PAGE);
});
it('should work with anchor navigation', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
expect(page.url()).toBe(server.EMPTY_PAGE);
@ -48,7 +48,7 @@ describe('navigation', function () {
expect(page.url()).toBe(server.EMPTY_PAGE + '#bar');
});
it('should work with redirects', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
server.setRedirect('/redirect/1.html', '/redirect/2.html');
server.setRedirect('/redirect/2.html', '/empty.html');
@ -56,19 +56,19 @@ describe('navigation', function () {
expect(page.url()).toBe(server.EMPTY_PAGE);
});
it('should navigate to about:blank', async () => {
const { page } = getTestState();
const {page} = getTestState();
const response = await page.goto('about:blank');
expect(response).toBe(null);
});
it('should return response when page changes its URL after load', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const response = (await page.goto(server.PREFIX + '/historyapi.html'))!;
expect(response.status()).toBe(200);
});
itFailsFirefox('should work with subframes return 204', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
server.setRoute('/frames/frame.html', (_req, res) => {
res.statusCode = 204;
@ -77,20 +77,20 @@ describe('navigation', function () {
let error!: Error;
await page
.goto(server.PREFIX + '/frames/one-frame.html')
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
expect(error).toBeUndefined();
});
itFailsFirefox('should fail when server returns 204', async () => {
const { page, server, isChrome } = getTestState();
const {page, server, isChrome} = getTestState();
server.setRoute('/empty.html', (_req, res) => {
res.statusCode = 204;
res.end();
});
let error!: Error;
await page.goto(server.EMPTY_PAGE).catch((error_) => {
await page.goto(server.EMPTY_PAGE).catch(error_ => {
return (error = error_);
});
expect(error).not.toBe(null);
@ -101,7 +101,7 @@ describe('navigation', function () {
}
});
it('should navigate to empty page with domcontentloaded', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const response = await page.goto(server.EMPTY_PAGE, {
waitUntil: 'domcontentloaded',
@ -109,7 +109,7 @@ describe('navigation', function () {
expect(response!.status()).toBe(200);
});
it('should work when page calls history API in beforeunload', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => {
@ -127,7 +127,7 @@ describe('navigation', function () {
itFailsFirefox(
'should navigate to empty page with networkidle0',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const response = await page.goto(server.EMPTY_PAGE, {
waitUntil: 'networkidle0',
@ -138,7 +138,7 @@ describe('navigation', function () {
itFailsFirefox(
'should navigate to empty page with networkidle2',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const response = await page.goto(server.EMPTY_PAGE, {
waitUntil: 'networkidle2',
@ -147,10 +147,10 @@ describe('navigation', function () {
}
);
itFailsFirefox('should fail when navigating to bad url', async () => {
const { page, isChrome } = getTestState();
const {page, isChrome} = getTestState();
let error!: Error;
await page.goto('asdfasdf').catch((error_) => {
await page.goto('asdfasdf').catch(error_ => {
return (error = error_);
});
if (isChrome) {
@ -171,7 +171,7 @@ describe('navigation', function () {
: 'net::ERR_CERT_AUTHORITY_INVALID';
itFailsFirefox('should fail when navigating to bad SSL', async () => {
const { page, httpsServer, isChrome } = getTestState();
const {page, httpsServer, isChrome} = getTestState();
// Make sure that network events do not emit 'undefined'.
// @see https://crbug.com/750469
@ -187,7 +187,7 @@ describe('navigation', function () {
});
let error!: Error;
await page.goto(httpsServer.EMPTY_PAGE).catch((error_) => {
await page.goto(httpsServer.EMPTY_PAGE).catch(error_ => {
return (error = error_);
});
if (isChrome) {
@ -201,16 +201,14 @@ describe('navigation', function () {
expect(requests[1]!).toBe('requestfailed');
});
it('should fail when navigating to bad SSL after redirects', async () => {
const { page, server, httpsServer, isChrome } = getTestState();
const {page, server, httpsServer, isChrome} = getTestState();
server.setRedirect('/redirect/1.html', '/redirect/2.html');
server.setRedirect('/redirect/2.html', '/empty.html');
let error!: Error;
await page
.goto(httpsServer.PREFIX + '/redirect/1.html')
.catch((error_) => {
return (error = error_);
});
await page.goto(httpsServer.PREFIX + '/redirect/1.html').catch(error_ => {
return (error = error_);
});
if (isChrome) {
expect(error.message).toContain(EXPECTED_SSL_CERT_MESSAGE);
} else {
@ -218,13 +216,13 @@ describe('navigation', function () {
}
});
it('should throw if networkidle is passed as an option', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
let error!: Error;
await page
// @ts-expect-error purposefully passing an old option
.goto(server.EMPTY_PAGE, { waitUntil: 'networkidle' })
.catch((error_) => {
.goto(server.EMPTY_PAGE, {waitUntil: 'networkidle'})
.catch(error_ => {
return (error = error_);
});
expect(error.message).toContain(
@ -232,12 +230,12 @@ describe('navigation', function () {
);
});
it('should fail when main resources failed to load', async () => {
const { page, isChrome } = getTestState();
const {page, isChrome} = getTestState();
let error!: Error;
await page
.goto('http://localhost:44123/non-existing-url')
.catch((error_) => {
.catch(error_ => {
return (error = error_);
});
if (isChrome) {
@ -247,61 +245,61 @@ describe('navigation', function () {
}
});
it('should fail when exceeding maximum navigation timeout', async () => {
const { page, server, puppeteer } = getTestState();
const {page, server, puppeteer} = getTestState();
// Hang for request to the empty.html
server.setRoute('/empty.html', () => {});
let error!: Error;
await page
.goto(server.PREFIX + '/empty.html', { timeout: 1 })
.catch((error_) => {
.goto(server.PREFIX + '/empty.html', {timeout: 1})
.catch(error_ => {
return (error = error_);
});
expect(error.message).toContain('Navigation timeout of 1 ms exceeded');
expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);
});
it('should fail when exceeding default maximum navigation timeout', async () => {
const { page, server, puppeteer } = getTestState();
const {page, server, puppeteer} = getTestState();
// Hang for request to the empty.html
server.setRoute('/empty.html', () => {});
let error!: Error;
page.setDefaultNavigationTimeout(1);
await page.goto(server.PREFIX + '/empty.html').catch((error_) => {
await page.goto(server.PREFIX + '/empty.html').catch(error_ => {
return (error = error_);
});
expect(error.message).toContain('Navigation timeout of 1 ms exceeded');
expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);
});
it('should fail when exceeding default maximum timeout', async () => {
const { page, server, puppeteer } = getTestState();
const {page, server, puppeteer} = getTestState();
// Hang for request to the empty.html
server.setRoute('/empty.html', () => {});
let error!: Error;
page.setDefaultTimeout(1);
await page.goto(server.PREFIX + '/empty.html').catch((error_) => {
await page.goto(server.PREFIX + '/empty.html').catch(error_ => {
return (error = error_);
});
expect(error.message).toContain('Navigation timeout of 1 ms exceeded');
expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);
});
it('should prioritize default navigation timeout over default timeout', async () => {
const { page, server, puppeteer } = getTestState();
const {page, server, puppeteer} = getTestState();
// Hang for request to the empty.html
server.setRoute('/empty.html', () => {});
let error!: Error;
page.setDefaultTimeout(0);
page.setDefaultNavigationTimeout(1);
await page.goto(server.PREFIX + '/empty.html').catch((error_) => {
await page.goto(server.PREFIX + '/empty.html').catch(error_ => {
return (error = error_);
});
expect(error.message).toContain('Navigation timeout of 1 ms exceeded');
expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);
});
it('should disable timeout when its set to 0', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
let error!: Error;
let loaded = false;
@ -309,34 +307,34 @@ describe('navigation', function () {
return (loaded = true);
});
await page
.goto(server.PREFIX + '/grid.html', { timeout: 0, waitUntil: ['load'] })
.catch((error_) => {
.goto(server.PREFIX + '/grid.html', {timeout: 0, waitUntil: ['load']})
.catch(error_ => {
return (error = error_);
});
expect(error).toBeUndefined();
expect(loaded).toBe(true);
});
it('should work when navigating to valid url', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const response = (await page.goto(server.EMPTY_PAGE))!;
expect(response.ok()).toBe(true);
});
itFailsFirefox('should work when navigating to data url', async () => {
const { page } = getTestState();
const {page} = getTestState();
const response = (await page.goto('data:text/html,hello'))!;
expect(response.ok()).toBe(true);
});
it('should work when navigating to 404', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const response = (await page.goto(server.PREFIX + '/not-found'))!;
expect(response.ok()).toBe(false);
expect(response.status()).toBe(404);
});
it('should return last response in redirect chain', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
server.setRedirect('/redirect/1.html', '/redirect/2.html');
server.setRedirect('/redirect/2.html', '/redirect/3.html');
@ -348,7 +346,7 @@ describe('navigation', function () {
itFailsFirefox(
'should wait for network idle to succeed navigation',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
let responses: ServerResponse[] = [];
// Hold on to a bunch of requests without answering.
@ -388,7 +386,7 @@ describe('navigation', function () {
});
// Wait for the page's 'load' event.
await new Promise((fulfill) => {
await new Promise(fulfill => {
return page.once('load', fulfill);
});
expect(navigationFinished).toBe(false);
@ -425,10 +423,10 @@ describe('navigation', function () {
}
);
it('should not leak listeners during navigation', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
let warning = null;
const warningHandler: NodeJS.WarningListener = (w) => {
const warningHandler: NodeJS.WarningListener = w => {
return (warning = w);
};
process.on('warning', warningHandler);
@ -439,10 +437,10 @@ describe('navigation', function () {
expect(warning).toBe(null);
});
it('should not leak listeners during bad navigation', async () => {
const { page } = getTestState();
const {page} = getTestState();
let warning = null;
const warningHandler: NodeJS.WarningListener = (w) => {
const warningHandler: NodeJS.WarningListener = w => {
return (warning = w);
};
process.on('warning', warningHandler);
@ -455,10 +453,10 @@ describe('navigation', function () {
expect(warning).toBe(null);
});
it('should not leak listeners during navigation of 11 pages', async () => {
const { context, server } = getTestState();
const {context, server} = getTestState();
let warning = null;
const warningHandler: NodeJS.WarningListener = (w) => {
const warningHandler: NodeJS.WarningListener = w => {
return (warning = w);
};
process.on('warning', warningHandler);
@ -475,10 +473,10 @@ describe('navigation', function () {
itFailsFirefox(
'should navigate to dataURL and fire dataURL requests',
async () => {
const { page } = getTestState();
const {page} = getTestState();
const requests: HTTPRequest[] = [];
page.on('request', (request) => {
page.on('request', request => {
return !utils.isFavicon(request) && requests.push(request);
});
const dataURL = 'data:text/html,<div>yo</div>';
@ -491,10 +489,10 @@ describe('navigation', function () {
itFailsFirefox(
'should navigate to URL with hash and fire requests without hash',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const requests: HTTPRequest[] = [];
page.on('request', (request) => {
page.on('request', request => {
return !utils.isFavicon(request) && requests.push(request);
});
const response = (await page.goto(server.EMPTY_PAGE + '#hash'))!;
@ -505,14 +503,14 @@ describe('navigation', function () {
}
);
it('should work with self requesting page', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const response = (await page.goto(server.PREFIX + '/self-request.html'))!;
expect(response.status()).toBe(200);
expect(response.url()).toContain('self-request.html');
});
it('should fail when navigating and show the url at the error message', async () => {
const { page, httpsServer } = getTestState();
const {page, httpsServer} = getTestState();
const url = httpsServer.PREFIX + '/redirect/1.html';
let error!: Error;
@ -524,7 +522,7 @@ describe('navigation', function () {
expect(error.message).toContain(url);
});
itFailsFirefox('should send referer', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
const [request1, request2] = await Promise.all([
server.waitForRequest('/grid.html'),
@ -541,7 +539,7 @@ describe('navigation', function () {
describe('Page.waitForNavigation', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
const [response] = await Promise.all([
@ -554,7 +552,7 @@ describe('navigation', function () {
expect(response!.url()).toContain('grid.html');
});
it('should work with both domcontentloaded and load', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
let response!: ServerResponse;
server.setRoute('/one-style.css', (_req, res) => {
@ -582,7 +580,7 @@ describe('navigation', function () {
await navigationPromise;
});
it('should work with clicking on anchor links', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setContent(`<a href='#foobar'>foobar</a>`);
@ -594,7 +592,7 @@ describe('navigation', function () {
expect(page.url()).toBe(server.EMPTY_PAGE + '#foobar');
});
itFailsFirefox('should work with history.pushState()', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setContent(`
@ -611,7 +609,7 @@ describe('navigation', function () {
expect(page.url()).toBe(server.PREFIX + '/wow.html');
});
itFailsFirefox('should work with history.replaceState()', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setContent(`
@ -630,7 +628,7 @@ describe('navigation', function () {
itFailsFirefox(
'should work with DOM history.back()/history.forward()',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.setContent(`
@ -661,15 +659,15 @@ describe('navigation', function () {
itFailsFirefox(
'should work when subframe issues window.stop()',
async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
server.setRoute('/frames/style.css', () => {});
const navigationPromise = page.goto(
server.PREFIX + '/frames/one-frame.html'
);
const frame = await utils.waitEvent(page, 'frameattached');
await new Promise<void>((fulfill) => {
page.on('framenavigated', (f) => {
await new Promise<void>(fulfill => {
page.on('framenavigated', f => {
if (f === frame) {
fulfill();
}
@ -687,7 +685,7 @@ describe('navigation', function () {
describe('Page.goBack', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.goto(server.PREFIX + '/grid.html');
@ -704,7 +702,7 @@ describe('navigation', function () {
expect(response).toBe(null);
});
itFailsFirefox('should work with HistoryAPI', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => {
@ -724,7 +722,7 @@ describe('navigation', function () {
describeFailsFirefox('Frame.goto', function () {
it('should navigate subframes', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/frames/one-frame.html');
expect(page.frames()[0]!.url()).toContain('/frames/one-frame.html');
@ -735,7 +733,7 @@ describe('navigation', function () {
expect(response.frame()).toBe(page.frames()[1]!);
});
it('should reject when frame detaches', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/frames/one-frame.html');
@ -743,19 +741,19 @@ describe('navigation', function () {
const navigationPromise = page
.frames()[1]!
.goto(server.EMPTY_PAGE)
.catch((error_) => {
.catch(error_ => {
return error_;
});
await server.waitForRequest('/empty.html');
await page.$eval('iframe', (frame) => {
await page.$eval('iframe', frame => {
return frame.remove();
});
const error = await navigationPromise;
expect(error.message).toBe('Navigating frame was detached');
});
it('should return matching responses', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
// Disable cache: otherwise, chromium will cache similar requests.
await page.setCacheEnabled(false);
@ -789,7 +787,7 @@ describe('navigation', function () {
describeFailsFirefox('Frame.waitForNavigation', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/frames/one-frame.html');
const frame = page.frames()[1]!;
@ -805,14 +803,14 @@ describe('navigation', function () {
expect(page.url()).toContain('/frames/one-frame.html');
});
it('should fail when frame detaches', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.PREFIX + '/frames/one-frame.html');
const frame = page.frames()[1]!;
server.setRoute('/empty.html', () => {});
let error!: Error;
const navigationPromise = frame.waitForNavigation().catch((error_) => {
const navigationPromise = frame.waitForNavigation().catch(error_ => {
return (error = error_);
});
await Promise.all([
@ -821,7 +819,7 @@ describe('navigation', function () {
return ((window as any).location = '/empty.html');
}),
]);
await page.$eval('iframe', (frame) => {
await page.$eval('iframe', frame => {
return frame.remove();
});
await navigationPromise;
@ -831,7 +829,7 @@ describe('navigation', function () {
describe('Page.reload', function () {
it('should work', async () => {
const { page, server } = getTestState();
const {page, server} = getTestState();
await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => {

Some files were not shown because too many files have changed in this diff Show More