mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
chore: use Google's TS style guide's format config (#8542)
This commit is contained in:
parent
3744c2f584
commit
84712cbc28
@ -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
1
.prettierrc.cjs
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('gts/.prettierrc.json');
|
14
README.md
14
README.md
@ -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:
|
||||
|
@ -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};
|
||||
|
@ -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};
|
||||
|
213
docs/api.md
213
docs/api.md
@ -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({
|
||||
|
@ -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();
|
||||
})();
|
||||
|
@ -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}`;
|
||||
});
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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(() => {
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
})();
|
||||
|
@ -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();
|
||||
})();
|
||||
|
@ -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}`;
|
||||
});
|
||||
|
@ -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",
|
||||
|
@ -1,5 +0,0 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'es5',
|
||||
singleQuote: true,
|
||||
};
|
@ -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';
|
||||
|
||||
|
@ -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')
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
})
|
||||
);
|
||||
|
@ -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) {
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { JSHandle } from './JSHandle.js';
|
||||
import {JSHandle} from './JSHandle.js';
|
||||
|
||||
/**
|
||||
* @public
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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([
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { JSHandle, ElementHandle } from './JSHandle.js';
|
||||
import {JSHandle, ElementHandle} from './JSHandle.js';
|
||||
|
||||
/**
|
||||
* @public
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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,
|
||||
});
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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',
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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('/');
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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},
|
||||
};
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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
2
src/compat.d.ts
vendored
@ -1,3 +1,3 @@
|
||||
declare const puppeteerDirname: string;
|
||||
|
||||
export { puppeteerDirname };
|
||||
export {puppeteerDirname};
|
||||
|
@ -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)));
|
||||
|
@ -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';
|
||||
|
@ -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}`);
|
||||
}
|
||||
|
@ -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);
|
||||
}),
|
||||
];
|
||||
|
@ -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.
|
||||
|
@ -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};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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', () => {
|
||||
|
@ -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;
|
||||
|
@ -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', () => {
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { initializePuppeteer } from './initializePuppeteer.js';
|
||||
import {initializePuppeteer} from './initializePuppeteer.js';
|
||||
|
||||
const puppeteer = initializePuppeteer('puppeteer-core');
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { initializePuppeteer } from './initializePuppeteer.js';
|
||||
import {initializePuppeteer} from './initializePuppeteer.js';
|
||||
|
||||
const puppeteer = initializePuppeteer('puppeteer');
|
||||
|
||||
|
@ -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"}
|
||||
]
|
||||
}
|
||||
|
@ -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"}
|
||||
]
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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';
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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'}],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -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']);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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');
|
||||
|
@ -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;
|
||||
|
@ -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'
|
||||
);
|
||||
|
@ -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');
|
||||
|
@ -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(), [
|
||||
{
|
||||
|
@ -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(() => {
|
||||
|
@ -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!'
|
||||
|
@ -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('');
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}),
|
||||
];
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
})
|
||||
);
|
||||
|
@ -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',
|
||||
]);
|
||||
|
@ -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>`);
|
||||
|
@ -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([
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
@ -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];
|
||||
});
|
||||
});
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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});
|
||||
});
|
||||
});
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user