Handle file upload with Selenium Server Standalone - java

I try to execute testsuite on a remote host with use of Selenium Standalone Server. It should upload a file. I use code below to handle file uploads:
FileBrowserDialogHandler fileBrowserDialogHandler = new FileBrowserDialogHandler();
fileBrowserDialogHandler.fileUploadDialog(fileSource);
It doesn't work when I execute it remotely, because it is not able to open file chooser window.
Input field looks like this on webpage:
<input type="text" id="file-path">
I replaced current solution with WebElement based one to avoid graphical window, but it doesn't work.
WebElement fileInput = driver.findElement(By.id("filepathelement"));
fileInput.sendKeys(filepath);
Input type is not file, so code below is not working:
driver.findElement(By.id("myUploadElement")).sendKeys("<absolutePathToMyFile>");

Upload a file using Java Selenium: sendKeys() or Robot Class.
This method is to Set the specified file-path to the ClipBoard.
Copy data to ClipBoard as.
WIN [ Ctrl + C ]
MAC [ Command ⌘ + C ] - way to tell full Path of file.
public static void setClipboardData(String filePath) {
StringSelection stringSelection = new StringSelection( filePath );
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
}
Locate the file on Finder Window and press OK to select the file.
WIN [ Ctrl + V ]
MAC
"Go To Folder" - Command ⌘ + Shift + G.
Paste - Command ⌘ + V and
press OK to open it.
enum Action {
WIN, MAC, LINUX, SEND_KEYS;
}
public static boolean FileUpload(String locator, String filePath, Action type) {
WebDriverWait explicitWait = new WebDriverWait(driver, 10);
WebElement element = explicitWait.until(ExpectedConditions.elementToBeClickable( By.xpath(locator) ));
if( type == Action.SEND_KEYS ) {
element.sendKeys( filePath );
return true;
} else {
try {
element.click();
Thread.sleep( 1000 * 5 );
setClipboardData(filePath);
Robot robot = new Robot();
if( type == Action.MAC ) { // Apple's Unix-based operating system.
// “Go To Folder” on Mac - Hit Command+Shift+G on a Finder window.
robot.keyPress(KeyEvent.VK_META);
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_G);
robot.keyRelease(KeyEvent.VK_G);
robot.keyRelease(KeyEvent.VK_SHIFT);
robot.keyRelease(KeyEvent.VK_META);
// Paste the clipBoard content - Command ⌘ + V.
robot.keyPress(KeyEvent.VK_META);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_META);
// Press Enter (GO - To bring up the file.)
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
return true;
} else if ( type == Action.WIN || type == Action.LINUX ) { // Ctrl + V to paste the content.
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
}
robot.delay( 1000 * 4 );
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
return true;
} catch (AWTException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return false;
}
File Upload Test :- You can find fileUploadBytes.html file by clicking on Try it Yourself.
public static void uploadTest( RemoteWebDriver driver ) throws Exception {
//driver.setFileDetector(new LocalFileDetector());
String baseUrl = "file:///D:/fileUploadBytes.html";
driver.get( baseUrl );
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
FileUpload("//input[1]", "D:\\log.txt", Action.SEND_KEYS);
Thread.sleep( 1000 * 10 );
FileUpload("//input[1]", "D:\\DB_SQL.txt", Action.WIN);
Thread.sleep( 1000 * 10 );
driver.quit();
}
For more information see my post.

The file(s) in question should be available on the machine (be it local or remote server) that your program is running on, for example, in your /resources directory
On your local machine, this should work.
chooseFileElement.waitForVisible().type("/file/path/filename.jpg");
clickButton("Attach File");
On Remote Server however, you need to associate a new instance of LocalFileDetector to the <input type=file> element.
LocalFileDetector detector = new LocalFileDetector();
File localFile = detector.getLocalFile("/file/path/filename.jpg");
RemoteWebElement input = (RemoteWebElement) myDriver().findElement(By.id("fileUpload"));
input.setFileDetector(detector);
input.sendKeys(localFile.getAbsolutePath());
clickButton("Attach File");

Related

File not getting uploaded using java.awt.Robot class in Java

