I have some RPA processes which use ChromeDriver to connect to specific instances of Chrome identified by its remote-debugging-port and a custom command arument for chrome which idenitifies the specific chrome instances as "from my program".
I have a program using Selenium ChromeDriver. I do not let ChromeDriver create the Chrome Instance, but rahter re-use an existing one. So when my program starts up it can find the specific Chrome I want to use, and connect a new ChromeDriver to it. The issue is that sometimes the ChromeDriver is left running stuck because I exited without Quitting it (this is development work - stuff happens!)
I would like to be able to somehow tag the ChromeDriver that was launched by my programs. Iti is easy to tage the Chrome instance - I just pass in any unique argument and it happily accepts it, as in "--originator=me", then I can go through the chrome processes, get their command line and know which Chrome is mine. But I do not know how to do this with ChromeDriver. Here are ideas I have that have not worked:
Pass in a command line argument to chromedriver, but the only argument I see in the process is "port=12345"
Get the Process ID of the chromedriver I just created. But I do not know how to ask the new driver for this, even though I have access to it.
Any ideas on how to identify a chromedriver that my process created, assuming that later on my program will be looking for this specific instance?
You can use a ChromeDriverService to create a ChromeDriver then give the service a LogPath. That LogPathcan be the identifier as long as it's a valid file name. Just like this:
var svc = ChromeDriverService.CreateDefaultService();
svc.LogPath = LogPath
ChromeOptions options = new ChromeOptions();
driver = new ChromeDriver(svc, options);
Then if you want to find the specific ChromeDriver, just find the windows process with this command-line argument. In this case we really don't care about the contents of that file itself, just the fact that the magic word is now programmatically discoverable.
Related
I have the issue that sometimes our application don't start and therefore a connect of the Selenium will fail. It is OK for me that I get the error and the test fails.
My issue is in these case: That the following commands still starts the chromedriver.exe but I don't get a driver object back. So I can't stop the driver afterwards.
_driver = new Driver()
.SetChromeOptionsWeb()
.SetDriver()
.StartDriver();
Is there any possibility to not end up with a chromedriver.exe deamon process at the machine?
Thanks in advance
Nico
You need to surround it into try/catch/finally block or just make use of using.
For example you could use this piece of code:
using var driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://example.com");
//
// some driver actions
//
// Here the purpose of this task is to keep the driver up.
await CustomTaskAsync();
// And here after last action the driver will be disposed
I want to load a new Selenium ChromeDriver that is using Chrome as if I open Chrome from my dock (Essentially it'll have all my extensions, history, etc.)
When I use the following code:
ChromeOptions options = new ChromeOptions();
options.AddArgument("user-data-dir=C:\\Users\\User\\AppData\\Local\\Google\\Chrome\\User Data\\");
options.AddArgument("disable-infobars");
options.AddArgument("--start-maximized");
ChromeDriver chromeDriver = new ChromeDriver(options);
It loads the Chrome browser with me signed into my Gmail and with all my extensions, just like I want, but the rest of my code:
chromeDriver.Navigate().GoToUrl("https://www.youtube.com/");
doesn't execute. But when I use the following
ChromeOptions options = new ChromeOptions();
options.AddArgument("user-data-dir=C:\\Users\\Andrea\\AppData\\Local\\Google\\Chrome\\User Data\\Default");
options.AddArgument("disable-infobars");
options.AddArgument("--start-maximized");
ChromeDriver chromeDriver = new ChromeDriver(options);
The rest of my code executes perfectly (Notice the 'Default' added to the end of the first Argument). Any tips or suggestions on how I can get the first block of code (The one without 'Default' on the end) to execute the rest of my program would be great. Thanks!
I know this is an old question, but what worked for me is to do remove the "C:\" and replace all of the backslashes with forward slashes. So, with that from the original question, this should work to load the default profile:
options.AddArgument("user-data-dir=/Users/User/AppData/Local/Google/Chrome/User Data");
The Default Chrome Profile which you use for your regular tasks may contain either/all of the following items:
History
Bookmarks
Cookies
Extensions
Themes
Customized Fonts
All these configurations untill and unless are part of your Test Specification it would be a overkill to load them into the session initiated by Selenium WebDriver. Hence it will be a better approach if you create a dedicated New Chrome Profile for your tests and configure it with all the required configuration.
Here you will find a detailed discussion on How to create and open a Chrome Profile
Once you have created the dedicated New Chrome Profile for your tests you can easily invoke the Chrome Profile as follows:
ChromeOptions options = new ChromeOptions();
options.AddArgument("user-data-dir=C:\\Users\\User\\AppData\\Local\\Google\\Chrome\\User Data\\Profile 2");
options.AddArgument("disable-infobars");
options.AddArgument("--start-maximized");
ChromeDriver chromeDriver = new ChromeDriver(options);
chromeDriver.Navigate().GoToUrl("https://www.youtube.com/");
Here you will find a detailed discussion on How to open URL through default Chrome profile using Python Selenium Webdriver
I have the same issue. I don't know how to fix it, I guess the root cause is white space in profile path.
I know a workaround for this. Just copy the C:\\Users\\Andrea\\AppData\\Local\\Google\\Chrome\\User Data to c:\myUserData (no space in the path).
Then add the argument.
options.AddArgument("user-data-dir=C:\\myUserData");
This is an Old question, but if you are facing this issue, all you have to do is close all tabs, Just shut down the chrome window..
Selenium can't use the data since it is already in use.
Hope you fond this helpful.
Currently, I'm trying to run my Selenium tests on Safari using Selenium Grid and RemoteWebDriver. This is my setup:
Mac OS Sierra 10.12.6 as a machine for running tests.
Selenium server 3.5.3.
Safari 11.
C# Selenium WebDriver and Selenium Support (latest version).
I'm using port forwarding on my host OS (Windows 10) to forward requests to Mac, running on my Virtual Machine. On my Mac I have Selenium Grid hub, which I run like this:
java -jar selenium-server-standalone-3.5.3.jar -role hub -port 4723
Also, there is a node:
java -jar selenium-server-standalone-3.5.3.jar -role node -hub http://10.0.2.15:4723/grid/register
In code, I start my driver like this:
SafariOprions options = new SafariOptions();
IWebDriver driver = new RemoteWebDriver(new Uri(hubURL), options.ToCapabilities());
My tests are running fine with current setup. But when it comes to clicking a link with attribute target='_blank' I'm starting to face some troubles. For other drivers, which I run locally, I can switch tab without any trouble: I'm getting driver.WindowHandles before I click a link, then I click a link and again retrieve Window Handles to compare with previous handles. After that I use driver.SwitchTo().Window(newHandle) and everything is ok.
But when it comes to RemoteWebDriver (or SafariDriver from Apple, I cannot say more precisely) I'm always getting only one Window Handle, even if the new tab is opened and i can see it.
I'm trying to avoid switching tab with "Command + T" as one of solutions suggested, because my tests are meant to be run on all browsers (Chrome, Firefox, Opera, Edge, Safari) and this wont work.
UPDATE: I've tried running Chrome and other browsers in Selenium Grid via RemoteWebDriver and I can say that this is not an issue of RemoteWebDriver. Next, I've installed Visual Studio for Mac and rewrite several things to run my tests without Selenium Grid, just using this code:
//if memory serves, just like this
SafariOptions options = new SafariOptions();
SafariDriver driver = new SafariDriver(options);
But, unfortunately, this didn't help. Driver navigated me to the page, clicked the link and opened a new tab, but without any switch. When I checked for driver.WindowHandles I've only got one, although there was two visible tabs. Neither driver.SwitchTo().ActiveElement nor driver.SwitchTo().Frame(hardcoded_frame_name) doesn't seem to work. Pretty long waits (for 60 seconds after opening the link and another one after that) aren't working too. Now I think that this is really a bug and I will try to report this to Apple as soon as I can.
But for now, maybe someone has a fancy workaround for this?
As we discussed in the comments, it seems to be a timing issue. So we will induce
WebDriverWait to sync up with the trailing Browser instance. I am providing a code block as a solution through Selenium-Java, consider implementing it in C# and update me if it works for you.
driver.get("http://www.google.com");
System.out.println("Page Title is : "+driver.getTitle());
String parent_window = driver.getWindowHandle();
((JavascriptExecutor) driver).executeScript("window.open('http://facebook.com/');");
WebDriverWait wait = new WebDriverWait(driver,3);
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
Set<String> allWindows_1 = driver.getWindowHandles();
ArrayList<String> tabs = new ArrayList<>(allWindows_1);
driver.switchTo().window(tabs.get(1));
wait.until(ExpectedConditions.titleContains("Facebook"));
System.out.println("First Child Handle : "+driver.getTitle());
I could help you with the Java version:
After the actions done, do this below.
//Store the parent window
String parentWindow = driver.getWindowHandle();
//Open a new Windows(Mailtrap)
String a = "window.open('https://mailtrap.io/signin','_blank');";
((JavascriptExecutor)driver).executeScript(a);
//This Thread.sleep is useful with Safari. Do not remove.
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Take control over new browser
for(String handle: driver.getWindowHandles()){
driver.switchTo().window(handle);
}
I want to block c# controlled Google ChromeDriver via Selenium
Is that possible?
This is how i start the selenium and navigate
var Driver = new ChromeDriver();
Driver.Navigate().GoToUrl(URL)
Lets say i want that particular Chrome instance to do not connect http://googleads.g.doubleclick.net:443
Is this possible?
When that chrome instance requests to connect http://googleads.g.doubleclick.net:443, it should be automatically blocked or maybe return 127.0.0.1 I do not know
I need some solution which will prevent driver waiting response
Ok after i saw the answer i think i couldnt clarify the question well enough
The thing i want is, i am navigating to a page, which makes a lot of unnecessary requests to other hosts. I want to block those hosts, so page load timings would be much better
I tried via editing hosts file in etc and now it is 10 times better
But this is system wide
I wonder same may apply to chromedriver or not
The WebDriver does not allow this level of control (on purpose), so the short answer is no, you can't do that through it.
There is a solution though - just proxy all the traffic, and blacklist the offending URIs; or whitelist the one you're working with. In any ways, make the proxy return a reasonable response in time (a pixel file, or 404) for any unneeded URIs.
Sample code (my C#is rusty :):
ChromeOptions options = new ChromeOptions();
options.AddArguments("--proxy-server=XXX.XXX.XXX.XXX");
var Driver = new ChromeDriver(options);
(for Firefox it's a bit different, it's set as capabilities there)
There are a lot of options for the proxy, from the squid legend, the tinyproxy I've used in the past for similar purposes, to whatever will suit your environment and needs.
When I create a new chrome driver in Selenium while Google Chrome is already running AND I am referencing the users settings/data (via user-data-dir). A new Chrome window will open, but my application will hang. The ChromeDriver console will display the following error each second: DevTools Request: 127.0.0.1:12585/json/version. DevTools request failed
Screenshot:
Code to instantiate the driver:
ChromeDriverService driverService = ChromeDriverService.CreateDefaultService();
//driverService.HideCommandPromptWindow = true;
driverService.EnableVerboseLogging = true;
string path = Environment.ExpandEnvironmentVariables("%LOCALAPPDATA%\\Google\\Chrome\\User Data");
ChromeOptions options = new ChromeOptions();
options.AddArguments("user-data-dir=" + path);
options.AddArguments("--start-maximized");
options.AddArguments("--disable-extensions");
IWebDriver driver = new ChromeDriver(driverService, options);
This will work perfectly fine in every instance if I do not try and load user settings/data. If I am trying to load user setting/data it will only work if there is no instance of Chrome running on the device already.
Versions:
Selenium v 2.47.0
ChromeDriver v 2.16.333243
Chrome v44.0.2403
What can I do to resolve this?
If anyone was looking for answer like me;
https://bugs.chromium.org/p/chromedriver/issues/detail?id=2443
This behavior is by design. Two instances of Chrome can't use the same user-data-dir at the same time. Otherwise they would try to update the same set of files and cause corruptions. So if an instance is already running, attempting to start another instance using the same user-data-dir will cause the second instance to ask the first instance to open a new window, and then the second instance exits.