Selenium Automation fails if Browser Already Open (Edge Chromium/VB.NET/C#) - c#

I am using the below VB.NET code op open Edge Chromium(In IE Capability Mode). It works if there are no existing Edge windows open, Other wise, it just opens another tab in the existing window and just displays This is the initial start page for the WebDriver server. and nothing happens (see screenshot below)
Dim ieService = InternetExplorerDriverService.CreateDefaultService(Environment.CurrentDirectory, "IEDriverServer.exe")
Dim ieOptions = New InternetExplorerOptions
ieOptions.IgnoreZoomLevel = True
ieOptions.AddAdditionalCapability("ie.edgechromium", True)
ieOptions.AddAdditionalCapability("ie.edgepath", "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe")
Dim driver = New InternetExplorerDriver(ieService, ieOptions, TimeSpan.FromSeconds(60))
driver.Navigate().GoToUrl("https://example.com")
After one minute, it throws below exception at the line Dim driver = New InternetExplorerDriver(ieService, ieOptions, TimeSpan.FromSeconds(60))
OpenQA.Selenium.WebDriverException: 'The HTTP request to the remote
WebDriver server for URL http://localhost:52074/session timed out
after 60 seconds.'
Do anyone know how to fix this? (I don't want to kill edge sessions first and then start, because i want the are existing edge windows untouched)

To automate Edge-IE in already opened Edge browser window. Please follow the below steps
Include the application you are trying to launch in Edge-IE browser to the compatibility list of Edge browser(edge://compat)
Include the below command line to start an Edge process before calling Edge-IE driver initialization
code sample
System.Diagnostics.Process.Start(#"msedge.exe", "https://google.com/");
Thread.Sleep(1000);
var dir = "//path of your Edgedriver";
var driver = "IEDriverServer.exe";
if (!Directory.Exists(dir) || !File.Exists(Path.Combine(dir, driver))){
Console.WriteLine("Failed to find {0} in {1} folder.", dir, driver);}
var ieService = InternetExplorerDriverService.CreateDefaultService(dir, driver);
var ieOptions = new InternetExplorerOptions { };
ieOptions.AddAdditionalCapability("ie.edgechromium", true);
ieOptions.AddAdditionalCapability("ie.edgepath", #"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe");
InternetExplorerDriver webdriver = new InternetExplorerDriver(ieService, ieOptions, TimeSpan.FromMinutes(3));

Related

Selenium - Launch Edge Chromium as different user

I have a requirement to switch from chrome to edge driver chromium
I am having issues trying to launch the browser as a different user. We need to open the browser with different users who have different roles and validate
To manually do this you would right click edge browser > shift and click Microsoft edge > Run as different user
I am using the following NuGet Packages:
MicrosoftEdge.SeleniumTools 3.141.2
Selenium.Webdriver 3.141.0
Microsoft Edge version
91.0.864.54
Previously with using chrome and the package Selenium.Chrome.Webdriver i was able to use the following
service.StartupDomain = ""
service.StartupUserName = ""
service.StartupPassword = ""
service.StartupLoadUserProfile = true;
However with MicrosoftEdge.SeleniumTools 3.141.2 i am unable to find a similar solutions. Does anyone know an equivalent solution?
Current code below
EdgeDriverService service = EdgeDriverService.CreateChromiumService(driverpath, msedgedriverExe);
var edgeOptions = new EdgeOptions();
edgeOptions.UseChromium = true;
service. ???
edgeOptions. ???
IWebDriver driver = new EdgeDriver(service, options)

Selenium can't handle new window with edge IE mode C#

For an automation project I have to use selenium webdriver with edge. Unfortunately the site is under IE kernel. So I start edge in IE mode everything works fine. But when the controller needs to detect a new window with windowHandle, it does not detect anything new even with a wait.
Is it possible to make the switch work in IE mode ?
PS: As I use an IE driver I can by changing a few lines start IE. When I run IE the window change is done. When I run Edge with the options I don't detect anything. So everything works fine with the IE browser, the problem only comes from edge and the IE mod.
I am using an IE driver with capabilities like this :
var ieService = InternetExplorerDriverService.CreateDefaultService(dir, driver);
var ieOptions = new InternetExplorerOptions{};
ieOptions.AddAdditionalCapability("ie.edgechromium", true);
ieOptions.AddAdditionalCapability("ie.edgepath", "{path to msedge.exe}");
var webdriver = new InternetExplorerDriver(ieService, ieOptions, TimeSpan.FromSeconds(30));
driver.FindElement(By.Id("button")).Click();
Thread.Sleep(2000);
string popupHandle = string.Empty;
ReadOnlyCollection<string> windowHandles = driver.WindowHandles;
foreach (string handle in windowHandles)
{
if (handle != existingWindowHandle)
{
popupHandle = handle;
break;
}
}
driver.SwitchTo().Window(popupHandle);
Now it is solved. You can download latest Selenium version 4.0 and start scripting for Edge in IE Mode. You can also follow the issue ticket in github in the following link MS Edge in IE Mode

ChromeDriver v90 does not give correct URL when connecting to remote-debugging port through the ChromeDriverService

We use ChromeDriver in C# to connect to existing instances of Chrome that have the remote debugging port 9222 set. Here is how we connect:
var svc = ChromeDriverService.CreateDefaultService(path);
ChromeOptions options = new ChromeOptions();
options.DebuggerAddress = "127.0.0.1:9222";
var driver = new ChromeDriver(svc, options);
var url = driver.Url;
The problem is that the value of driver.Url is not what it used to be when using ChromeDriver version 88.
At that point and all earlier versions, driver.Url was the value of the URL for the current active tab in Chrome. So if Chrome had five tabs open and tab 4 is active, the Url was that of tab 4. And that made sense.
Once we upgraded to version 90 that is no longer the case. It appears that the value of Url is... well it's not clear. Sometimes the last active tab, sometimes some other tab, sometimes the first. I do not see a pattern.
Is this an error in ChromeDriver? In the past, whatever was the active tab was the one that driver.Url yielded. Now it's indeterminate which wreaks havoc with our code.
Update: If I have two tabs open, then the driver.Url and driver.Title are for the tab that was just prior active. So always the other tab. With 3 tabs it may be the 2nd to the last active tab. This feels like a off-by-one error within an internal array of tabs.
I had the same problem. I solved it using the method suggested here
ChromeDriverService driverService =
ChromeDriverService.CreateDefaultService();
var options = new ChromeOptions();
options.DebuggerAddress = "127.0.0.1:9222";
var driver = new ChromeDriver(driverService, options);
driver.SwitchTo().Window(driver.WindowHandles[0]); // Switch to the recently opened tab
MessageBox.Show("driver.Url: " + driver.Url);

How to get Selenium to operate two browser windows using only one driver selenium (using c# and chromedriver)?

I am attempting to control two browser windows via selenium using c# and a single chromedriver. The reason being that I need to share session details accross browser windows.
The code that I have tried and failed with is below;
var options = new ChromeOptions();
options.AddArguments("chrome.switches", "--disable-extensions --disable-extensions-file-access-check --disable-extensions-http-throttling --disable-infobars --enable-automation ");
options.AddUserProfilePreference("credentials_enable_service", false);
options.AddUserProfilePreference("profile.password_manager_enabled", false);
options.PageLoadStrategy = PageLoadStrategy.Default;
ChromeDriverService service = ChromeDriverService.CreateDefaultService();
service.HideCommandPromptWindow = true;
var Driver = new ChromeDriver(service, options);
//THIS WILL OPEN A NEW WINDOW. BUT BECAUSE IT IS A NEW DRIVER DOES NOT WORK FOR SHARING SESSION DETAILS.
//var TestDriver = new ChromeDriver(service, options);
//TestDriver.Manage().Window.Maximize();
//THIS JUST OPENS UP A NEW TAB. NOT A NEW WINDOW (IT WOULD SEEM MOST DOCUMENTATION SUGGESTS THAT IT SHOULD)
IJavaScriptExecutor jscript = Driver as IJavaScriptExecutor;
jscript.ExecuteScript("window.open();", "google.com.au");
//TRY USING THE SEND KEYS TECHNIQUE. NOTHING HAPPENS
var test = Driver.FindElement(By.TagName("html"));
test.SendKeys(Keys.Control + "n");
test.SendKeys(Keys.Control + "t");
//TRY AGAIN USING THE SEND KEYS TECHNIQUE USING A DIFFERENT TAG. NOTHING HAPPENS
var blah = Driver.FindElements(By.TagName("body"));
blah[0].SendKeys(Keys.Control + "t");
//TRY USING ACTIONS. NOTHING HAPPENS
Actions action = new Actions(Driver);
action.SendKeys(OpenQA.Selenium.Keys.Control + "n");
action.Build().Perform();
I may resort to AutoIt to open a browser if I have to, but one more dependency is not what I need. Documentation everywhere around the web seems to suggest than all the options I tried above should work...I suspect it may be a chromedriver issue of some kind.
Any ideas on how to achieve my goal would be greatly appreciated
UPDATE.
Arnons answer below lead me to the solution. If you are in a similar situation the best thing to do is just open up the browser console (from developers tools) and experiment with javascript until you get what you want. Then just execute that. In the end executing the following code has worked for me.
IJavaScriptExecutor jscript = Driver as IJavaScriptExecutor;
jscript.ExecuteScript("window.open('https://www.bing.com.au','_blank','toolbar = 0, location = 0, menubar = 0')");
The other alternative was to use Autoit, which I also got working, much easier than I did figuring out the javascript. But one less dependency is best :)
UPDATE2.
Further complications arise with trying to control the window as an independent browser window. I believe any new window created from a parent window, has the same process id (at least my testing has indicated so), and for all intense and purpose is treated as a tab in the selinium driver. I therefore conclude that certain things are just not possible (for example relocating the child browser window on the screen).
Your first attempt using ExecuteJavaScript was very close, but In order for it to open a new window instead of new tab, you should add the following arguments: `"_blank", "toolbar=0,location=0,menubar=0" to it.
See this question for more details.
I should have read the question better, here is my solution. Ended up using this for selecting windows that popped up after clicking a button but should work with swapping between windows.
//---- Setup Handles ----
//Create a Handle to come back to window 1
string currentHandle = driver.CurrentWindowHandle;
//Creates a target handle for window 2
string popupWindowHandle = wait.Until<string>((d) =>
{
string foundHandle = null;
// Subtract out the list of known handles. In the case of a single
// popup, the newHandles list will only have one value.
List<string> newHandles = driver.WindowHandles.Except(originalHandles).ToList();
if (newHandles.Count > 0)
{
foundHandle = newHandles[0];
}
return foundHandle;
});
//Now you can use these next 2 lines to continuously swap
//Swaps to window 2
driver.SwitchTo().Window(popupWindowHandle);
// Do stuff here in second window
//Swap back to window 1
driver.SwitchTo().Window(currentHandle);
// Do stuff here in first window
You need to explicitly tell Selenium which tab you wish to interact with, which in this case would be;
driver.SwitchTo().Window(driver.WindowHandles.Last());

Can't use existing Firefox profile in Selenium WebDriver using C#

I need to use a shared profile for Firefox, which doesn't get deleted on exit. Seems that this can be done using a FirefoxProfile or FirefoxOptions. But none of them seems to work: When starting the geckodriver, it uses a temp profile like this
1507646897935 mozrunner::runner INFO Running command:
"C:\Program Files\Mozilla Firefox\firefox.exe" "-marionette"
"-profile"
"C:\Users\\AppData\Local\Temp\rust_mozprofile.uzI9KAmLQ1zP"
When debugging, I noticed that the property ProfileDirectory of the profile is always null.
var profileManager = new FirefoxProfileManager();
var profile = profileManager.GetProfile("Test");
var driver = new FirefoxDriver(profile);
The profile Test was created manually using firefox -pbefore. I also tried to use it's location like this:
var profile = new FirefoxProfile(#"C:\Users\<MyUsername>\TestProfile", deleteSourceOnClean: false);
But same problem, can't figure out why this isn't working.
Used software
geckodriver 0.19.0
Selenium.Firefox.WebDriver 2.0.0 (NuGet)
Selenium.WebDriver 3.6.0 (NuGet)
ASP.NET Core 2.0
Solved this issue by passing the path to my profile as regular CLI parameter to Chrome:
var options = new ChromeOptions();
options.AddArgument(#"--user-data-dir=C:\Users\<MyUsername>\TestProfile");
var driver = new ChromeDriver(options);
Should also work with Firefox. But I needed to switch to Chrome until another bug in the FF driver got fixed. This is no full clean solution at all, but it works as a workaround until a better solution is found.
In Firefox, I needed to preserve all the cookies, history, cache etc and nothing worked since selenium isn't built to save any of these across sessions for obvious reasons.
Since there is no solution for Firefox, here is how I hacked it
Read the firefox.exe command line in order to find out whats the
profile temp dir.
Manually close the browser so the temp profile isn't deleted
Move the temp profile with all the data preserved
Here is the code:
IWebDriver _driver;
var service = FirefoxDriverService.CreateDefaultService();
//Start webdriver
_driver = new FirefoxDriver(service, options);
//get the webdriver commandline so we can get the path of the ff profile temp dir so we can save it later
var proc = service.ProcessId;
string cmdline = GetCommandLine(proc);
string profilePath = cmdline.Substring(cmdline.IndexOf(" -profile ") + 10);
//Do stuff with your browser
//In order to move the temp profile dir, we have to 'manually' close the browser window.
//There is no other way because the temp profile gets deleted if you use _driver.close()
var ffprocess = Process.GetProcesses().FirstOrDefault(x => x.MainWindowTitle == $"{title} - Mozilla Firefox");
ffprocess.CloseMainWindow();
//Delete the old profile data so we can get the updated data.
Directory.Delete(sProfile, true);
//store the temp profile data
Directory.Move(profilePath, sProfile);
//this must be deleted, othervise the webdriver won't start next time
File.Delete(sProfile + #"\user.js");
string GetCommandLine(int process)
{
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher($"SELECT CommandLine FROM Win32_Process WHERE CommandLine Like \"% -profile %\" AND ParentProcessID = {process}"))
using (ManagementObjectCollection objects = searcher.Get())
{
return objects.Cast<ManagementBaseObject>().SingleOrDefault()?["CommandLine"]?.ToString();
}
}

Categories

Resources