Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Puppeteer how to switch to chrome window from default profile to desired profile

My requirement is to test chrome extensions on a new profile.

I referred https://peter.sh/experiments/chromium-command-line-switches/ for Chromium args[--user-data-dir, --profile-directory]

After the browser is launched, 2 chrome windows are opened. One with given profile and extension and another with default profile and given extension. Also the focus is on a window with default profile. So all actions are happening on it.

I had expected that only 1 browser window would be opened with desired profile and extension.

I tried to switch focus to desired window but browser.BrowserContexts().length is 1, which is browser with default profile. Also browser.targets() shows that there is only 1 target with type as browser.

My Environment:
1. Puppeteer version: 6.9.0
2. Platform / OS version: Windows 10 Pro version 1803
3. URLs (if applicable):
4. Node.js version: 10.16.3

What I tried:
a. Open chrome.exe from path\to\my\project\node_modules\puppeteer.local-chromium\win64-674921\chrome-win\chrome.exe
b. Click on profile icon and open Manage People dialog.
c. Add new person (Profile)
d. Open chrome://version and make a note of Profile Path and close the browser.
e. Create example1.js, example2.js and execute it using node example1.js, node example2.js. The code for both examples are given below.

example1.js

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless:false, args:['--disable-extensions-except=\\path\\to\\my\\extension',
'--load-extension=\\path\\to\\my\\extension',
'--user-data-dir=%userprofile%\\AppData\\Local\\Chromium\\User Data',
'--profile-directory=Profile 1'
]});

  const page = await browser.newPage();
  await page.waitFor(5000);
  await browser.close();
})();

example2.js

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless:false, args:['--disable-extensions-except=c:\\dev\\prj\\vpnteam\\global VPN\\extension', 
                                                                '--load-extension=c:\\dev\\prj\\vpnteam\\global VPN\\extension',
                                                                '--user-data-dir=c:\\Users\\govinda.s\\AppData\\Local\\Chromium\\User Data',
                                                                '--profile-directory=Profile 1'
                                                            ]});
  console.log(browser.browserContexts().length);
  var x = await browser.targets();
  for(let i=0;i<x.length;i++)
  {
    if(x[i].type()==='browser')
    {
        console.log(x[i]['_targetInfo']['targetId']);
    }
  }
  await browser.close();
})();

I had expected Puppeteer should launch Chrome with given:
a. Profile
b. Given extension should be loaded for that profile.

However, apart from above expectations,
a. A browser with default profile is also launched. In total 2 browser windows are opened.
b. The browser with default profile also has given extension loaded.
c. By default, the browser with default profile has focus.
d. browser.browserContexts().length is 1
e. There is only 1 target with type browser

like image 557
Govinda Avatar asked Aug 23 '19 09:08

Govinda


People also ask

How do I use Chromium puppeteer instead of Chrome?

By default, Puppeteer downloads and uses a specific version of Chromium so its API is guaranteed to work out of the box. To use Puppeteer with a different version of Chrome or Chromium, pass in the executable's path when creating a Browser instance: const browser = await puppeteer.

How do you connect already existing Chrome browser with puppeteer?

You can connect to an existing using the connect function: const browserURL = 'http://127.0.0.1:21222'; const browser = await puppeteer. connect({browserURL}); But, if you want to use those 2 lines you need to launch Chrome with the "--remote-debugging-port=21222 argument.

Does puppeteer work with Chrome?

Puppeteer is a Node library which provides a high-level API to control headless Chrome or Chromium over the DevTools Protocol. It can also be configured to use full (non-headless) Chrome or Chromium.


1 Answers

Okay, I found the reason.

But first i would like to add that the issue is not in puppeteer. The issue is how chromium flag --user-data-dir works and the way i expected it to work.

My understanding was that arg --user-data-dir is specified to change default dir for user data. The default dir where chromium searches for user data is %userprofile%\AppData\Local\Chromium\User Data but when arg --user-data-dir is used then it appends '\Default' to specific dir. So it becomes %userprofile%\AppData\Local\Chromium\User Data\Default instead, which is a profile directory.

Hence there was no need of arg --profile-directory. But since I had used it, I also instructed chromium to consider using specific profile.

There is definitely some clash of args here which led to opening of 2 browsers. One with specified profile and another with default.

So what I did instead is:

  1. I moved contents of directory %userprofile%\AppData\Local\Chromium\User Data\Profile 1 to %userprofile%\AppData\Local\Chromium\User Data\Profile 1\Default. I created 'Default' Directory inside Profile 1 directory.

  2. Removed arg --profile-directory and set --user-data-dir=%userprofile%\AppData\Local\Chromium\User Data\Profile 1.

Now, what chromium does is, it changes it to %userprofile%\AppData\Local\Chromium\User Data\Profile 1\Default. This way I can use puppeteer to launch using desired profile.

Final Code:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless:false, args:['--disable-extensions-except=/path/to/my/extension',
                                                                '--load-extension=/path/to/my/extension',
                                                                '--user-data-dir=%userprofile%\\AppData\\Local\\Chromium\\User Data\\Profile 1'
                                                                //'--profile-directory=Profile 1'
                                                            ]});
  const page = await browser.newPage();
  await page.goto("http://www.google.com");
  await page.waitFor(5000)
  await browser.close();
})();

Thanks for reading.

like image 109
Govinda Avatar answered Nov 15 '22 20:11

Govinda