Headful puppeteer does not run on existing chrome profile - puppeteer

I'm getting this error when I try to run puppeteer on my existing chrome profile on headful but it works on headless but I cannot see the tab.
I know it works on the existing chrome because I can get it to open a new tab but then I get the error.
I want to be able to interact with this puppeteer instantiated tab.
C:\Users\Me\node_modules\puppeteer-core\lib\cjs\puppeteer\node\BrowserRunner.js:299
reject(new Error([
^
Error: Failed to launch the browser process!
TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
const pptr = require('puppeteer');
(async () =>{
const browser = await pptr.launch({
headless: false,
defaultViewport: {width: 1920,height: 1080},
executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
userDataDir: 'C:\\Users\\Me\\AppData\\Local\\Google\\Chrome\\User Data\\'
})
await browser.newPage()
})()

Related

How to simulate a browser crash with Puppeteer?

I have a lot of tests that are being run with Jest and Puppeteer. I'm creating a new browser instance with puppeteer.launch() before each test, in order to avoid situations where re-using the browser results in flaky behavior. When I run all my tests together, occasionally the browser crashes after launching, and I can detect this by listening for the browser.on('disconnected', ...) event.
I'm now trying to handle that case, and re-create the browser if needed. The problem is how can I force the Chromium browser to crash, and send the same disconnected event? I've tried loading the page with special chrome:// URLs (see below).
Here's the simple example I'm working on:
import puppeteer from 'puppeteer';
async function getPage(url) {
const browser = await puppeteer.launch({});
const page = await browser.newPage();
await browser.on('disconnected', async () => {
console.log('############ browser crashed #############');
});
await page.goto(url, {waitUntil: 'load'});
return page;
};
describe('Raw Puppeteer Test', () => {
let page;
beforeEach(async () => {
page = await getPage('chrome://kill/');
});
afterEach(async () => {
await page.close();
await page.browser().close();
});
it('should relaunch the browser and re-run if the browser crashes', async () => {
const el = await page.waitForSelector('h1');
expect(el).not.toBeNull();
});
});
While kill and crash do appear to crash the Chromium browser, it doesn't send the disconnected event that a real crash would. I also tried inducebrowsercrashforrealz but that just results in a net::ERR_INVALID_URL error.
Is there a way to simulate a failed browser initialization in Puppeteer, that mimics a real-life crash?

How to check if the puppeteer is finish downloading the file

I'm using this code to download files. I just hide the urls for security reasons. In the code below how can I check if the puppeteer has finished downloading the file
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.setDefaultNavigationTimeout(0);
await page.goto('https://');
await page.waitForSelector('#aaa');
await page.goto('https://');
await page.waitForSelector('#bbb');
await page.goto('https://');
Please see the Puppeteer documentation as this is a very basic first step when working with Puppeteer.
page.waitForNavigation({ waitUntil: 'networkidle0' })
This will:
"consider navigation to be finished when there are no more than 0 network connections for at least 500 ms."
https://pptr.dev/

In Puppeteer how to capture Chrome browser log in the console

I'm trying to collect Chrome browser logs: browser-issued warnings such as deprecation and interventions. For example, for site https://uriyaa.wixsite.com/corvid-cli2:
A cookie associated with a cross-site resource at http://wix.com/ was set without the `SameSite` attribute.
A future release of Chrome will only deliver cookies with cross-site requests if they are set with `SameSite=None` and `Secure`.
You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.
I thought the following code would do the trick but it only catches logs generated by the page code.
(async ()=> {
const browser = await puppeteer.launch({dumpio: true});
const page = await browser.newPage();
page.on('console', msg => {
for (let i = 0; i < msg._args.length; ++i)
console.log(`${i}: ${msg._args[i]}`);
});
await page.goto('https://uriyaa.wixsite.com/corvid-cli2', {waitUntil: 'networkidle2', timeout: 20000});
await page.screenshot({path: 'screenshot.png'});
await browser.close();
})();
bellow is not relevant as I thought as reportingobserver does not catch the chrome info on cookies without sameSite:
Reading on the subject led me to https://developers.google.com/web/updates/2018/07/reportingobserver but I'm not sure how to use it, using the example int the browser console didn't work.
I'm not sure in which context the observer code should be used or if the browser need a flag to activate the reporting API. Or if this is the way to got about it.
help is welcomed.
Presumably, the 'console' event only catches console.log() and similar calls from the pages. But it seems you can catch warnings from the browser via CDPSession with Log Domain. Unfortunately, it works for me only with a headful browser:
'use strict';
const puppeteer = require('puppeteer');
(async function main() {
try {
const browser = await puppeteer.launch({ headless: false });
const [page] = await browser.pages();
const cdp = await page.target().createCDPSession();
await cdp.send('Log.enable');
cdp.on('Log.entryAdded', async ({ entry }) => {
console.log(entry);
});
await page.goto('https://uriyaa.wixsite.com/corvid-cli2');
} catch (err) {
console.error(err);
}
})();
And one of the entries:
{
source: 'other',
level: 'warning',
text: 'A cookie associated with a cross-site resource at http://www.wix.com/ was set without the `SameSite` attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.',
timestamp: 1589058118372.802,
url: 'https://uriyaa.wixsite.com/corvid-cli2'
}
When you launch Puppeteer browser, inside the options object, you should set dumpio to true:
await puppeteer.launch({ dumpio: true });
This will basically "pipe browser process stdout and stderr into process.stdout and process.stderr", which means it will redirect browser logs to whatever main process, server, etc. you are running.
You can see this and other launch options you can use when launching Puppeteer in here: https://www.puppeteersharp.com/api/PuppeteerSharp.LaunchOptions.html

How to test the application in Incognito mode using puppetter?

When ever I tried using the below code, it launches a second window in incognito mode.
const context = await browser.createIncognitoBrowserContext();
const page = await context.newPage();
When I tried the below code, it launches the Incognito mode. But opens the url in regular chrome mode
const browser = await puppeteer.launch({
headless: false,
args: [
"--incognito"
]
});

Make Puppeteer use local profile's cookies

I want to use my local user's profile with Puppeteer. However, it doesn't seem to work.
I launch it with these args.
const browser = await puppeteer.launch({
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
userDataDir: '/Users/me/Library/Application Support/Google/Chrome',
});
When headless, it doesn't use the user's local profile's cookies at all, even though I'd expect it to. When it isn't headless, it can't even open the tab; Puppeteer crashes with
(node:23303) UnhandledPromiseRejectionWarning: Error: Failed to launch chrome!
TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
Is there a way to use my local user's profile? I'm using ^1.7.0 and Chrome 70.0.3521.2.
Rather than setting a userDataDir path in the Puppeteer.launch arguments you can use the chrome-cookies-secure NPM package to use cookies for one of your existing Chrome Profiles. This solution does not require Chrome Canary to be installed.
With your macOS keychain authorisation, the package reads the cookies for a given url from your hard-disk and makes them accessible in NodeJS. You can then load them into Puppeteer using the page.setCookie(...) method.
Here's an example:
const chrome = require('chrome-cookies-secure');
const puppeteer = require('puppeteer');
const url = 'https://www.yourUrl.com';
const getCookies = (callback) => {
chrome.getCookies(url, 'puppeteer', function(err, cookies) {
if (err) {
console.log(err, 'error');
return
}
console.log(cookies, 'cookies');
callback(cookies);
}, 'yourProfile') // e.g. 'Profile 2'
}
// find profiles at ~/Library/Application Support/Google/Chrome
getCookies(async (cookies) => {
const browser = await puppeteer.launch({
headless: false
});
const page = await browser.newPage();
await page.setCookie(...cookies);
await page.goto(url);
await page.waitFor(1000);
browser.close()
});
I solved this on MacOS by installing chrome canary, copying my default folder contained in ~/Library/Application Support/Google/Chrome/Default to ~/Library/Application Support/Google/Chrome\ Canary/Default
My working code looks like this:
async function run() {
const browser = await puppeteer.launch({
headless: false,
executablePath: '/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary',
userDataDir: '/Users/radium/Library/Application\ Support/Google/Chrome\ Canary/',
});
}
I was previously using the file path all the way to the Default folder, and truncated it to end with 'Chrome Canary' folder. This fixed everything. I have not tried with regular chrome.