feat: detect Firefox in connect() automatically (#8718)
This PR implements automatic detection of the Firefox product when the `.connect()` method is used. This partially undoes the breaking change in https://github.com/puppeteer/puppeteer/pull/8520 but it's also a breaking change on its own since we don't accept an explicit product name anymore (it does not look like it was used anyway).
This commit is contained in:
parent
fae4fa5915
commit
2abd772c9c
@ -18,5 +18,4 @@ export interface ConnectOptions extends BrowserConnectOptions
|
|||||||
| --------------------------------------------------------------------- | --------- | --------------------------------------------------------- | ----------------- |
|
| --------------------------------------------------------------------- | --------- | --------------------------------------------------------- | ----------------- |
|
||||||
| [browserURL?](./puppeteer.connectoptions.browserurl.md) | | string | <i>(Optional)</i> |
|
| [browserURL?](./puppeteer.connectoptions.browserurl.md) | | string | <i>(Optional)</i> |
|
||||||
| [browserWSEndpoint?](./puppeteer.connectoptions.browserwsendpoint.md) | | string | <i>(Optional)</i> |
|
| [browserWSEndpoint?](./puppeteer.connectoptions.browserwsendpoint.md) | | string | <i>(Optional)</i> |
|
||||||
| [product?](./puppeteer.connectoptions.product.md) | | [Product](./puppeteer.product.md) | <i>(Optional)</i> |
|
|
||||||
| [transport?](./puppeteer.connectoptions.transport.md) | | [ConnectionTransport](./puppeteer.connectiontransport.md) | <i>(Optional)</i> |
|
| [transport?](./puppeteer.connectoptions.transport.md) | | [ConnectionTransport](./puppeteer.connectiontransport.md) | <i>(Optional)</i> |
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
sidebar_label: ConnectOptions.product
|
|
||||||
---
|
|
||||||
|
|
||||||
# ConnectOptions.product property
|
|
||||||
|
|
||||||
**Signature:**
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
interface ConnectOptions {
|
|
||||||
product?: Product;
|
|
||||||
}
|
|
||||||
```
|
|
@ -26,7 +26,6 @@ import {Connection} from './Connection.js';
|
|||||||
import {ConnectionTransport} from './ConnectionTransport.js';
|
import {ConnectionTransport} from './ConnectionTransport.js';
|
||||||
import {getFetch} from './fetch.js';
|
import {getFetch} from './fetch.js';
|
||||||
import {Viewport} from './PuppeteerViewport.js';
|
import {Viewport} from './PuppeteerViewport.js';
|
||||||
import {Product} from './Product.js';
|
|
||||||
/**
|
/**
|
||||||
* Generic browser options that can be passed when launching any browser or when
|
* Generic browser options that can be passed when launching any browser or when
|
||||||
* connecting to an existing browser instance.
|
* connecting to an existing browser instance.
|
||||||
@ -75,7 +74,6 @@ export async function _connectToBrowser(
|
|||||||
browserWSEndpoint?: string;
|
browserWSEndpoint?: string;
|
||||||
browserURL?: string;
|
browserURL?: string;
|
||||||
transport?: ConnectionTransport;
|
transport?: ConnectionTransport;
|
||||||
product?: Product;
|
|
||||||
}
|
}
|
||||||
): Promise<Browser> {
|
): Promise<Browser> {
|
||||||
const {
|
const {
|
||||||
@ -87,7 +85,6 @@ export async function _connectToBrowser(
|
|||||||
slowMo = 0,
|
slowMo = 0,
|
||||||
targetFilter,
|
targetFilter,
|
||||||
_isPageTarget: isPageTarget,
|
_isPageTarget: isPageTarget,
|
||||||
product,
|
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
@ -111,6 +108,11 @@ export async function _connectToBrowser(
|
|||||||
await WebSocketClass.create(connectionURL);
|
await WebSocketClass.create(connectionURL);
|
||||||
connection = new Connection(connectionURL, connectionTransport, slowMo);
|
connection = new Connection(connectionURL, connectionTransport, slowMo);
|
||||||
}
|
}
|
||||||
|
const version = await connection.send('Browser.getVersion');
|
||||||
|
|
||||||
|
const product = version.product.toLowerCase().includes('firefox')
|
||||||
|
? 'firefox'
|
||||||
|
: 'chrome';
|
||||||
|
|
||||||
const {browserContextIds} = await connection.send(
|
const {browserContextIds} = await connection.send(
|
||||||
'Target.getBrowserContexts'
|
'Target.getBrowserContexts'
|
||||||
|
@ -19,7 +19,6 @@ import {ConnectionTransport} from './ConnectionTransport.js';
|
|||||||
import {devices} from './DeviceDescriptors.js';
|
import {devices} from './DeviceDescriptors.js';
|
||||||
import {errors} from './Errors.js';
|
import {errors} from './Errors.js';
|
||||||
import {networkConditions} from './NetworkConditions.js';
|
import {networkConditions} from './NetworkConditions.js';
|
||||||
import {Product} from './Product.js';
|
|
||||||
import {
|
import {
|
||||||
clearCustomQueryHandlers,
|
clearCustomQueryHandlers,
|
||||||
CustomQueryHandler,
|
CustomQueryHandler,
|
||||||
@ -43,7 +42,6 @@ export interface ConnectOptions extends BrowserConnectOptions {
|
|||||||
browserWSEndpoint?: string;
|
browserWSEndpoint?: string;
|
||||||
browserURL?: string;
|
browserURL?: string;
|
||||||
transport?: ConnectionTransport;
|
transport?: ConnectionTransport;
|
||||||
product?: Product;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,9 +110,6 @@ export class PuppeteerNode extends Puppeteer {
|
|||||||
* @returns Promise which resolves to browser instance.
|
* @returns Promise which resolves to browser instance.
|
||||||
*/
|
*/
|
||||||
override connect(options: ConnectOptions): Promise<Browser> {
|
override connect(options: ConnectOptions): Promise<Browser> {
|
||||||
if (options.product) {
|
|
||||||
this._productName = options.product;
|
|
||||||
}
|
|
||||||
return super.connect(options);
|
return super.connect(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,12 +63,11 @@ describe('Browser specs', function () {
|
|||||||
expect(process!.pid).toBeGreaterThan(0);
|
expect(process!.pid).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
it('should not return child_process for remote browser', async () => {
|
it('should not return child_process for remote browser', async () => {
|
||||||
const {browser, puppeteer, isFirefox} = getTestState();
|
const {browser, puppeteer} = getTestState();
|
||||||
|
|
||||||
const browserWSEndpoint = browser.wsEndpoint();
|
const browserWSEndpoint = browser.wsEndpoint();
|
||||||
const remoteBrowser = await puppeteer.connect({
|
const remoteBrowser = await puppeteer.connect({
|
||||||
browserWSEndpoint,
|
browserWSEndpoint,
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
expect(remoteBrowser.process()).toBe(null);
|
expect(remoteBrowser.process()).toBe(null);
|
||||||
remoteBrowser.disconnect();
|
remoteBrowser.disconnect();
|
||||||
@ -77,12 +76,11 @@ describe('Browser specs', function () {
|
|||||||
|
|
||||||
describe('Browser.isConnected', () => {
|
describe('Browser.isConnected', () => {
|
||||||
it('should set the browser connected state', async () => {
|
it('should set the browser connected state', async () => {
|
||||||
const {browser, puppeteer, isFirefox} = getTestState();
|
const {browser, puppeteer} = getTestState();
|
||||||
|
|
||||||
const browserWSEndpoint = browser.wsEndpoint();
|
const browserWSEndpoint = browser.wsEndpoint();
|
||||||
const newBrowser = await puppeteer.connect({
|
const newBrowser = await puppeteer.connect({
|
||||||
browserWSEndpoint,
|
browserWSEndpoint,
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
expect(newBrowser.isConnected()).toBe(true);
|
expect(newBrowser.isConnected()).toBe(true);
|
||||||
newBrowser.disconnect();
|
newBrowser.disconnect();
|
||||||
|
@ -68,8 +68,7 @@ describe('Fixtures', function () {
|
|||||||
expect(dumpioData).toContain('DevTools listening on ws://');
|
expect(dumpioData).toContain('DevTools listening on ws://');
|
||||||
});
|
});
|
||||||
it('should close the browser when the node process closes', async () => {
|
it('should close the browser when the node process closes', async () => {
|
||||||
const {defaultBrowserOptions, puppeteerPath, puppeteer, isFirefox} =
|
const {defaultBrowserOptions, puppeteerPath, puppeteer} = getTestState();
|
||||||
getTestState();
|
|
||||||
|
|
||||||
const {spawn, execSync} = await import('child_process');
|
const {spawn, execSync} = await import('child_process');
|
||||||
const options = Object.assign({}, defaultBrowserOptions, {
|
const options = Object.assign({}, defaultBrowserOptions, {
|
||||||
@ -94,7 +93,6 @@ describe('Fixtures', function () {
|
|||||||
});
|
});
|
||||||
const browser = await puppeteer.connect({
|
const browser = await puppeteer.connect({
|
||||||
browserWSEndpoint: await wsEndPointPromise,
|
browserWSEndpoint: await wsEndPointPromise,
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
const promises = [
|
const promises = [
|
||||||
new Promise(resolve => {
|
new Promise(resolve => {
|
||||||
|
@ -139,13 +139,11 @@ describe('Launcher specs', function () {
|
|||||||
|
|
||||||
describe('Browser.disconnect', function () {
|
describe('Browser.disconnect', function () {
|
||||||
it('should reject navigation when browser closes', async () => {
|
it('should reject navigation when browser closes', async () => {
|
||||||
const {server, puppeteer, defaultBrowserOptions, isFirefox} =
|
const {server, puppeteer, defaultBrowserOptions} = getTestState();
|
||||||
getTestState();
|
|
||||||
server.setRoute('/one-style.css', () => {});
|
server.setRoute('/one-style.css', () => {});
|
||||||
const browser = await puppeteer.launch(defaultBrowserOptions);
|
const browser = await puppeteer.launch(defaultBrowserOptions);
|
||||||
const remote = await puppeteer.connect({
|
const remote = await puppeteer.connect({
|
||||||
browserWSEndpoint: browser.wsEndpoint(),
|
browserWSEndpoint: browser.wsEndpoint(),
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
const page = await remote.newPage();
|
const page = await remote.newPage();
|
||||||
const navigationPromise = page
|
const navigationPromise = page
|
||||||
@ -165,14 +163,12 @@ describe('Launcher specs', function () {
|
|||||||
await browser.close();
|
await browser.close();
|
||||||
});
|
});
|
||||||
it('should reject waitForSelector when browser closes', async () => {
|
it('should reject waitForSelector when browser closes', async () => {
|
||||||
const {server, puppeteer, defaultBrowserOptions, isFirefox} =
|
const {server, puppeteer, defaultBrowserOptions} = getTestState();
|
||||||
getTestState();
|
|
||||||
|
|
||||||
server.setRoute('/empty.html', () => {});
|
server.setRoute('/empty.html', () => {});
|
||||||
const browser = await puppeteer.launch(defaultBrowserOptions);
|
const browser = await puppeteer.launch(defaultBrowserOptions);
|
||||||
const remote = await puppeteer.connect({
|
const remote = await puppeteer.connect({
|
||||||
browserWSEndpoint: browser.wsEndpoint(),
|
browserWSEndpoint: browser.wsEndpoint(),
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
const page = await remote.newPage();
|
const page = await remote.newPage();
|
||||||
const watchdog = page
|
const watchdog = page
|
||||||
@ -188,13 +184,11 @@ describe('Launcher specs', function () {
|
|||||||
});
|
});
|
||||||
describe('Browser.close', function () {
|
describe('Browser.close', function () {
|
||||||
it('should terminate network waiters', async () => {
|
it('should terminate network waiters', async () => {
|
||||||
const {server, puppeteer, defaultBrowserOptions, isFirefox} =
|
const {server, puppeteer, defaultBrowserOptions} = getTestState();
|
||||||
getTestState();
|
|
||||||
|
|
||||||
const browser = await puppeteer.launch(defaultBrowserOptions);
|
const browser = await puppeteer.launch(defaultBrowserOptions);
|
||||||
const remote = await puppeteer.connect({
|
const remote = await puppeteer.connect({
|
||||||
browserWSEndpoint: browser.wsEndpoint(),
|
browserWSEndpoint: browser.wsEndpoint(),
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
const newPage = await remote.newPage();
|
const newPage = await remote.newPage();
|
||||||
const results = await Promise.all([
|
const results = await Promise.all([
|
||||||
@ -671,12 +665,11 @@ describe('Launcher specs', function () {
|
|||||||
|
|
||||||
describe('Puppeteer.connect', function () {
|
describe('Puppeteer.connect', function () {
|
||||||
it('should be able to connect multiple times to the same browser', async () => {
|
it('should be able to connect multiple times to the same browser', async () => {
|
||||||
const {puppeteer, defaultBrowserOptions, isFirefox} = getTestState();
|
const {puppeteer, defaultBrowserOptions} = getTestState();
|
||||||
|
|
||||||
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
||||||
const otherBrowser = await puppeteer.connect({
|
const otherBrowser = await puppeteer.connect({
|
||||||
browserWSEndpoint: originalBrowser.wsEndpoint(),
|
browserWSEndpoint: originalBrowser.wsEndpoint(),
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
const page = await otherBrowser.newPage();
|
const page = await otherBrowser.newPage();
|
||||||
expect(
|
expect(
|
||||||
@ -695,12 +688,11 @@ describe('Launcher specs', function () {
|
|||||||
await originalBrowser.close();
|
await originalBrowser.close();
|
||||||
});
|
});
|
||||||
it('should be able to close remote browser', async () => {
|
it('should be able to close remote browser', async () => {
|
||||||
const {defaultBrowserOptions, puppeteer, isFirefox} = getTestState();
|
const {defaultBrowserOptions, puppeteer} = getTestState();
|
||||||
|
|
||||||
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
||||||
const remoteBrowser = await puppeteer.connect({
|
const remoteBrowser = await puppeteer.connect({
|
||||||
browserWSEndpoint: originalBrowser.wsEndpoint(),
|
browserWSEndpoint: originalBrowser.wsEndpoint(),
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
utils.waitEvent(originalBrowser, 'disconnected'),
|
utils.waitEvent(originalBrowser, 'disconnected'),
|
||||||
@ -708,8 +700,7 @@ describe('Launcher specs', function () {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
it('should support ignoreHTTPSErrors option', async () => {
|
it('should support ignoreHTTPSErrors option', async () => {
|
||||||
const {httpsServer, puppeteer, defaultBrowserOptions, isFirefox} =
|
const {httpsServer, puppeteer, defaultBrowserOptions} = getTestState();
|
||||||
getTestState();
|
|
||||||
|
|
||||||
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
||||||
const browserWSEndpoint = originalBrowser.wsEndpoint();
|
const browserWSEndpoint = originalBrowser.wsEndpoint();
|
||||||
@ -717,7 +708,6 @@ describe('Launcher specs', function () {
|
|||||||
const browser = await puppeteer.connect({
|
const browser = await puppeteer.connect({
|
||||||
browserWSEndpoint,
|
browserWSEndpoint,
|
||||||
ignoreHTTPSErrors: true,
|
ignoreHTTPSErrors: true,
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
let error!: Error;
|
let error!: Error;
|
||||||
@ -739,8 +729,7 @@ describe('Launcher specs', function () {
|
|||||||
});
|
});
|
||||||
// @see https://github.com/puppeteer/puppeteer/issues/4197
|
// @see https://github.com/puppeteer/puppeteer/issues/4197
|
||||||
itFailsFirefox('should support targetFilter option', async () => {
|
itFailsFirefox('should support targetFilter option', async () => {
|
||||||
const {server, puppeteer, defaultBrowserOptions, isFirefox} =
|
const {server, puppeteer, defaultBrowserOptions} = getTestState();
|
||||||
getTestState();
|
|
||||||
|
|
||||||
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
||||||
const browserWSEndpoint = originalBrowser.wsEndpoint();
|
const browserWSEndpoint = originalBrowser.wsEndpoint();
|
||||||
@ -753,7 +742,6 @@ describe('Launcher specs', function () {
|
|||||||
|
|
||||||
const browser = await puppeteer.connect({
|
const browser = await puppeteer.connect({
|
||||||
browserWSEndpoint,
|
browserWSEndpoint,
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
targetFilter: (targetInfo: Protocol.Target.TargetInfo) => {
|
targetFilter: (targetInfo: Protocol.Target.TargetInfo) => {
|
||||||
return !targetInfo.url?.includes('should-be-ignored');
|
return !targetInfo.url?.includes('should-be-ignored');
|
||||||
},
|
},
|
||||||
@ -837,8 +825,7 @@ describe('Launcher specs', function () {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
it('should be able to reconnect', async () => {
|
it('should be able to reconnect', async () => {
|
||||||
const {puppeteer, server, defaultBrowserOptions, isFirefox} =
|
const {puppeteer, server, defaultBrowserOptions} = getTestState();
|
||||||
getTestState();
|
|
||||||
const browserOne = await puppeteer.launch(defaultBrowserOptions);
|
const browserOne = await puppeteer.launch(defaultBrowserOptions);
|
||||||
const browserWSEndpoint = browserOne.wsEndpoint();
|
const browserWSEndpoint = browserOne.wsEndpoint();
|
||||||
const pageOne = await browserOne.newPage();
|
const pageOne = await browserOne.newPage();
|
||||||
@ -847,7 +834,6 @@ describe('Launcher specs', function () {
|
|||||||
|
|
||||||
const browserTwo = await puppeteer.connect({
|
const browserTwo = await puppeteer.connect({
|
||||||
browserWSEndpoint,
|
browserWSEndpoint,
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
const pages = await browserTwo.pages();
|
const pages = await browserTwo.pages();
|
||||||
const pageTwo = pages.find(page => {
|
const pageTwo = pages.find(page => {
|
||||||
@ -991,16 +977,14 @@ describe('Launcher specs', function () {
|
|||||||
itFailsFirefox(
|
itFailsFirefox(
|
||||||
'should be emitted when: browser gets closed, disconnected or underlying websocket gets closed',
|
'should be emitted when: browser gets closed, disconnected or underlying websocket gets closed',
|
||||||
async () => {
|
async () => {
|
||||||
const {puppeteer, defaultBrowserOptions, isFirefox} = getTestState();
|
const {puppeteer, defaultBrowserOptions} = getTestState();
|
||||||
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
||||||
const browserWSEndpoint = originalBrowser.wsEndpoint();
|
const browserWSEndpoint = originalBrowser.wsEndpoint();
|
||||||
const remoteBrowser1 = await puppeteer.connect({
|
const remoteBrowser1 = await puppeteer.connect({
|
||||||
browserWSEndpoint,
|
browserWSEndpoint,
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
const remoteBrowser2 = await puppeteer.connect({
|
const remoteBrowser2 = await puppeteer.connect({
|
||||||
browserWSEndpoint,
|
browserWSEndpoint,
|
||||||
product: isFirefox ? 'firefox' : 'chrome',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let disconnectedOriginal = 0;
|
let disconnectedOriginal = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user