org.openqa.selenium.WebDriverException: unknown error: cannot focus element on trying to upload a file in selenium - selenium

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.

Related

Selenium JS set_preference

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

How to create a better screenshot during the selenium automation in JAVA?

I am creating automated test cases by using selenium 3 & testng. Everything looks good, except the screenshots that are generated. Here is my piece of code to create screenshots PNG files:
file = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file, new File(pngfile));
which is pretty standard way to do it, but the quality of the created PNG file is not so good.
As you can see from following PNG file. In the picture, the email value ( "....#yahoo.com"), which should be at the upper-right corner of the web-page and should be as high as the other navigation bar elements on the left side. But in the created PNG file, this item has been squeezed to the lower level, which is not what I am looking for. Any ideas ? Thanks for the help !
Make sure your window is the right size when you're opening the browser. You can do this via visual inspection or using Selenium's getSize method. I assume you're using Java, but here it is in Python as well.
Then, if the window is not of the correct size in order to guarantee that your webpage's CSS doesn't break, use setSize. Here is that method in Python as well.
Afterwards, your screenshot should look like the window does.
Please try this,
public void calltakeScreenShot(String SSName) throws Exception
{
File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
BufferedImage img = ImageIO.read(screen);
File filetest = Paths.get(".").toAbsolutePath().normalize().toFile();
ImageIO.write(img, "png", new File(filetest + "\\Screenshots\\" + SSName + ".png"));
}
Additionally Here you just need to pre-created Screenshots folder in your Project directory. It will store it by getting absolute path of your project. Also you can manage screenshot name by passing argument.
After several day's research, here is my latest summary.
A). If I was executing the scripts, that is not in the "headless" mode. When the selenium test case is being executed, I will see a new browser session is being popped up and get to that URL, click some buttons, etc, ... till the execution is finished. In this execution, the screenshot page will be saved in good quality.
B). For the same selenium test script, if I am including one extra ChromeOptions setting, which is "--headless", I will not see any browser being brought up during the execution. And once execution is finished, I will get the screenshot with such squeezed web elements.
Comments ?

Automate a button click on chrome://extensions page using selenium webdriver

I'm trying to write an automated test that will automate the process of updating a google chrome extension. I'm not aware of another method of doing this automatically so here is what I'm currently trying to do:
Open the chrome extensions page (as far as I'm aware this is just an html page unless I'm missing something).
Click on the "Update extensions" button
Here is what I have tried having opened the chrome extensions page:
IwebElement UpdateButton = driver.findelement(By.Id("update-extensions-now"));
UpdateButton.Click();
For some reason the button click is not registering. I have tried some other locators such as CSS path and Xpath but they don't work either. Also, when I debug this test, it passes fine so I know it's not an issue with any of my locators. I have (as a test) tried to automate clicks on the other elements on this page and it's the same issue. I can't get a handle on any elements on the chrome://extensions page at all.
Has anyone encountered this or have any ideas as to what's going on?
You can use the Chrome extensions API to auto-update required extension.
Find the file "manifest.json" in the default Google Chrome
C:\Users\*UserName*\AppData\Local\Google\Chrome\User Data\Default\Extensions
There find the update URL of your extension:
{
"name": "My extension",
...
"update_url": "http://myhost.com/mytestextension/updates.xml",
...
}
The returned XML by the Google server looks like:
<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
<app appid='yourAppID'>
<updatecheck codebase='http://myhost.com/mytestextension/mte_v2.crx' version='2.0' />
</app>
</gupdate>
appid
The extension or app ID, generated based on a hash of the public key, as described in Packaging. You can find the ID of an extension or Chrome App by going to the Extensions page (chrome://extensions).
codebase
A URL to the .crx file.
version
Used by the client to determine whether it should download the .crx file specified by codebase. It should match the value of "version" in the .crx file's manifest.json file.
The update manifest XML file may contain information about multiple extensions by including multiple elements.
Another option is to use the --extensions-update-frequency command-line flag to set a more frequent interval in seconds. For example, to make checks run every 45 seconds, run Google Chrome like this:
chrome.exe --extensions-update-frequency=45
Note that this affects checks for all installed extensions and apps, so consider the bandwidth and server load implications of this. You may want to temporarily uninstall all but the one you are testing with, and should not run with this option turned on during normal browser usage.
The request to update each individual extension would be:
http://test.com/extension_updates.php?x=id%3DyourAppID%26v%3D1.1
You can find even more detailed information on exntesions developers site: https://developer.chrome.com/extensions
If you look at the HTML of the "chrome://extensions" page you will notice that the "Update extensions now" button is contained within an iframe. You need to switch to the iframe before trying to register a button click. i.e:
(This is in c#. Note that this code is written from memory so it may not be 100% accurate. Also, you will want to write more robust method. This code just quickly demonstrates that by switching to the iframe, it will work ok)
String ChromeExtensionsPage = "chrome://extensions";
driver.Navigate().GoToUrl(ChromeExtensionsPage);
driver.Switchto().Frame("DesiredFrame");
IwebElement UpdateButton = driver.findelement(By.Id("DesiredButtonID"));
UpdateButton.Click();

Selenium: Can't SendKeys() to an item that was below the visible window but was made visible by Click()

I have this problem with a text field that is visible at the time of the SendKeys. I'm using IEDriverServer.exe and C#.
Here's how I can reproduce the problem:
The text field in question is visible in the window but you have to scroll down to see it. To scroll down I click on the element using code like this:
var element = driver.FindElement(By.Xpath("…"));
element.Click();
This scrolls the window down and makes the text field visible.
But when I try to send text to now-visible window:
element.SendKeys("blah");
I get the exception:
When_applicant_enters_application.Should_be_instantly_approved_on_external threw exception: OpenQA.Selenium.ElementNotVisibleException: Element is not displayed
How can I fix or workaround this problem?
Selenium version: 2.32.1
OS: Windows 7
Browser: IE
Browser version: 9.0.15
I've written code demonstrating the problem and submitted it to the Selenium tech support volunteers.
The full discussion is at http://code.google.com/p/selenium/issues/detail?id=5620
but the take-home is:
// Doesn't work
// driver = new InternetExplorerDriver();
// driver.Navigate().GoToUrl(#"D:\CGY\selenium\Bug5620\Bug5620\Bug5620.htm");
// Works
// driver = new FirefoxDriver();
// driver.Navigate().GoToUrl(#"D:\CGY\selenium\Bug5620\Bug5620\Bug5620.htm");
// Works
driver = new InternetExplorerDriver();
driver.Navigate().GoToUrl(#"http://localhost:8080/Bug5620/"); // Hosted on Tomcat
so there may be a problem that possibly involves IE, IE security settings, Visual Studio local servers and/or the IE Driver. This may not even be a code problem, but something that needs to be documented, since other people are apparently running into the problem.
I don't know where the problem is exactly but I do have a work-around at this point, which is to use the Firefox Driver.
Thanks for your help, Jim. If you find out a better way of dealing with the problem, please add an answer here for the other folks.

how does selenium webdriver upload files to the browser?

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);
}
}
}