puppeteer
puppeteer copied to clipboard
Support extensions with createIncognitoBrowserContext
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.
- Use
createIncognitoBrowserContext - Try to enable an extension using
--load-extensionand--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
Quite reasonable and shouldn't be that hard to do, but requires upstream investigation.
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.
I'm encountering the same problem. Do you have some ideas for a temporary fix?
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.
I've found a workaround for it. Pretty naive approach but it solves my problem :-) What I do:
- Define userDataDir for the browser instance like
userDataDir: "./tmp" - Start browser in headful mode
- Manually goto browser extensions => enable dev mode => enable incognito for extensions
- Close Browser Instance
- Copy created the
tmpdir totmp_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.
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 you may try to set
It will not work unfortunatelyincognito: spanning in your manifest file to have only one background page
https://developer.chrome.com/extensions/manifest/incognito#spanning
@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 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 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.