3

Java code in thread function:

    System.setProperty("webdriver.chrome.driver", "/usr/bin/chromedriver");
    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.addArguments("--no-sandbox");
    chromeOptions.addArguments("--user-data-dir="+config.chromeUserDir);
    chromeOptions.addArguments("--profile-directory="+profile);
    chromeOptions.addArguments("--start-maximized");
    WebDriver driver = new ChromeDriver(chromeOptions);
    driver.get("https://www.google.com");

and create object and start in thread with following code

    Driver d1 = new Driver(profile);
    d1.start();

    Driver d2 = new Driver(profile1);
    d1.start();

two different profiles have been created, code works well with single thread but with multiple threads it does not open google website in two separate windows. it says,

Starting ChromeDriver 2.42.591071 (0b695ff80972cc1a65a5cd643186d2ae582cd4ac) on port 25692
Only local connections are allowed.
Starting ChromeDriver 2.42.591071 (0b695ff80972cc1a65a5cd643186d2ae582cd4ac) on port 25954
Only local connections are allowed.
Oct 14, 2018 2:10:46 AM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
Oct 14, 2018 2:10:46 AM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
Created new window in existing browser session.

and it opens google in only one window. window opened by anther thread remains idle. Could anyone please help?

Ishita Shah
  • 3,955
  • 2
  • 27
  • 51
sama940
  • 35
  • 1
  • 5
  • Can you update the question with what `("--user-data-dir="+config.chromeUserDir)` and `("--profile-directory="+profile)` refers to? – undetected Selenium Oct 14 '18 at 19:26
  • config.chromeUserDir is the ~/.config/google-chrome/ on Linux and --profile-directory="+profile is dir of profile i.e. "Profile 1" or "Profile 2" created under ~/.config/google-chrome/ when we create profile on google chrome. – sama940 Oct 14 '18 at 19:37

3 Answers3

13

Issue Analysis

This issue can be reproduced even if you try to run chrome driver in two profile sequential without quiting the driver.

    ChromeOptions chromeOptions1 = new ChromeOptions();
    chromeOptions1.addArguments("--user-data-dir=C:/Users/My UserName/AppData/Local/Google/Chrome/User Data/Default");
    chromeOptions1.addArguments("--profile-directory=Profile 1");
    WebDriver driver1 = new ChromeDriver(chromeOptions1);
    driver1.get("https://www.google.com");

    ChromeOptions chromeOptions2 = new ChromeOptions();
    chromeOptions2.addArguments("--user-data-dir=C:/Users/My UserName/AppData/Local/Google/Chrome/User Data/Default");
    chromeOptions2.addArguments("--profile-directory=Profile 2");
    WebDriver driver2 = new ChromeDriver(chromeOptions2);

When running first instance browser starts and page will be accesed. While running the second instance browser starts, but the page will not open. The driver.get() line fails with following exception for the second instance

Exception in thread "main" org.openqa.selenium.NoSuchSessionException: invalid session id
  (Driver info: chromedriver=70.0.3538.16 (16ed95b41bb05e565b11fb66ac33c660b721f778),platform=Windows NT 10.0.17134 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 2.99 seconds
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{message=unknown error: Chrome failed to start: crashed
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location C:\Program Files (x86)\Google\Chrome\Application\chrome.exe is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
  (Driver info: chromedriver=70.0.3538.16 (16ed95b41bb05e565b11fb66ac33c660b721f778),platform=Windows NT 10.0.17134 x86_64), platform=ANY}]

When the first instance is started the user data directory get locked and we are getting error for the second instance as the user data directory is in use.

We can simulate this issue by opening one chrome instance manually with one profile and trying to open one more chrome instance with other profile using chrome driver.

Solution

We have to use different user-data directory for each profile. We no need to create profile manually in chrome browser and also no need to provide --profile-directory argument in chrome options. But you can maintain the sessions and history by mentioning different user-data-dir path for each chrome driver instance

ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--user-data-dir=C:/ChromeProfiles/FirstProfile"); // Custom directory path for first profile
WebDriver driver = new ChromeDriver(chromeOptions);
driver.get("https://www.google.com");

ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--user-data-dir=C:/ChromeProfiles/SecondProfile"); // Custom directory path second profile
WebDriver driver = new ChromeDriver(chromeOptions);
driver.get("https://www.google.com");

This is will maintains the sessions and history in two profile that you are looking for.

Also multithreading will work without any issue.

class Driver extends Thread {
    private String profile;
    public Driver(String profile){
        this.profile=profile;
    }
    public void run()
    {
        System.out.println ("Thread " +
                    Thread.currentThread().getId() +
                    " is running");
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.addArguments("--no-sandbox");
        chromeOptions.addArguments("--user-data-dir=C:/ChromeProfiles/"+profile);
//        chromeOptions.addArguments("--profile-directory="+profile);
        chromeOptions.addArguments("--start-maximized");
        WebDriver driver = new ChromeDriver(chromeOptions);
        driver.get("https://www.google.com");

    }
}

public class MultiThreadDriver
{
    public static void main(String[] args)
    {
        ChromeDriverManager.getInstance().setup();
        Driver object = new Driver("First Profile");
        object.start();
        Driver object1 = new Driver("Second Profile");
        object1.start();
    }
}
Navarasu
  • 8,209
  • 2
  • 21
  • 32
  • have you tested this solution by running code multiple times? two different directories under ~/.config/google-chrome already created for each profile. I tried your code with by creating different profile dirs under home dir, somehow it worked one time but later on it did not work even after creating new dirs for profiles. every time I want to use existing chrome profile for the testing. I may have 10 profiles created and I want to run automation on 10 profiles simultaneously. – sama940 Oct 14 '18 at 14:07
  • 1
    Thanks for the analysis ... your fix worked but I am not able to upvote your answer .. :( – sama940 Oct 14 '18 at 21:37
  • 1
    If I have a user data directory with multiple profiles inside, how can I split it to multiple user data for each profile? – Kien Vu Jun 28 '21 at 05:08
  • 1
    Not only worked like a charm for `chrome driver/browser`, but also same settings for `edge driver/browser`. You saved me after 4 hours try and error :) – ehsan_kabiri_33 Nov 08 '22 at 18:28
0

Because user data directory get locked when the first instance run, you can change forlder cache of profile 2.

0

Just copy your profile directory to another folder, and specify it in your --user-data-dir. Browser instances running under debugging mode.

Refer to my answer under another question for detailed explanation: https://stackoverflow.com/a/75191111/4810608

user9818
  • 49
  • 5
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Akzy Jan 25 '23 at 10:29