puppeteer icon indicating copy to clipboard operation
puppeteer copied to clipboard

Support extensions with createIncognitoBrowserContext

Open kivutar opened this issue 7 years ago • 11 comments

Steps to reproduce

Tell us about your environment:

  • Puppeteer version: ^1.6.2
  • Platform / OS version: OSX
  • Node.js version: v8.11.3

What steps will reproduce the problem?

Please include code that reproduces the issue.

  1. Use createIncognitoBrowserContext
  2. Try to enable an extension using --load-extension and --disable-extensions-except

What is the expected result?

I expect the extension to work in incognito mode. This extension works well with Allow in incognito switched on in Google Chrome, outside of Puppeteer.

What happens instead?

Got error net::ERR_BLOCKED_BY_CLIENT at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/popup.html

kivutar avatar Oct 25 '18 10:10 kivutar

Quite reasonable and shouldn't be that hard to do, but requires upstream investigation.

aslushnikov avatar Nov 01 '18 07:11 aslushnikov

yeah I just hit a major roadblock with this. I have a fully functional system using puppeteer and a custom plugin for deep testing / video recording, trying to cluster it now using puppeteer-cluster and realized plugins do not work with incognito mode which is a must in order to have the video recorder record each site test individually.

jpilon avatar Nov 02 '18 14:11 jpilon

I'm encountering the same problem. Do you have some ideas for a temporary fix?

Raidus avatar Feb 22 '19 12:02 Raidus

Never got plugins to work in Incognito mode so we ended up using puppeteer in a Docker image so the browser history/cache is destroyed when the image is terminated.

jpilon avatar Feb 22 '19 14:02 jpilon

I've found a workaround for it. Pretty naive approach but it solves my problem :-) What I do:

  1. Define userDataDir for the browser instance like userDataDir: "./tmp"
  2. Start browser in headful mode
  3. Manually goto browser extensions => enable dev mode => enable incognito for extensions
  4. Close Browser Instance
  5. Copy created the tmp dir to tmp_ref

On each new browser instance I use this tmp_ref for my userDataDir. Browser history is in my case not an issue. Maybe it's possible to compare the temporary files and check where those incognito settings are made.

Raidus avatar Feb 24 '19 10:02 Raidus

Though ugly, it's possible to use Puppeteer to drive the extensions page and enable extensions in incognito mode:

const extensionsPage = await browser.newPage();
await extensionsPage.goto( 'chrome://extensions/' );

// https://github.com/GoogleChrome/puppeteer/issues/858
// https://github.com/GoogleChrome/puppeteer/issues/4171
const extensionCount = await extensionsPage.evaluate( `
    document
        .querySelector( 'extensions-manager' )
        .shadowRoot
        .querySelector( 'extensions-item-list' )
        .shadowRoot
        .querySelectorAll( 'extensions-item' )
        .length
` );
if ( extensionCount !== 2 ) {
    throw new Error( 'Could not find extensions on extensions page!' );
}
for ( let i = 0; i < extensionCount; i++ ) {
    const detailsButton = await extensionsPage.evaluateHandle( `
        document
            .querySelector( 'extensions-manager' )
            .shadowRoot
            .querySelector( 'extensions-item-list' )
            .shadowRoot
            .querySelectorAll( 'extensions-item' )[ ${ i } ]
            .shadowRoot
            .querySelector( 'paper-button#detailsButton' )
    ` );
    await detailsButton.click();
    await new Promise( resolve => setTimeout( resolve, 1000 ) );
    const incognitoToggle = await extensionsPage.evaluateHandle( `
        document
            .querySelector( 'extensions-manager' )
            .shadowRoot
            .querySelector( 'extensions-detail-view' )
            .shadowRoot
            .querySelector( 'extensions-toggle-row#allow-incognito' )
            .shadowRoot
            .querySelector( '#crToggle' )
    ` );
    await incognitoToggle.click();
    await new Promise( resolve => setTimeout( resolve, 1000 ) );
    const closeDetailsButton = await extensionsPage.evaluateHandle( `
        document
            .querySelector( 'extensions-manager' )
            .shadowRoot
            .querySelector( 'extensions-detail-view' )
            .shadowRoot
            .querySelector( '#closeButton' )
    ` );
    await closeDetailsButton.click();
    await new Promise( resolve => setTimeout( resolve, 1000 ) );
}

await extensionsPage.close();

However I'm having more problems after that. I need to use await browser.targets() and await target.page() to grab a handle to one of my extensions' background pages, and this is not working. After enabling this extension in incognito mode, it has 2 background pages, and the call to await target.page() for one of them just hangs and never returns anything.

nylen avatar Apr 09 '19 21:04 nylen

@nylen you may try to set incognito: spanning in your manifest file to have only one background page https://developer.chrome.com/extensions/manifest/incognito#spanning It will not work unfortunately

Bnaya avatar Apr 21 '20 22:04 Bnaya

@nylen I found a faster way:

const extensionsPage = await browser.newPage();
await extensionsPage.goto( 'chrome://extensions/' );

page.go_to('chrome://extensions')
await extensionsPage.evaluate(`
  chrome.developerPrivate.getExtensionsInfo().then((extensions) => {
    extensions.map((extension) => chrome.developerPrivate.updateExtensionConfiguration({extensionId: extension.id, incognitoAccess: true}));
  });
`);

alhafoudh avatar Jun 24 '22 08:06 alhafoudh

@alhafoudh Thanks for sharing. Your code does toggle "Allow in incognito" successfully on all installed extensions, but the extensions are still inactive in browser contexts created with createIncognitoBrowserContext(). Did it work for you?

CComparon avatar Jan 12 '23 02:01 CComparon

@CComparon I think you must do it after creating the incognit context. I use https://github.com/rubycdp/ferrum not puppeteer. I came to this issue by researching installing and enabling extensions in automated Chrome incognito window.

alhafoudh avatar Jan 30 '23 10:01 alhafoudh