chore: cleanup puppeteer.connect({browserURL}) (#3766)
This patch: - renames `browserUrl` into `browserURL` - cleans up some code - adds tests for error handling References #3537
This commit is contained in:
parent
15af75f9a2
commit
d346cb57b4
@ -445,7 +445,7 @@ puppeteer.launch().then(async browser => {
|
|||||||
#### puppeteer.connect(options)
|
#### puppeteer.connect(options)
|
||||||
- `options` <[Object]>
|
- `options` <[Object]>
|
||||||
- `browserWSEndpoint` <?[string]> a [browser websocket endpoint](#browserwsendpoint) to connect to.
|
- `browserWSEndpoint` <?[string]> a [browser websocket endpoint](#browserwsendpoint) to connect to.
|
||||||
- `browserUrl` <?[string]> a browser url to connect to, in format `http://${host}:${port}`. Use interchangeably with `browserWSEndpoint` to let Puppeteer fetch it from [metadata endpoint](https://chromedevtools.github.io/devtools-protocol/#how-do-i-access-the-browser-target).
|
- `browserURL` <?[string]> a browser url to connect to, in format `http://${host}:${port}`. Use interchangeably with `browserWSEndpoint` to let Puppeteer fetch it from [metadata endpoint](https://chromedevtools.github.io/devtools-protocol/#how-do-i-access-the-browser-target).
|
||||||
- `ignoreHTTPSErrors` <[boolean]> Whether to ignore HTTPS errors during navigation. Defaults to `false`.
|
- `ignoreHTTPSErrors` <[boolean]> Whether to ignore HTTPS errors during navigation. Defaults to `false`.
|
||||||
- `defaultViewport` <?[Object]> Sets a consistent viewport for each page. Defaults to an 800x600 viewport. `null` disables the default viewport.
|
- `defaultViewport` <?[Object]> Sets a consistent viewport for each page. Defaults to an 800x600 viewport. `null` disables the default viewport.
|
||||||
- `width` <[number]> page width in pixels.
|
- `width` <[number]> page width in pixels.
|
||||||
|
@ -24,7 +24,7 @@ const {Connection} = require('./Connection');
|
|||||||
const {Browser} = require('./Browser');
|
const {Browser} = require('./Browser');
|
||||||
const readline = require('readline');
|
const readline = require('readline');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const {helper, debugError} = require('./helper');
|
const {helper, assert, debugError} = require('./helper');
|
||||||
const {TimeoutError} = require('./Errors');
|
const {TimeoutError} = require('./Errors');
|
||||||
const WebSocketTransport = require('./WebSocketTransport');
|
const WebSocketTransport = require('./WebSocketTransport');
|
||||||
const PipeTransport = require('./PipeTransport');
|
const PipeTransport = require('./PipeTransport');
|
||||||
@ -278,33 +278,33 @@ class Launcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {!(Launcher.BrowserOptions & {browserWSEndpoint?: string, browserUrl?: string, transport?: !Puppeteer.ConnectionTransport})} options
|
* @param {!(Launcher.BrowserOptions & {browserWSEndpoint?: string, browserURL?: string, transport?: !Puppeteer.ConnectionTransport})} options
|
||||||
* @return {!Promise<!Browser>}
|
* @return {!Promise<!Browser>}
|
||||||
*/
|
*/
|
||||||
async connect(options) {
|
async connect(options) {
|
||||||
const {
|
const {
|
||||||
browserWSEndpoint,
|
browserWSEndpoint,
|
||||||
browserUrl,
|
browserURL,
|
||||||
ignoreHTTPSErrors = false,
|
ignoreHTTPSErrors = false,
|
||||||
defaultViewport = {width: 800, height: 600},
|
defaultViewport = {width: 800, height: 600},
|
||||||
transport,
|
transport,
|
||||||
slowMo = 0,
|
slowMo = 0,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
let connectionUrl;
|
assert(Number(!!browserWSEndpoint) + Number(!!browserURL) + Number(!!transport) === 1, 'Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect');
|
||||||
let connectionTransport;
|
|
||||||
|
|
||||||
if (browserWSEndpoint)
|
let connection = null;
|
||||||
connectionUrl = browserWSEndpoint;
|
if (transport) {
|
||||||
else if (!browserWSEndpoint && browserUrl)
|
connection = new Connection('', transport, slowMo);
|
||||||
connectionUrl = await getWSEndpoint(browserUrl);
|
} else if (browserWSEndpoint) {
|
||||||
|
const connectionTransport = await WebSocketTransport.create(browserWSEndpoint);
|
||||||
|
connection = new Connection(browserWSEndpoint, connectionTransport, slowMo);
|
||||||
|
} else if (browserURL) {
|
||||||
|
const connectionURL = await getWSEndpoint(browserURL);
|
||||||
|
const connectionTransport = await WebSocketTransport.create(connectionURL);
|
||||||
|
connection = new Connection(connectionURL, connectionTransport, slowMo);
|
||||||
|
}
|
||||||
|
|
||||||
if (transport)
|
|
||||||
connectionTransport = transport;
|
|
||||||
else
|
|
||||||
connectionTransport = await WebSocketTransport.create(connectionUrl);
|
|
||||||
|
|
||||||
const connection = new Connection(connectionUrl, connectionTransport, slowMo);
|
|
||||||
const {browserContextIds} = await connection.send('Target.getBrowserContexts');
|
const {browserContextIds} = await connection.send('Target.getBrowserContexts');
|
||||||
return Browser.create(connection, browserContextIds, ignoreHTTPSErrors, defaultViewport, null, () => connection.send('Browser.close').catch(debugError));
|
return Browser.create(connection, browserContextIds, ignoreHTTPSErrors, defaultViewport, null, () => connection.send('Browser.close').catch(debugError));
|
||||||
}
|
}
|
||||||
@ -393,45 +393,35 @@ function waitForWSEndpoint(chromeProcess, timeout, preferredRevision) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} browserUrl
|
* @param {string} browserURL
|
||||||
* @return {!Promise<string>}
|
* @return {!Promise<string>}
|
||||||
*/
|
*/
|
||||||
function getWSEndpoint(browserUrl) {
|
function getWSEndpoint(browserURL) {
|
||||||
let resolve, reject;
|
let resolve, reject;
|
||||||
const endpointUrl = URL.resolve(browserUrl, '/json/version');
|
|
||||||
const requestOptions = Object.assign(URL.parse(endpointUrl), { method: 'GET' });
|
|
||||||
const promise = new Promise((res, rej) => { resolve = res; reject = rej; });
|
const promise = new Promise((res, rej) => { resolve = res; reject = rej; });
|
||||||
|
|
||||||
function handleRequestEnd(data) {
|
const endpointURL = URL.resolve(browserURL, '/json/version');
|
||||||
try {
|
const requestOptions = Object.assign(URL.parse(endpointURL), { method: 'GET' });
|
||||||
const {webSocketDebuggerUrl} = JSON.parse(data);
|
|
||||||
resolve(webSocketDebuggerUrl);
|
|
||||||
} catch (e) {
|
|
||||||
handleRequestError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleRequestError(err) {
|
|
||||||
reject(new Error(`Failed to fetch browser webSocket url from ${endpointUrl}: ${err}`));
|
|
||||||
}
|
|
||||||
|
|
||||||
const request = http.request(requestOptions, res => {
|
const request = http.request(requestOptions, res => {
|
||||||
let data = '';
|
let data = '';
|
||||||
if (res.statusCode !== 200) {
|
if (res.statusCode !== 200) {
|
||||||
// consume response data to free up memory
|
// Consume response data to free up memory.
|
||||||
res.resume();
|
res.resume();
|
||||||
handleRequestError(res.statusCode);
|
reject(new Error('HTTP ' + res.statusCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res.setEncoding('utf8');
|
res.setEncoding('utf8');
|
||||||
res.on('data', chunk => data += chunk);
|
res.on('data', chunk => data += chunk);
|
||||||
res.on('end', () => handleRequestEnd(data));
|
res.on('end', () => resolve(JSON.parse(data).webSocketDebuggerUrl));
|
||||||
});
|
});
|
||||||
|
|
||||||
request.on('error', handleRequestError);
|
request.on('error', reject);
|
||||||
request.end();
|
request.end();
|
||||||
|
|
||||||
return promise;
|
return promise.catch(e => {
|
||||||
|
e.message = `Failed to fetch browser webSocket url from ${endpointURL}: ` + e.message;
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,7 +37,7 @@ module.exports = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {!(Launcher.BrowserOptions & {browserWSEndpoint?: string, browserUrl?: string, transport?: !Puppeteer.ConnectionTransport})} options
|
* @param {!(Launcher.BrowserOptions & {browserWSEndpoint?: string, browserURL?: string, transport?: !Puppeteer.ConnectionTransport})} options
|
||||||
* @return {!Promise<!Puppeteer.Browser>}
|
* @return {!Promise<!Puppeteer.Browser>}
|
||||||
*/
|
*/
|
||||||
connect(options) {
|
connect(options) {
|
||||||
|
@ -348,17 +348,40 @@ module.exports.addTests = function({testRunner, expect, defaultBrowserOptions})
|
|||||||
const originalBrowser = await puppeteer.launch(Object.assign({}, defaultBrowserOptions, {
|
const originalBrowser = await puppeteer.launch(Object.assign({}, defaultBrowserOptions, {
|
||||||
args: ['--remote-debugging-port=21222']
|
args: ['--remote-debugging-port=21222']
|
||||||
}));
|
}));
|
||||||
const browserUrl = 'http://127.0.0.1:21222';
|
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();
|
const page1 = await browser1.newPage();
|
||||||
expect(await page1.evaluate(() => 7 * 8)).toBe(56);
|
expect(await page1.evaluate(() => 7 * 8)).toBe(56);
|
||||||
browser1.disconnect();
|
browser1.disconnect();
|
||||||
|
|
||||||
const browser2 = await puppeteer.connect({browserUrl: browserUrl + '/'});
|
const browser2 = await puppeteer.connect({browserURL: browserURL + '/'});
|
||||||
const page2 = await browser2.newPage();
|
const page2 = await browser2.newPage();
|
||||||
expect(await page2.evaluate(() => 8 * 7)).toBe(56);
|
expect(await page2.evaluate(() => 8 * 7)).toBe(56);
|
||||||
browser2.disconnect();
|
browser2.disconnect();
|
||||||
|
originalBrowser.close();
|
||||||
|
});
|
||||||
|
it('should throw when using both browserWSEndpoint and browserURL', async({server}) => {
|
||||||
|
const originalBrowser = await puppeteer.launch(Object.assign({}, defaultBrowserOptions, {
|
||||||
|
args: ['--remote-debugging-port=21222']
|
||||||
|
}));
|
||||||
|
const browserURL = 'http://127.0.0.1:21222';
|
||||||
|
|
||||||
|
let error = null;
|
||||||
|
await puppeteer.connect({browserURL, browserWSEndpoint: originalBrowser.wsEndpoint()}).catch(e => error = e);
|
||||||
|
expect(error.message).toContain('Exactly one of browserWSEndpoint, browserURL or transport');
|
||||||
|
|
||||||
|
originalBrowser.close();
|
||||||
|
});
|
||||||
|
it('should throw when trying to connect to non-existing browser', async({server}) => {
|
||||||
|
const originalBrowser = await puppeteer.launch(Object.assign({}, defaultBrowserOptions, {
|
||||||
|
args: ['--remote-debugging-port=21222']
|
||||||
|
}));
|
||||||
|
const browserURL = 'http://127.0.0.1:32333';
|
||||||
|
|
||||||
|
let error = null;
|
||||||
|
await puppeteer.connect({browserURL}).catch(e => error = e);
|
||||||
|
expect(error.message).toContain('Failed to fetch browser webSocket url from');
|
||||||
|
|
||||||
originalBrowser.close();
|
originalBrowser.close();
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user