I tried implementing Robot class in my Selenium Test cases written using Java. I am getting a strange issue there. So when I am trying to run those test cases on my local machine (Windows 10 Enterprise Edition) and monitoring it's working fine and the file is getting uploaded. But when I am trying to run those in a remote server (Windows Server 2012) and monitoring those it's again working fine but when I am leaving those test cases for the entire night to run I found that the File Explorer dialogue box is opening but it's never getting close. It might be that the file path is not getting pasted and the Enter (Ok) button is not getting clicked.
public void uploadFile(String path) {
String abspath = _getAbsolutePath(path);
StringSelection stringSelection = new StringSelection(abspath);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
Robot robot = null;
try {
// native key strokes for CTRL, V and ENTER keys
robot = new Robot();
robot.setAutoDelay(5000);
robot.keyPress(KeyEvent.VK_CONTROL); // Press Ctrl
robot.keyPress(KeyEvent.VK_V); // Pres V
robot.keyRelease(KeyEvent.VK_V); // Release Ctrl
robot.keyRelease(KeyEvent.VK_CONTROL); // Release V
robot.setAutoDelay(5000);
robot.keyPress(KeyEvent.VK_ENTER); // Press Enter
robot.keyRelease(KeyEvent.VK_ENTER); // Release Enter
} catch (Exception exp) {
exp.printStackTrace();
}
}

Download a file in IE using Selenium

