How to set the download folder for Edge in Selenium? - c#

I am writing automated tests using Selenium. I want to set the download directory in Edge so that I can download files as part of my test. There is an EdgeOptions object that I can provide when creating the EdgeDriver, but I don't know what to set on the EdgeOptions.
I know the equivalent of how to do this in Chrome
chromeOptions.AddUserProfilePreference("download.default_directory", #"C:\temp")
and Firefox
firefoxOptions.SetPreference("browser.download.dir", #"C:\temp")
But, how do I do the same thing in Edge? And get it to download automatically without a save prompt?

As #Prany already mentioned, probably there is no way to set download automatically. And if I right understood, you want to handle with native window dialogue, when you are clicking on download button. Selenium cannot interact with native windows, but you can use this framework. The sample code would be like this:
// Press the A Key Down
KeyboardSimulator.KeyDown(Keys.A);
// Let the A Key back up
KeyboardSimulator.KeyUp(Keys.A);
// Press A down, and let up (same as two above)
KeyboardSimulator.KeyPress(Keys.A);
// Simulate (Ctrl + C) shortcut, which is copy for most applications
KeyboardSimulator.SimulateStandardShortcut(StandardShortcut.Copy);
// This does the same as above
KeyboardSimulator.KeyDown(Keys.Control);
KeyboardSimulator.KeyPress(Keys.C);
KeyboardSimulator.KeyUp(Keys.Control);
So you can simulate Ctrl + V keyboard action and Enter action. Hope it helps.

You can do this for Edge like this:
// hide driver Console? true/false
EdgeDriverService service = EdgeDriverService.CreateDefaultService();
service.HideCommandPromptWindow = true; // hide Console
// change Standard-Download-Path
EdgeOptions options = new EdgeOptions();
var downloadDirectory = "C:\temp";
// Setting custom download directory
options.AddUserProfilePreference("download.default_directory", downloadDirectory);
// start Selenium Driver:
webdriver = new EdgeDriver(service, options);
// max. Window
webdriver.Manage().Window.Maximize();

Related

C# Selenium Edge Driver unable to download file - Keep file prompt shows up

I am using C# with Selenium for QA automation, and I am having issues with downloading an .xml file, because a prompt is always showing up asking if I want to keep the file. It also opens a second tab to execute the download, closing it after the prompt shows up.
[keep file prompt][1]
Using Chrome I do not see this behavior.
I searched all over and could not find a EdgeOptions() and/or AddArguments() capable of taking care of this issue.
Any ideas?
You need to use JS to interact with elements in another browser. I have had such experience and I used if else statement in my method to handle that problem. Just look trough the Selenium documentation, JS with selenium examples and so long so for.
Just add this to your OneTimeSetup method. Make sure to run Visual Studio as administrator. This works since Edge 105+:
public void SetEdgeXmlDownloadPolicy()
{
var keyName = "Software\\Policies\\Microsoft\\Edge\\";
var valueName = "ExemptFileTypeDownloadWarnings";
var valueData = #"{""domains"": ["" * ""], ""file_extension"": ""xml""}";
var currentUser = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
var currentKey = currentUser.OpenSubKey(keyName, true);
if (currentKey == null)
currentKey = currentUser.CreateSubKey(keyName);
if (currentKey.GetValue(valueName) == null)
currentKey.SetValue(valueName, valueData);
}

How to open a Chrome Profile through --user-data-dir argument of Selenium

I am attempting to load a chrome browser with selenium using my existing account and settings from my profile.
I can get this working using ChromeOptions to set the userdatadir and profile directory. This loads the browser with my profile like i want, but the browser then hangs for 60 seconds and times out without advancing through any more of the automation.
If I don't use the user data dir and profile settings, it works fine but doesn't use my profile.
The reading I've done points to not being able to have more than one browser open at a time with the same profile so I made sure nothing was open while I ran the program. It still hangs for 60 seconds even without another browser open.
m_Options = new ChromeOptions();
m_Options.AddArgument("--user-data-dir=C:/Users/Me/AppData/Local/Google/Chrome/User Data");
m_Options.AddArgument("--profile-directory=Default");
m_Options.AddArgument("--disable-extensions");
m_Driver = new ChromeDriver(#"pathtoexe", m_Options);
m_Driver.Navigate().GoToUrl("somesite");
It always hangs on the GoToUrl. I'm not sure what else to try.
As per your code trials you were trying to load the Default Chrome Profile which will be against all the best practices as the Default Chrome Profile may contain either of the following:
Extensions
Bookmarks
Browsing History
etc
So the Default Chrome Profile may not be in compliance with you Test Specification and may raise exception while loading. Hence you should always use a customized Chrome Profile as below.
To create and open a new Chrome Profile you need to follow the following steps :
Open Chrome browser, click on the Side Menu and click on Settings on which the url chrome://settings/ opens up.
In People section, click on Manage other people on which a popup comes up.
Click on ADD PERSON, provide the person name, select an icon, keep the item Create a desktop shortcut for this user checked and click on ADD button.
Your new profile gets created.
Snapshot of a new profile SeLeNiUm
Now a desktop icon will be created as SeLeNiUm - Chrome
From the properties of the desktop icon SeLeNiUm - Chrome get the name of the profile directory. e.g. --profile-directory="Profile 2"
Get the absolute path of the profile-directory in your system as follows :
C:\\Users\\Thranor\\AppData\\Local\\Google\\Chrome\\User Data\\Profile 2
Now pass the value of profile-directory through an instance of ChromeOptions with AddArgument method along with key user-data-dir as follows :
m_Options = new ChromeOptions();
m_Options.AddArgument("--user-data-dir=C:/Users/Me/AppData/Local/Google/Chrome/User Data/Profile 2");
m_Options.AddArgument("--disable-extensions");
m_Driver = new ChromeDriver(#"pathtoexe", m_Options);
m_Driver.Navigate().GoToUrl("somesite");
Execute your Test
Observe Chrome gets initialized with the Chrome Profile as SeLeNiUm
If you want to run Chrome using your default profile (cause you need a extension), you need to run your script using another browser, like Microsoft Edge or Microsoft IE and your code will lunch a Chrome instance.
My Code in PHP:
namespace Facebook\WebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Chrome\ChromeOptions;
require_once('vendor/autoload.php');
$host = 'http://localhost:4444/';
$options = new ChromeOptions();
$options->addArguments(array(
'--user-data-dir=C:\Users\paulo\AppData\Local\Google\Chrome\User Data',
'--profile-directory=Default',
'--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
));
$caps = DesiredCapabilities::chrome();
$caps->setCapability(ChromeOptions::CAPABILITY, $options);
$caps->setPlatform("Windows");
$driver = RemoteWebDriver::create($host, $caps);
$driver ->manage()->window()->maximize();
$driver->get('https://www.google.com/');
// your code goes here.
$driver->quit();
i guys, in my enviroment with chrome 63 and selenum for control, i have find same problem (60 second on wait for open webpage).
To fix i have find a way by setting a default webpage in chrome ./[user-data-dir]/[Profile]/Preferences file, this is a json data need to insert in "Preferences" file for obtain result
...
"session":{
"restore_on_startup":4,
"startup_urls":[
"http://localhost/test1"
]
}
...
For set "Preferences" from selenium i have use this sample code
ChromeOptions chromeOptions = new ChromeOptions();
//set my user data dir
chromeOptions.addArguments("--user-data-dir=/usr/chromeDataDir/");
//start create data structure to for insert json in "Preferences" file
Map<String, Object> prefs = new HashMap<String, Object>();
prefs.put("session.restore_on_startup", 4);
List<String> urlList = new ArrayList<String>();
urlList.add("http://localhost/test1");
prefs.put("session.startup_urls", urlList);
//set in chromeOptions data structure
chromeOptions.setExperimentalOption("prefs", prefs);
//start chrome
ChromeDriver chromeDriver = new ChromeDriver(chromeOptions);
//this get command for open web page, response instant
chromeDriver.get("http://localhost/test2")
i have find information here https://chromedriver.chromium.org/capabilities

C# not able to get console Logs from PhantomJSDriver (Selenium)

I'm using Selenium in C# with the PhantomJS Driver.
I need to click specific coordinates on a website, that works with using Javascript (im using the ExecutePhantomJS(string script) function of the selenium phantomjs driver). I also need to capture the network traffic. I used browsermob earlier to do that, but for now i cant use it because i also need to use another proxy. So i solved it like that until now:
//Hide CMD of PhantomJS.exe
var driverService = PhantomJSDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
//Initialize Driver and execute Network Script to capture traffic
driver = new PhantomJSDriver(driverService);
driver.ExecutePhantomJS(networkScript);
//Call URL
driver.Navigate().GoToUrl(url);
This is the networkScript:
string networkScript = "var page = this; page.onResourceRequested = function(req) { console.log('received: ' + JSON.stringify(res, undefined, 4)); }; page.onResourceReceived = function(res) { console.log('received: ' + JSON.stringify(res, undefined, 4)); };";
The good thing:
URL is called and all network traffic is logged into the console of the PhantomJS.exe.
But I dont know how I can get these console logs now in my C# code (I need to get specific things like URLs etc.. out of the network log).
I already read the whole afternoon but couldn't find a solution until now. Some of the things I already tried:
1) Tried to use PhantomJSOptions, there u can set LoggingPreferences and later i called driver.Manager().Logs.GetLog(LogType), but there were none of the console logs
2) Dont use console.log inside networkScript. I used require('system').stdout.write(...). It was also logged into console but I cant get the standard output stream of the phantomjs.exe from my C# code.
...
I really dont know how i could solve the problem.
One way would be to log into a .txt file instead of console, but it is very much text and later there will be many opened drivers, so I want to avoid that because then i will have very much and big .txt files

Running a Selenium test in Firefox creates two tabs and runs the in the "non-active" tab

When I create an instance of the Firefox Web driver, it successfully opens Firefox. However, it opens it with two tabs (one "regular" Firefox tab and one IE tab; the IE tab is active and remains active for the duration of the testing unless I manually switch to the tab that the test is actually executing in).
It will run the test in the Firefox tab (i.e. the non-active one).
I'm instantiating my Firefox web driver like this:
var firefoxOptions = new FirefoxOptions()
{
Profile = new FirefoxProfile(),
UseLegacyImplementation = false,
BrowserExecutableLocation = #"C:\Program Files (x86)\Mozilla Firefox\Firefox.exe"
};
firefoxDriver = new FirefoxDriver(firefoxOptions);
firefoxDriver.Manage().Timeouts().ImplicitWait = new TimeSpan(0, 0, 10);
I'd include the code for the unit test, too, but the problem occurs during initialization prior to me running any tests.
Also, when I do cleanup like this:
[TestCleanup]
public void Cleanup()
{
if (firefoxDriver != null)
{
firefoxDriver.Close();
firefoxDriver.Dispose();
}
}
it closes the tab that the test was running in (the Firefox tab). However, it only closes that tab - the IE tab and the browser both stay open.
This question seems to be somewhat related, but the behavior's somewhat different because Selenium isn't trying to actually execute the test in both tabs - it only ever uses the one tab. Also, the OP there was using Firefox 20.0 and I'm using Firefox 52.2.0.
Simply, we can create profile and use it. I answered here Firefox 44.0.1 opening two tabs , when running selenium webdriver code
Another way, we can create profile pro-grammatically like
FirefoxProfile profile= new FirefoxProfile();
profile.setPreference(“browser.startup.homepage”,”https://...");
WebDriver driver = new FirefoxDriver(profile);
Just use about:config in firefox URL , it will provide settings.

Choose a File from OpenFileDialog with C#

I have a little problem - I don't know how to Select a File and Open it in the Mozilla OpenFileDialog.
First, I open the Dialog by pressing "Browse" with Selenium and then I want to put in a File-Name (I know the exact location via Environment variable)
In my case: Environment.GetEnvironmentVariable("Testplatz_Config_Location") + "\TestConfig.fpc"
So my Question, does anyone know how to handle an already open OpenFileDialog using C# - Or is it perhaps possible to handle this with Selenium?
Selenium does not provide any native way to handle windows based pop ups. But we have some third party tools like AutoIT and RobotClass to handle those windows based pop ups. Refer those and give it a a try.
AutoIT with Selenium and Java
Selenium/SeleniumWebDriver does not provide any native way to handle windows based popups. Still, the best way is to miss this popup using
IWebElement element = driver.FindElement(By.Id("file_input"));
element.SendKeys(filePath);
but this is not allways is possible. And if it is not, you can use my lib:
https://github.com/ukushu/DialogCapabilities
by the following way:
OpenFileDialog:
// for English Windows
DialogsEn.OpenFileDialog(#"d:\test.txt");
//For windows with russian GUI
Dialogs.OpenFileDialog("Открыть", #"d:\test.txt");
MultiFile selection in OpenFileDialog:
var filePaths = new string[] {#"d:\test1.txt", #"d:\test2.txt", #"d:\test3.txt"};
//Or for Eng windows:
DialogsEn.OpenFileDialog(filePaths);
//for russian language OS
Dialogs.OpenFileDialog("Открыть", filePaths);
You can use sendKeys() on the file upload element to upload a file using selenium by path. I would suggest using this instead of AutoIT or Robot.
So instead of clicking on the browse button, you send the path directly to the file input element using sendKeys().
Example:
IWebElement element = driver.FindElement(By.Id("file_input"));
element.SendKeys(
Environment.GetEnvironmentVariable("Testplatz_Config_Location") + "\TestConfig.fpc");
i used selenium with Robot class from Java awt. This is my solution
public static void setClipboardData(String string) {
//StringSelection is a class that can be used for copy and paste operations.
StringSelection stringSelection = new StringSelection(string);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
}
public static void uploadFile(String fileLocation) {
try {
//Setting clipboard with file location
setClipboardData(fileLocation);
//native key strokes for CTRL, V and ENTER keys
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
} catch (Exception exp) {
exp.printStackTrace();
}
}

Categories