I am a javascript/java developer and I have been trying to figure out how the selenium webdriver automation framework uploads files from the file system. It is impossible to set a file input via javascript because it is a security violation. Yet somehow webdriver is able to do this with the following command:
driver.setFileDetector(new LocalFileDetector());
WebElement upload = driver.findElement(By.id("myfile"));
upload.sendKeys("/Users/sso/the/local/path/to/darkbulb.jpg");
driver.findElement(By.id("submit")).click();
So they are setting the value by sending keys to it? I don't get it. I have looked through the source code found here:
http://code.google.com/p/selenium/source/checkout
I am still not able to find where they do this.
Edit: My question is not how to do this with selenium, but how did the selenium developers make this possible? How did they get around the security restrictions in javascript? How are they uploading the file?
Nice question buddy...they have written a HTTP proxy to solve the Javascript secuirty restrictions. Using this proxy made it possible to side-step many of the constraints of the "same host origin" policy, where a browser won't allow Javascript to make calls to anything other than the server from which the current page has been served.
Moreover WebDriver uses the alternative approach of firing events at the OS level. As these "native events" aren't generated by the browser this approach circumvents the security restrictions placed on synthesized events and, because they are OS specific, once they are working for one browser on a particular platform reusing the code in another browser is relatively easy.
Most of the content above is referenced from the below..do read the following reference for more details on Selenium internals
http://www.aosabook.org/en/selenium.html
The upload windowns file function HTML codes are:
<input id="fileField" type="file" onchange="document.getElementById('textfield').value=this.value" name="position">
<input type="submit" value="导入">
You can use the following codes to finishing uploading a windows file. It works sucessfully and the codes don't include clicking a upload action.
driver.FileDetector = new LocalFileDetector();
FindElement(By.Id("fileField")).SendKeys(#"C:\Users\admin\Desktop\ProfessionCodes.txt"); FindElement(By.CssSelector("input[type='submit']")).Click();
I have Uploaded photo on Facebook Using Selenium Webdriver and AutoIt
Steps are as below
Step 1
On eclipse code Upto (Upload a Photo) is as below:
WebElement Upload = Firefox.findElement(By.cssSelector("input[id^='u_']"));
Upload.click();
Step 2
Downloaded and install AutoIt: http://www.autoitscript.com/site/autoit/downloads/ (Download ZIP)
Step 3
Write the code as below in notepad and saved it as PhotoUpload.au3
WinWaitActive("File Upload")
Send("D:\Photo0116.jpg")
Send("{ENTER}")
Step 4: Right click on this .au3 File & compile it.
Step 5: Add code in script file as below:
try {
String[] commands = new String[]{};
// Location of the autoit executable
commands = new String[] {"D:\\My softwares\\install software\\selenium\\UploadPhoto3.exe"};
Runtime.getRuntime().exec(commands);
}
catch (IOException e) {}
Step 6: Run script (PhotoUpload.java)
Step 7: Photo get uploaded successfully.
//assuming driver is a healthy WebDriver instance
WebElement fileInput = driver.findElement(By.name("uploadfile"));
fileInput.sendKeys("C:/path/to/file.jpg");
or
driver.findElement(By.id("inputFile")).sendKeys("C:/path/to/file.jpg");
Try this and let me know
In some cases specially with Java you need to create a File object and pass the absolutePath() to the Driver, like the following:
File file = new File(sampleFile);
driver.findElement(By.id("<Your input tag with type of File>")).sendKeys(file.getAbsolutePath());
Sample file is a string that point to the file that needs to be uploaded.
This works for me in Firefox and Chrome.
This helped me to do file upload,
Code :
public class FileUpload {
#Test
public void test() {
WebDriver driver = new FirefoxDriver();
driver.get("http://www.freepdfconvert.com/pdf-word");
driver.findElement(By.id("clientUpload")).click();
driver.switchTo()
.activeElement()
.sendKeys(
"/home/likewise-open/GLOBAL/123/Documents/filename.txt");
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
driver.findElement(By.id("convertButton"));
/*
* driver.switchTo().activeElement()
* .sendKeys("selenium_2_testing_tools.pdf"); ;
*/
{
driver.wait(30000);
} catch (Exception er) {
System.out.println(er);
}
}
}
Related
Using a datasheet, I usually pass a browser name into a class I created to select which browser I want to run my tests from. Recently, I've been working on an app in which I need to download a PDF and then verify its contents. I have everything working successfully other than downloading the PDF. With WebDriverManager, it creates a browser profile every time a test runs, and so, I need to update chromeOptions to download PDFs automatically before at the start of the script.
Here is the code that I already have. I just need help with what to put in the prefs for this to work. -
public static void selectBrowser(String strBrowser) {
switch (strBrowser) {
case "Chrome":
String chromePrefs = "{'goog:chromeOptions':{'prefs':{'profile.default_content_settings.popups':0}}}";
ConfigurationManager.getBundle().setProperty("chrome.additional.capabilities", chromePrefs);
TestBaseProvider.instance().get().setDriver("chromeDriver");
Reporter.log("Chrome Browser was set", MessageTypes.Info);
break;
}
}
After researching for hours, finally found that I needed to use the plugins.always_open_pdf_externally preference. Here is the code for anyone who might need it.
Note, the "goog:" before chromeOptions is necessary since I have WebDriverManager enabled. With 3rd party driver managers, we need to put "goog:" before chromeOptions for it to work.
You can simply put it in the application.properties like this -
chrome.additional.capabilities={"goog:chromeOptions":{"args":[--disable-extensions],"prefs":{"plugins.always_open_pdf_externally":true}}}
or you can put it in the code I have up top like this
String chromePrefs = "{'goog:chromeOptions':{'args':[],'prefs':{\"plugins.always_open_pdf_externally\":true}}}";
I need to have selenium automation download a file using firefox.
The automation successfully clicks the download, but a MIME opens to ask what to do. I need selenium to ignore this and just download the file.
Everything I have read days I should be able to use a function like this
const firefoxOption = new firefox.Options().set_preference(
'browser.helperApps.neverAsk.saveToDisk',
'application/zip,text/csv,text/txt',
);
But when I run this, it fails before it ever gets to clicking the download because this piece throws an error.
TypeError: (intermediate value).set_preference is not a function
what am I doing wrong??
ALL answers listed on SO show this exact code snippet and it is not working.
const firefoxOption = new firefox.Options().setPreference(
'browser.helperApps.neverAsk.saveToDisk',
'application/zip,text/csv,text/txt',
);
That method is for python
https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/firefox_exports_Options.html
During execution I want to know which browser currently the script is running and do some actions based on the browser the script is running.
I am using
Option 1:
if (new QAFExtendedWebDriver().getUnderLayingDriver().equals("ChromeDriver")) {
// Do`enter code here` some thing if this is a chrome browser
}
else if (new QAFExtendedWebDriver().getUnderLayingDriver() instanceof FirefoxDriver) {
}
Thsi option is not working during my excution. What is the way to know which browser I am in ?
Below are few examples:
//to get driver name for this thread which provided using driver.name
String drivername = TestBaseProvider.instance().get().getDriverName();
//if running in browser, browser name for this thread, will not be avialable for mobile native or hybrid apps
String browserName =getDriver().getCapabilities().getBrowserName();
//underlying driver class name, which can be remote driver if you are using remote driver
String driverClassname = getDriver().getUnderLayingDriver().getClass().getSimpleName();
you didn't provided details about what you are trying to achieve. If you want to do something when browser opens, you can utilize driver listener.
If you are using bdd and you have platform/browser specific code, instead of using if else you can have separate step implementation for each platform/browser in different package and load step provider package accordingly, for example:
step.provider.pkg=com.exmple.steps.common;com.exmple.steps.chrome
I am trying to upload a file in the webpage through selenium webdriver, and i have written the below code
driver.findElement(By.cssSelector("#collapseDocuments > div > button.button.ng-isolatescope")).sendKeys("C:\\Users\\siva.247588\\Desktop\\Clarient+AML+Questionnaire.docx");
The CSS selector is that of the browse button.
I am getting the below error whwn i run this:
Exception in thread "main" org.openqa.selenium.WebDriverException: unknown error: cannot focus element
What is wrong with my code? Could any one advise?
When you try to upload a file, the control is shifted to our local machine from website where we were writing scripts.
So normal click method and select method won't work. You can use robot method to browse and upload some file from your local machine to websites.
Hope this help you..
See the below link for help:
http://www.seleniumeasy.com/selenium-tutorials/webdriver-file-upload-using-robots
I've used this somewhere , hope you can relate this:
Robot rb = new Robot();
rb.keyPress(KeyEvent.VK_A);
rb.keyRelease(KeyEvent.VK_A);
rb.keyPress(KeyEvent.VK_L);
rb.keyRelease(KeyEvent.VK_L);
rb.keyPress(KeyEvent.VK_E);
rb.keyRelease(KeyEvent.VK_E);
rb.keyPress(KeyEvent.VK_R);
rb.keyRelease(KeyEvent.VK_R);
rb.keyPress(KeyEvent.VK_T);
rb.keyRelease(KeyEvent.VK_T);
Thread.sleep(4000L);
rb.keyPress(KeyEvent.VK_TAB);
rb.keyRelease(KeyEvent.VK_TAB);
Thread.sleep(4000L);
rb.keyPress(KeyEvent.VK_ENTER);
rb.keyRelease(KeyEvent.VK_ENTER);
This will browse and upload a file with name "Alert"
If you need more help, kindly provide me code and what you want to upload , I'll help you to resolve your issue.
As #theroot mentioned AutoIT is a good solution, but the downside is it works only on windows based platforms. The best solution so far that I have come across for upload or focus outside browser situations is using Sikuli. Example code is below
Screen sikuliObject= new Screen(); // Creating Screen class object
Pattern add = new Pattern("path to the image.png"); // Path of the upload button image.
sikuliObject.click(add); // Click on Upload button
Thread.sleep(2000); // Wait for 2 seconds for upload window pop-up.
sikuliObject.type("Path of the uploading file and click on enter."+ Key.ENTER );
//Path of the uploading file and click on enter.
Thread.sleep(2000); // Wait for 2 seconds to load the file.
I've once had a similar problem (I'm not sure anymore if it threw a "not visible" exception or the "could not focus"one) and the problem was that the input Element wasn't accessible because it had no dimensions. I've changed the DOM information using the JavaScriptExecuter and afterwards it worked fine. Just go through your page with Firebug and look if the element is really visible.
the popup window is only happening if I use the Fire Fox browser otherwise, is there a way to fix this problem? I have to enter userid/password every time the i use FF as my browser.
currently, I am entering every time i run my test which is very painful but looking to make it more automated....
I have goggled and found two links here and here but no avail
http://username:password#xyz.com
This worked for me (xyz.com being the site name)
After spending hours reading I finally found the solution which works pretty well and I hope this will help others too. - Enjoy!!
First - follow this steps:
1) Open the FireFox browser
2) Type the following `about:config`
3) Look for `network.http.phishy-userpass-length` if you don't find then create a new Integer key
Create a new Integer key (right-click->New->Integer): `network.http.phishy-userpass-length` with value `255`
Second: You need to create a Firefox driver with the following:
FirefoxProfile profile = new FirefoxProfile();
profile.SetPreference("network.http.phishy-userpass-length", 255);
profile.SetPreference("network.automatic-ntlm-auth.trusted-uris", "YOUR HOST ADDRESS HERE");
_driver = new FirefoxDriver(profile);
let me know if you have any questions.
If this is a windows user account & password, then you need to enable the integrated windows login by setting
network.negotiate-auth.delegation-uris: MyIISServer.domain.com
network.automatic-ntlm-auth.trusted-uris: MyIISServer.domain.com
network.automatic-ntlm-auth.allow-proxies: True
network.negotiate-auth.allow-proxies: True
in the Firefox profile that WebDriver starts. Once you have the profile created and saved (run "Firefox -P" when no other instances are running to select a profile), you can do this in the code:
File profileDir = new File("C:/wherever/SeleniumFirefoxProfile");
FirefoxProfile profile = new FirefoxProfile(profileDir);
profile.setEnableNativeEvents(true);
driver = new FirefoxDriver(profile);
I have had to handle these a few times, but my approach is using a script outside Selenium. Are you working on Windows?
Basically what you do is this:
1) Prior to loading the page, clicking the URL, etc that causes that dialog to appear:
-- Launch an asynchronous script to handle the login
2) Then load the page, click the link, etc
-- Selenium will block until your asynch script completes
The async script:
-- Sleep for a few seconds
-- Activate the dialog
-- Send the username
-- Send a TAB
-- Send the password
-- Send a TAB
-- Send the Enter Key
If you are working on windows, I can post sample scripts to handle this. I've done it with Java and C#, but I would guess that basically the same thing would work regardless of how you are writing your tests (unless you are strictly using the FF plugin, in which case this won't work).
Let me know if you'd like more details.
You can use a FF plugin "autoauth". Download this plugin and create Firefox instance by the following way:
FirefoxProfile firefoxProfile = new ProfilesIni().getProfile("default");
File pluginAutoAuth = new File("D:\\autoauth-2.1-fx+fn.xpi");
firefoxProfile.addExtension(pluginAutoAuth);
driver = new FirefoxDriver(firefoxProfile);
I used "autoauth-2.1-fx+fn.xpi"