OK, so I am trying to export a file using Selenium. My browser is IE. When I click on the export button a native windows dialogue box comes up.
Image of the pop up
I have to click on the Save button. For this I tried using AutoIT but its not working.
exportbutton.click();
Thread.sleep(2000);
driver.switchTo().activeElement();
AutoItX x = new AutoItX();
x.winActivate("window name");
x.winWaitActive("window name");
x.controlClick("window name", "", "[CLASS:Button; INSTANCE:2]");
This did not work. So I decided to use Robot class and perform the keyboard clicks Atl + S, as this will also enable the browser to Save the file. That did not work either.
try
{
Robot robot = new Robot();
robot.setAutoDelay(250);
robot.keyPress(KeyEvent.VK_ALT);
Thread.sleep(1000);
robot.keyPress(KeyEvent.VK_S);
robot.keyRelease(KeyEvent.VK_ALT);
robot.keyRelease(KeyEvent.VK_S);
}
catch (AWTException e)
{
e.printStackTrace();
}
There is some problem with the web driver I suppose because I tried printing a line after exportbutton.click() and it did not get printed either.
I am new so I can't understand the problem. Please help me out.
So, the problem was that the cursor gets stuck sometimes when you call the click() function. So as a solution I used the Robot class to move my cursor and click on the export button and then I used Robot class to press Alt+S, which is a keyboard shortcut to save a file in IE.
To click on the button I used
try
{
Robot robot = new Robot();
Thread.sleep(2000);
robot.mouseMove(coordinates.getX()+100,coordinates.getY()-400);
Thread.sleep(2000);
robot.mousePress( InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
catch (AWTException e)
{
e.printStackTrace();
}
To get the coordinates in the above snippet I used the following line
Point coordinates = driver.findElement(By.id("id")).getLocation();
System.out.println("Co-ordinates"+coordinates);
And to press Alt+S I used the following code
try
{
Robot robot = new Robot();
robot.setAutoDelay(250);
robot.keyPress(KeyEvent.VK_ALT);
Thread.sleep(1000);
robot.keyPress(KeyEvent.VK_S);
robot.keyRelease(KeyEvent.VK_ALT);
robot.keyRelease(KeyEvent.VK_S);
}
catch (AWTException e)
{
e.printStackTrace();
}
I had the same problem. I came to realization that
button.click()
does not work very well in this case (with IE driver). So instead of clicking the button I tried this:
robot = new Robot();
button.sendKeys("""");
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
This just gives focus on button and 'presses' it by hitting enter.
Sorry, I wrote approach how to upload the file. If you want to download - use the same approach, but use another buttons: Instead buttons Cntrl + V you can use button Tab to find control of Save/Save as and then Press Enter. Before it, you can paste String with file path ( directory where you want to upload your file).
Auto IT is not required to handle this. just use the below code and it works fine.
If we give element.click on the element, control stops there and hence we use element.sendkeys("") and robot.keyPress(KeyEvent.VK_ENTER);
Below is the complete code:
Robot robot = new Robot();
//get the focus on the element..don't use click since it stalls the driver
element.sendKeys("");
//simulate pressing enter
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
//wait for the modal dialog to open
Thread.sleep(2000);
//press s key to save
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_N);
robot.keyRelease(KeyEvent.VK_N);
robot.keyRelease(KeyEvent.VK_ALT);
Thread.sleep(2000);
//press enter to save the file with default name and in default location
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
Thread.sleep(2000);
robot.keyPress(KeyEvent.VK_DOWN);
robot.keyRelease(KeyEvent.VK_DOWN);
Thread.sleep(2000);
robot.keyPress(KeyEvent.VK_DOWN);
robot.keyRelease(KeyEvent.VK_DOWN);
Thread.sleep(2000);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
Thread.sleep(2000);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
I used AutoIt and it works in windows 10. Refer to the below AutoIt script :
Sleep(9000);
Local $hIE = WinGetHandle("[Class:IEFrame]");
Local $hCtrl = ControlGetHandle($hIE, "", "[ClassNN:DirectUIHWND1]");
If WinExists($hIE,"") Then
WinActivate($hIE,"");
ControlSend($hIE ,"",$hCtrl,"{F6}");
Sleep(1500);
ControlSend($hIE ,"",$hCtrl,"{TAB}");
Sleep(1500);
ControlSend($hIE ,"",$hCtrl,"{ENTER}");
EndIf
Sleep(5000);
If WinExists($hIE,"") Then
WinActivate($hIE,"");
ControlSend($hIE ,"",$hCtrl,"{F6}");
Sleep(1500);
ControlSend($hIE ,"",$hCtrl,"{TAB}");
Sleep(1500);
ControlSend($hIE ,"",$hCtrl,"{TAB}");
Sleep(1500);
ControlSend($hIE ,"",$hCtrl,"{TAB}");
Sleep(1500);
ControlSend($hIE ,"",$hCtrl,"{ENTER}");
EndIf
Sleep(5000);
It clicks the save button and also closes the next alert.
Please adjust Sleep() accordingly.
This is a hack by Dave Haefner. If you don't care if a file was downloaded or not and you want to confirm only that a file can be downloaded, you can use an HTTP request. Instead of downloading the file you'll receive the header information for the file which contains things like the content type and length. With this information, you can confirm the file is you expect.
String link = driver.findElement(By.cssSelector("download-link-element")).getAttribute("href");
HttpClient httpClient = HttpClientBuilder.create().build();
HttpHead request = new HttpHead(link);
HttpResponse response = httpClient.execute(request);
String contentType = response.getFirstHeader("Content-Type").getValue();
int contentLength = Integer.parseInt(response.getFirstHeader("Content-Length").getValue());
assertThat(contentType, is("application/octet-stream"));
assertThat(contentLength, is(not(0)));

Handle Login/Password Popup Selenium JAVA

we are trying to authenticate our website https://staging.rockettes.com.
It asks for a user name and password, which we have to supply via our selenium java code.
Can you help?
Thanks,
Rachit
You will need to construct a testURL before you call your driver.get command.
So assuming that the username=admin and pass=pass
String testURL = "https://" + "admin" + ":" + "pass" + "#" + "staging.rockettes.com/";
Now you can safely call your driver.get as following:
driver.get(testURL);
Best of luck!
Updated answer after op's comment:
Okay then, so in order to accept the alert you can use:
WebDriverWait waitTime = new WebDriverWait(driver, 5);
Boolean isAlertPresent = wait.until(ExpectedConditions.alertIsPresent());
if(isAlertPresent==true){
Alert alert = driver.switchTo().alert();
alertText = alert.getText();
alert.accept();
}
else{
System.out.println("No alert was present!")
}
I think that, the pop-up on hitting the ur URL is not web based alert rather it's a window alert, so you can handle it with the help of AutoIT or you can do this using Robot class as follows (though not recommended):
String userName = "ADMIN";
StringSelection stringSelection = new StringSelection(userName);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, stringSelection);
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_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
String password = "PASS";
StringSelection stringSelection1 = new StringSelection(password);
Clipboard clipboard1 = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard1.setContents(stringSelection1, stringSelection1);
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
if your handling popups, use the following command before passing username and password
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
You can used any ways below:
1. By pass with URL:
String url= "https://" + "username" + ":" + "password" + "#" + "staging.rockettes.com";
driver.get(url);
2. Alert
Alert alert = wait.until(ExpectedConditions.alertIsPresent());
alert.authenticateUsing(new UserAndPassword("username", "password"));
3. AutoIT
Autoit script to handle the authentication window:
WinWaitActive("Windows Security")
Send("username")
Send("{TAB}")
Send("password")
Send("{ENTER}")
Save this file as “auth.au3"
Right click on the file and chose “Compile Script (x86)” option and it will make “auth.exe”
Now write the sample java code to use it:
driver.get("https://staging.rockettes.com/");
Runtime.getRuntime().exec("E:\\AutoIT\\auth.exe");
4. Sikuli
Screen screen = new Screen();
driver = new FirefoxDriver();
driver.get("https://staging.rockettes.com/");
screen.type("C:\\username.png"),"username");
screen.type("C:\\password.png","password");
screen.click("C:\\okButton.png");
Try this,
below solution is specific to chrome and the same approach can be applied for different browsers as well
public String getBaseUrl() {
StringBuilder stagingURl = new StringBuilder();
try {
URL url = new URL(baseUrl);
stagingURl
.append(url.getProtocol())
.append("://")
.append(URLEncoder.encode(stagingUsername, "utf-8"))
.append(":")
.append(URLEncoder.encode(stagingPassword, "utf-8"))
.append("#")
.append("staging.rockettes.com");
return stagingURl.toString();
} catch (UnsupportedEncodingException | MalformedURLException e) {
return "Issue while encoding URL" + e.getMessage();
}
The given solutions wouldn't work using the selenium get() method to load such a URL prompting for authentication with a JavaScript Popup, I was also stuck here for a long time. It's because of Chrome driver will not allow such authentication techniques after the update 59 (probably). There are still backdoors via Selenium using the JavaScript engine in the browser to load such URLs.
driver.get("https://www.google.com");
JavascriptExecutor jse = (JavascriptExecutor) driver;
URL = "https://username:password#www.example.com";
jse.executeScript("window.open('"+URL+"')");

Selenium sendkeys not inputting the text

I have the below code which will click on a button in window. On clicking the button,the current window is closed and new window will be opened. Some text will be inputted in a textbox in new window.
WebElement element=null;
try {
driver.getWindowHandles();
for (String winHandle : driver.getWindowHandles()) {
driver.switchTo().window(winHandle);
try {
element = driver.findElement(By.xpath("//*[#id='username']"));
} catch (Exception e) {
continue;
}
if (element.isDisplayed()) {
windowFound = 1;
break;
}
}
}
element.sendKeys("Testingusername");
Last line to input send keys is not failing. But the actual text is not entered into the textbox.
This works well in chrome. Issue is with Internet explorer only.
Selenium : 2.53.1
IE 11
Try to focus on the element let say
element.Clear();
element.sendKeys("testingUserName");
and put this code to try catch to see if you get any exceptions
Few things :
verify if you've located the correct element in IE as it sometimes XPath behavior is different in IE.
try to confirm the attributes of the element under question with the attributes observed in other browsers.
try using IE Driver 32 bit version for IE11 browser.
if nothing works then there is no harm in using javascript sendKeys. it's not a bad practise
Actions a = new Actions(driver);
a.SendKeys(element, "Your text to input").Build().Perform();
Note: Works in IE11
try this one This works for me
WebElement element=null;
try {
driver.getWindowHandles();
for (String winHandle : driver.getWindowHandles()) {
driver.switchTo().window(winHandle);
try {
element = driver.findElement(By.xpath("//*[#id='username']"));
} catch (Exception e) {
continue;
}
if (element.isDisplayed()) {
windowFound = 1;
break;
}
}
}
element.click();
String text = "your text that you want to enter";
StringSelection stringSelection = new StringSelection(text);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, stringSelection);
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
I think it's all about timing.
You should consider adding Thread.Sleep(3000); to your code:
Thread.Sleep(3000);
element.sendKeys("Testingusername");

Not able to save image at desired location/folder using AutoIT with Selenium Webdriver

I am trying to download an image from a website using AutoIT(to control OS Pop up Window) and Selenium Webdriver(to open the website from where i am trying to download the pic).
I am getting the OS Pop Up window and by using AutoIT i am able to send the new location for saving the file i.e ,
C:\Users\Casper\Desktop\Resume\Pic.jpg
But once the script clicks on the save button the pic get downloaded but with a different name and at a different/default location.
AutoIT Script which i am using is written below-
WinWait("Save As");
WinActive("Save As");
Sleep(1000);
ControlSetText("Save As","","[CLASS:Edit; INSTANCE:1]","C:\Users\Casper\Desktop\Resume\Pic.jpg");
Sleep(1000);
ControlClick("Save As","","[CLASS:Button; INSTANCE:1]");
Sleep(1000);
Java code for Webdriver-
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.io.IOException;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
public class Practice {
public void pic() throws AWTException, IOException, InterruptedException{
WebDriver driver;
System.setProperty("webdriver.chrome.driver","E:\\chromedriver.exe");
driver = new ChromeDriver();
try{
driver.navigate().to("http://i.stack.imgur.com/rKZOx.jpg?s=128&g=1");
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(By.xpath("/html/body/img"))).perform();
action.contextClick().perform();
Robot robo = new Robot();
robo.keyPress(KeyEvent.VK_V);
robo.keyRelease(KeyEvent.VK_V);
// Here i am getting the os window but don't know how to send the desired location
String command ="C:\\Users\\Casper\\Desktop\\Resume\\Pic.exe";
Runtime.getRuntime().exec(command);
}catch(Exception e){
e.printStackTrace();
driver.close();
}//catch
finally{
Thread.sleep(6000);
System.out.println("command");
driver.quit();
System.exit(0);
}
}//method
As you can see it is succsesfully sending the new address to the OS Window Pop (inside red circle) but after clicking on Save button the image is getting downloaded at different location C:\Users\Casper\Downloads (my default download folder) with a different name -rKZOx
Now i got the answer. Since i was not waiting for the window to open properly i was not able to download the file at my desired location. I just put a Thread wait for 2 seconds and now its working fine and saving the image at the desired location. Changed code is-
Rest of the code remain same the below code is changed -
Thread.wait(2000);
String command ="C:\\Users\\Casper\\Desktop\\Resume\\Pic.exe";
Runtime.getRuntime().exec(command);
And now i am able to save image at e drive with the name of the file as pic
Maybe try something like this:
Global $goExplorer = _myExplorerSelectUpload("C:\Users\Casper\Desktop\Resume", "Pic.exe", "Save As")
If #error Then Exit 101
ControlClick(HWnd($goExplorer.hwnd),"","[CLASS:Button; INSTANCE:1]")
Func _myExplorerSelectUpload($szDirectory, $szFileName, $vWndOrTitle, $sText = "")
Local $oExplorer = _explorerWinFindObj($vWndOrTitle, $sText)
If #error Then Return SetError(#error, #extended, 0)
$oExplorer.Navigate($szDirectory)
If #error Then Return SetError(3, 0, 0)
; might try a sleep here if it's rendering too fast
$oExplorer.document.SelectItem( _
$oExplorer.document.Folder.ParseName($szFileName), 1 + 4 + 8 + 16)
If #error Then Return SetError(5, 0, 0)
; return the object you're working with
Return $oExplorer
EndFunc
Func _explorerWinFindObj($vWndOrTitle, $sText = "")
Local $oShell = ObjCreate("Shell.Application")
If Not IsObj($oShell) Then
Return SetError(1, 0, 0)
EndIf
Local $oWins = $oShell.windows
Local $hWnd, $vDummy
For $oWin In $oWins
; browser confirmation - start
$vDummy = $oWin.type
If Not #error Then ContinueLoop ; if not/browser
$vDummy = $oWin.document.title
If Not #error Then ContinueLoop
; browser confirmation - end
; bypassed IE windows, now to find window
$hWnd = HWnd($oWin.hwnd)
If IsHWnd($vWndOrTitle) Then
; hwnd was passed, does it equal hwnd of object
If $hWnd = $vWndOrTitle Then Return $oWin
Else
; match titles (exact match)
If WinGetTitle($hWnd) = $vWndOrTitle Then
; match text, only in string text match
If $sText And Not _
StringInStr(WinGetText($hWnd), $sText) Then
ContinueLoop
EndIf
Return $oWin
; hwnd to hwnd
ElseIf WinGetHandle($vWndOrTitle, $sText) = $hWnd Then
Return $oWin
EndIf
EndIf
Next
Return SetError(2, 0, 0)
EndFunc

Categories

Resources