From 4e48dfc7a195331ab1ff987d98290a6ab060a353 Mon Sep 17 00:00:00 2001 From: Andrey Lushnikov Date: Thu, 20 Sep 2018 11:55:23 -0700 Subject: [PATCH] feat(launcher): add experimental "transport" option to pptr.connect (#3265) This patch: - adds experimental "transport" option to pptr.connect - uses "transport" option to make sure Puppeteer-Web works with Target.exposeDevToolsProtocol Drive-by: add `browser.target()` to access browser target. --- docs/api.md | 6 ++++++ lib/Browser.js | 7 +++++++ lib/Launcher.js | 4 ++-- lib/Puppeteer.js | 2 +- test/browser.spec.js | 7 +++++++ utils/ESTreeWalker.js | 1 + utils/browser/test.js | 22 ++++++++++++++++++++++ 7 files changed, 46 insertions(+), 3 deletions(-) diff --git a/docs/api.md b/docs/api.md index aa43624ea1b..f8c31b4f8b3 100644 --- a/docs/api.md +++ b/docs/api.md @@ -48,6 +48,7 @@ * [browser.newPage()](#browsernewpage) * [browser.pages()](#browserpages) * [browser.process()](#browserprocess) + * [browser.target()](#browsertarget) * [browser.targets()](#browsertargets) * [browser.userAgent()](#browseruseragent) * [browser.version()](#browserversion) @@ -677,6 +678,11 @@ the method will return an array with all the pages in all browser contexts. #### browser.process() - returns: Spawned browser process. Returns `null` if the browser instance was created with [`puppeteer.connect`](#puppeteerconnectoptions) method. +#### browser.target() +- returns: <[Target]> + +A target associated with the browser. + #### browser.targets() - returns: <[Array]<[Target]>> diff --git a/lib/Browser.js b/lib/Browser.js index 7553d15ec12..0ccd772052e 100644 --- a/lib/Browser.js +++ b/lib/Browser.js @@ -185,6 +185,13 @@ class Browser extends EventEmitter { return Array.from(this._targets.values()).filter(target => target._isInitialized); } + /** + * @return {!Target} + */ + target() { + return this.targets().find(target => target.type() === 'browser'); + } + /** * @return {!Promise>} */ diff --git a/lib/Launcher.js b/lib/Launcher.js index 9960dee939d..ccee01e3a6d 100644 --- a/lib/Launcher.js +++ b/lib/Launcher.js @@ -270,7 +270,7 @@ class Launcher { } /** - * @param {!(BrowserOptions & {browserWSEndpoint: string})} options + * @param {!(BrowserOptions & {browserWSEndpoint: string, transport?: !Puppeteer.ConnectionTransport})} options * @return {!Promise} */ async connect(options) { @@ -278,9 +278,9 @@ class Launcher { browserWSEndpoint, ignoreHTTPSErrors = false, defaultViewport = {width: 800, height: 600}, + transport = await WebSocketTransport.create(browserWSEndpoint), slowMo = 0, } = options; - const transport = await WebSocketTransport.create(browserWSEndpoint); const connection = new Connection(browserWSEndpoint, transport, slowMo); const {browserContextIds} = await connection.send('Target.getBrowserContexts'); return Browser.create(connection, browserContextIds, ignoreHTTPSErrors, defaultViewport, null, () => connection.send('Browser.close').catch(debugError)); diff --git a/lib/Puppeteer.js b/lib/Puppeteer.js index 63f6c07997a..b966a39462c 100644 --- a/lib/Puppeteer.js +++ b/lib/Puppeteer.js @@ -37,7 +37,7 @@ module.exports = class { } /** - * @param {{browserWSEndpoint: string, ignoreHTTPSErrors: boolean}} options + * @param {{browserWSEndpoint: string, ignoreHTTPSErrors: boolean, transport?: !Puppeteer.ConnectionTransport}} options * @return {!Promise} */ connect(options) { diff --git a/test/browser.spec.js b/test/browser.spec.js index bceabc3216d..c0042d4dd44 100644 --- a/test/browser.spec.js +++ b/test/browser.spec.js @@ -37,6 +37,13 @@ module.exports.addTests = function({testRunner, expect, headless}) { }); }); + describe('Browser.target', function() { + it('should return browser target', async({browser}) => { + const target = browser.target(); + expect(target.type()).toBe('browser'); + }); + }); + describe('Browser.process', function() { it('should return child_process instance', async function({browser}) { const process = await browser.process(); diff --git a/utils/ESTreeWalker.js b/utils/ESTreeWalker.js index 189186a2698..097a53d22a8 100644 --- a/utils/ESTreeWalker.js +++ b/utils/ESTreeWalker.js @@ -80,6 +80,7 @@ ESTreeWalker._walkOrder = { 'ArrayExpression': ['elements'], 'ArrowFunctionExpression': ['params', 'body'], 'AssignmentExpression': ['left', 'right'], + 'AssignmentPattern': ['left', 'right'], 'BinaryExpression': ['left', 'right'], 'BlockStatement': ['body'], 'BreakStatement': ['label'], diff --git a/utils/browser/test.js b/utils/browser/test.js index 8248c2579fd..b42b40a2147 100644 --- a/utils/browser/test.js +++ b/utils/browser/test.js @@ -69,6 +69,28 @@ describe('Puppeteer-Web', () => { ]); await browser2.close(); }); + it('should work over exposed DevTools protocol', async({browser, page, serverConfig}) => { + // Expose devtools protocol binding into page. + const session = await browser.target().createCDPSession(); + const pageInfo = (await session.send('Target.getTargets')).targetInfos.find(info => info.attached); + await session.send('Target.exposeDevToolsProtocol', {targetId: pageInfo.targetId}); + await session.detach(); + + // Use in-page puppeteer to create a new page and navigate it to the EMPTY_PAGE + await page.evaluate(async serverConfig => { + const puppeteer = require('puppeteer'); + window.cdp.close = () => {}; + const browser = await puppeteer.connect({transport: window.cdp}); + const page = await browser.newPage(); + await page.goto(serverConfig.EMPTY_PAGE); + }, serverConfig); + const pageURLs = (await browser.pages()).map(page => page.url()).sort(); + expect(pageURLs).toEqual([ + 'about:blank', + 'about:blank', + serverConfig.EMPTY_PAGE + ]); + }); }); if (process.env.CI && testRunner.hasFocusedTestsOrSuites()) {