10

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

Govinda
  • 582
  • 1
  • 5
  • 14

2 Answers2

10

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.

Govinda
  • 582
  • 1
  • 5
  • 14
  • Now I have 1 unanswered question left. What is the intended use of arg `--profile-directory`? – Govinda Aug 26 '19 at 18:20
  • Niche analysis. were you able to load the existing browser config then? I'm trying nothing helps yet :/ – Code Cooker Apr 29 '20 at 07:52
  • I don't exactly understand what you mean by existing browser config? Can you describe what u were trying to achieve and what u have tried till now? However, if you meant that was i able to launch a browser with new profile and load desired extension only then Yes, I was successful in achieving it using above mentioned soln. – Govinda May 06 '20 at 21:09
  • This seems to have been fixed in the meantime, meaning you can use --user-data-dir and --profile-directory together now in up to date browsers (including Chrome, Edge, etc). – loxx Oct 09 '22 at 06:05
  • I still couldn't get it to work. Turns out the code I inherited included default args were sent to puppeteer. These default args already a default user-data-dir in that points to the temp folder, which came first so Chrome was using the temp dir even though I was specifying something different. I couldn't change the defaults around so the fix I found was to use userDataDir direct with puppeteer.launch, which takes precedence over the args. Using chrome://version was very useful debugging which profile directory is being used. – Adam Dec 16 '22 at 04:16
2

We need to use puppeteer-core in order to utilize the exsting chrome/edge etc. I found the following working in my windows10.

const puppeteer = require('puppeteer-core');

(async () => {
    const browser = await puppeteer.launch({
        headless: false,
        executablePath: 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
        args: [
            '--user-data-dir=%userprofile%\\AppData\\Local\\Chrome\\User Data',
            '--profile-directory=Profile 8'
        ]
    });
})();
xinqiu
  • 795
  • 6
  • 13