I am writing a script in Selenium WebDriver using C#. In the script, I am downloading some documents from the webpage and I want to download it in a dynamic path. I am using ChromeOptions class and its method to accomplish the task. Here is my sample code:
ChromeOptions options = new ChromeOptions();
options.AddUserProfilePreference("download.default_directory", "C:\Users\Desktop\MyDownloads");
IWebDriver driver = new ChromeDriver(#"C:\Users\chromedriver_win32\" , options);
If I am using the above code in the starting of the function then it works fine.
However, I want to set the properties of ChromeOptions class in the middle of the function because my path is dynamic. Hence I just change the hard coded path with the string variable and put the following code in the middle of the function
ChromeOptions options = new ChromeOptions();
options.AddUserProfilePreference("download.default_directory", strDownloadFinalPath);
IWebDriver driver = new ChromeDriver(#"C:\Users\chromedriver_win32\" , options);
Now, when I am updating the ChromeOptions in the middle of the function or at run time, then Its creating another instance of a ChromeDriver and its opening one more chrome window. It does not update the properties of ChromeOptions class. I did some experiments like removing the path of chromedriver.exe from IChromeDriver class but it started giving the following error:
The chromedriver.exe file does not exist in the current directory or
in a directory on the PATH environment variable.
What could be the way to set the ChromeOptions in the middle of the code without creating an another instance of a IWebDriver Class?
You can only set ChromeOptions, and thus the download path, via the class constructor(s). There is no property you can update once you've instantiated ChromeDriver. So the answer to your final question ("without creating another instance") is, you cannot.
What I have done to deal with this is to check the "Ask where to save each file before downloading" setting in Chrome and then I interact with the Save As dialog prompt in my test inputing the full dynamic save file path and clicking save. The problem is that this is a Windows dialog and Selenium cannot interact with it. I am using MS CodedUI to work with it. My dialog class for the Save As prompt:
using Microsoft.VisualStudio.TestTools.UITesting.WinControls;
public class WindowsDialogBoxView : WinWindow
{
public WindowsDialogBoxView()
{
this.SearchProperties[WinWindow.PropertyNames.ClassName] = "#32770";
}
public WinEdit FilenameEdit
{
get
{
this.filenameEdit = new WinEdit(this);
this.filenameEdit.SearchProperties[WinEdit.PropertyNames.Name] = "File name:";
return this.filenameEdit;
}
}
private WinEdit filenameEdit;
Usage:
WindowsDialogBoxView WindowsDialogBox = new WindowsDialogBoxView();
Keyboard.SendKeys(WindowsDialogBox.FilenameEdit, "C:\\myFileSavePath\\Blah\\FileToSave.abc");
I had difficulty interacting with the Save button of the dialog so I use Keyboard.SendKeys("{ENTER}"); You may have to add some {TAB}s in there.
Related
I started using selenium with CS and have one issue. When code is compiled, program cannot find webdriver path, because it's being moved into the .exe file. I fixed this problem, by copying driver into the bin folder, so program can access it again. However, I want it to be able to access that driver inside .exe file.
I was doing this in python using os path:
def resource_path(relative_path: str) -> str:
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.dirname(__file__)
return os.path.join(base_path, relative_path)
If anyone knows how to do this in cs, please let me know.
Code that I'm using in c#:
var browser = new EdgeDriver();
browser.Navigate().GoToUrl(link);
webdrivermanager should be more helpful here. you can add its Nuget and use to manage drivers for browsers without requiring the driver exe files.
I use something like this and call this method everytime I need a browser.
public static InternetExplorerDriver InitBrowser(string browserName)
{
switch (browserName)
{
case "IE":
{
var IE_DRIVER_PATH = #"C:\PathTo\IEDriverServer";
InternetExplorerDriver driver = new InternetExplorerDriver(IE_DRIVER_PATH);
return driver;
}
}
return null;
}
This allows you to define the path from which to grab the driver, and so you wont have to depend on it being in your BIN folder. There are other solutions but this is what I have that works really well for me. You are set up to use this method for other browsers by adding more switch cases, and also from here you can easily add your browser options. You can call the method in your tests using:
InternetExplorerDriver driver = InitBrowser(IE);
Here it is simplified without the switch case:
var IE_DRIVER_PATH = #"C:\PathTo\IEDriverServer";
InternetExplorerDriver driver = new InternetExplorerDriver(IE_DRIVER_PATH);
I'm using selenium 3.14 with geckodriver 0.24, I'm using following code to run the existing profiles I have already created for my different accounts.
FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.Proxy = pro; //my proxy object
firefoxOptions.AddArgument("-profile " + path); //path to the profile
FirefoxDriverService ffDriverService = FirefoxDriverService.CreateDefaultService();
ffDriverService.BrowserCommunicationPort = 2828;
PropertiesCollection.Driver = new FirefoxDriver(ffDriverService, firefoxOptions);
I have multiple profiles each with a different proxy. Right now, the browser is started and everything works very well for the first profile, but once I dispose the browser and start a new one with new profile and proxy, the driver opens the same last browser. I've tried many solutions and have changed selenium to old versions but no luck.
One thing I noticed in the console is that when driver opens the browser, it runs a command on console like this:
1561625708285 mozrunner::runner INFO Running command: "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe" "-marionette" "-profile C:\\Users\\Usr\\Desktop\\fprofiles\\pf1" "-foreground" "-no-remote"
if I run this command from cmd the profile issue remains there:
"C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe" "-marionette" "-profile C:\\Users\\Usr\\Desktop\\fprofiles\\pf1" "-foreground" "-no-remote"
If I remove the " from command and make it complete text it will look like this
"C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe" -marionette -profile C:\\Users\\Usr\\Desktop\\fprofiles\\pf1 -foreground -no-remote
I cloned the selenium project of OpenQA and tried to debug there but that also uses geckodriver.exe and I guess geckodriver.exe is responsible for getting arguments and passing to firefox.
Last but the least option will be to compile geckodriver(which has been developed in RUST) once again as per my consent but the programming language is RUST and that's going to be a long long job for achieving what I need.
Has anyone faced the same problem? How can I get it fixed?
Try loading browser profile based on it's name. An example with profile called 'selenium_profile':
public static WebDriver driver;
public static String driverPath = "C:\\Users\\pburgr\\Desktop\\selenium-tests\\FF_driver_0_23\\geckodriver.exe";
public static WebDriver startFF() {
FirefoxOptions options = new FirefoxOptions();
ProfilesIni allProfiles = new ProfilesIni();
FirefoxProfile selenium_profile = allProfiles.getProfile("selenium_profile");
options.setProfile(selenium_profile);
options.setBinary("C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
System.setProperty("webdriver.gecko.driver", driverPath);
driver = new FirefoxDriver(options);
driver.manage().window().maximize();
return driver;
}
It must not be static so you can parse name of desired profile in argument.
We are trying to create a website verifier for our internal site, to verify that all sites are up. For this, we use seleniums chromedriver.
We have 2 projects for this:
1 main project which executes the code.
1 "shared" project, which is shared between all of our different solution. This project contains data, which is used across multiple solutions.
We have placed the chromedriver in the shared project, and initialize it like this:
public static IWebDriver InitiateChromeDriver()
{
ChromeOptions option = new ChromeOptions();
option.AddUserProfilePreference("download.default_directory", downloadPath);
option.AddUserProfilePreference("disable-popup-blocking", "true");
var path = Path.GetFullPath("Utility");
Console.WriteLine(path);
IWebDriver driver = new ChromeDriver(path, option, TimeSpan.FromMinutes(20));
return driver;
}
This method is placed in the "Utility" folder, together with the Chromedriver.exe, and can run locally when debugging through Visual Studio.
When we deploy it to our production server, it cannot find the path to the chromedriver. The referenced path changes to C:\windows\system32\inetsrv\Utility\chromedriver.exe on our production server.
What is a better approach at referencing the file, and ensuring that the path is correct?
Try the below. Create a folder called drivers and add the chromedriver to it.
ChromeOptions options = new ChromeOptions();
option.AddUserProfilePreference("disable-popup-blocking", "true");
driver = new ChromeDriver(Path.Combine(GetBasePath, #"Drivers\\"), options);
public static string GetBasePath
{
get
{
var basePath =
System.IO.Path.GetDirectoryName((System.Reflection.Assembly.GetExecutingAssembly().Location));
basePath = basePath.Substring(0, basePath.Length - 10);
return basePath;
}
}
I am working on creating a regression test suite using Selenium for IE Browser. I am using the IEDriver exe from Selenium website. As per instructions from Selenium,
"The Internet Explorer Driver Server
This is required if you want to make use of the latest and greatest features of the WebDriver InternetExplorerDriver. Please make sure that this is available on your $PATH (or %PATH% on Windows) in order for the IE Driver to work as expected."
Approach 1
I tried to setup PATH variable via batch file as follows
setlocal
set varC=%CD%\ChromeDriver
set varI=%CD%\IEDriver
set PATH=%PATH%;%varC%;%varI%
However i still face issues with IEDriver not working properly.
Approach 2
When i set PATH variable via "Advanced System Settings", everything seems to be working fine. Can someone confirm if this setting can't be done via batch file or if i am performing some wrong operation?
Here is how I am initializing driver
[OneTimeSetUp]
public void SetupTestFixture()
{
switch (ConfigPara.TestBrowser.ToLower())
{
case "ie":
Utility.KillProcess("iexplore");
DesiredCapabilities caps = DesiredCapabilities.InternetExplorer();
caps.SetCapability("ignoreZoomSetting", true);
caps.SetCapability("nativeEvents", false);
caps.SetCapability("allow-blocked-content", true);
caps.SetCapability("disable-popup-blocking", true);
caps.SetCapability("allowBlockedContent", true);
aOptIE = new OpenQA.Selenium.IE.InternetExplorerOptions();
aOptIE.InitialBrowserUrl = ConfigurationManager.AppSettings.Get("baseURL");
aOptIE.EnablePersistentHover = false;
aOptIE.RequireWindowFocus = true;
aOptIE.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
System.Environment.SetEnvironmentVariable("webdriver.ie.driver", ConfigPara.IEDriverDirectory.FullName +"\\IEDriverServer.exe");
Utility.Instance.driver = new InternetExplorerDriver(ConfigPara.IEDriverDirectory.FullName, aOptIE);
break;
}
Utility.Instance.driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(7));
baseURL = ConfigPara.BaseURL;
Utility.Instance.wait = new OpenQA.Selenium.Support.UI.WebDriverWait(Utility.Instance.driver, TimeSpan.FromSeconds(30));
//utility = new Utility(driver);
}
[OneTimeTearDown]
public void SetupTestTeardown()
{
try
{
Utility.Instance.driver.Quit();
Utility.Instance.driver.Dispose();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
Assert.AreEqual("", verificationErrors.ToString());
}
Hi actually you have to set the path of the IE driver that you downloaded form here http://docs.seleniumhq.org/download/
please do it like below
System.setProperty("webdriver.ie.driver","pathofIEdriver\\IEDriverServer.exe");
WebDriver driver = new InternetExplorerDriver();
User below code for C# webdriver:
System.Environment.SetEnvironmentVariable("webdriver.ie.driver", "Path\IEDriverServer.exe");
You can use webdriver manager class to handle it.
WebDriverManager.iedriver().setup();
Added in your maven pom file :
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>3.8.1</version>
</dependency>
You can also use Webdrivermanage dependency for Gradle. This will automatically maintain IE driver exe file.
I try to load ChromeDriver with adblock, and somehow it reloads downloading the extension everytime it runs and shows this message:
If you see this message every time you start AdBlock, please make sure you are not using a file cleaner that also cleans 'localStorage' files.
var options = new ChromeOptions();
options.AddArgument("--no-experiments");
options.AddArgument("--disable-translate");
options.AddArgument("--disable-plugins");
options.AddArgument("--no-default-browser-check");
options.AddArgument("--clear-token-service");
options.AddArgument("--disable-default-apps");
options.AddArgument("--no-displaying-insecure-content");
options.AddArgument("--disable-bundled-ppapi-flash");
options.AddExtension(#"D:\AdBlock-v2.6.5\adblock.crx");
using (IWebDriver driver = new ChromeDriver(options))
{
driver.Navigate().GoToUrl(url);
}
Try to use the same chrome profile on every run. This must resolve the issue.
Code to do this located here: Load Chrome Profile using Selenium WebDriver