Selenium moveByOffset doesn't do anything - java

I'm running latest selenium 2.41 with Firefox 28.0 on Linux Xubuntu 13.10
I'm trying to get FirefoxDriver to move the mouse over the page (in my test, I've used the wired webpage, that has a lot of hover-activated menus), but the moveByOffset is not doing anything noticeable to the mouse, at all:
package org.openqa.mytest;
import java.util.List;
import java.io.File;
import java.lang.*;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.*;
import org.apache.commons.io.FileUtils;
public class Example {
public static void main(String[] args) throws Exception {
// The Firefox driver supports javascript
FirefoxProfile profile = new FirefoxProfile();
profile.setEnableNativeEvents(true);
WebDriver driver = new FirefoxDriver(profile);
// Go to the Google Suggest home page
driver.get("http://www.wired.com");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// now save the screenshto to a file some place
FileUtils.copyFile(scrFile, new File("./screenshot.png"));
Actions builder = new Actions(driver);
Action moveM = builder.moveByOffset(40, 40).build();
moveM.perform();
Action click = builder.click().build();
click.perform();
//click.release();
Action moveM2 = builder.moveByOffset(50, 50).build();
moveM2.perform();
Action click2 = builder.click().build();
click2.perform();
//click2.release();
Action moveM3 = builder.moveByOffset(150, 540).build();
moveM3.perform();
for( int i=0; i < 1000; i++)
{
moveM = builder.moveByOffset(200, 200).build();
moveM.perform();
Thread.sleep(500);
moveM = builder.moveByOffset(-200, -200).build();
moveM.perform();
Thread.sleep(500);
}
//Action click3 = builder.click().build();
//click3.perform();
//click3.release();
scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// now save the screenshto to a file some place
FileUtils.copyFile(scrFile, new File("./screenshot2.png"));
driver.quit();
}
}
I'm expecting the mouse the move over the different elements and trigger all the hover actions, but nothing is happening

The method moveByOffset of class Actions is or has been broken. See Selenium WebDriver Bug 3578
(The error is described some lines more down in this bug document).
A project member (barancev) claims that this error should have been fixed with Selenium version 2.42.
Nevertheless I found the same error in version 2.44 running on openSUSE 12.3 with Firefox 33.0. moveToElement works, moveToOffset doesn't.

I struggled as well getting drag and drop working.
It seems as if selenium has problems if the dragtarget is not visible, thus scrolling is requiered.
Anyway, that's the (Java) code that works. Note that I call "release()" without an argument - neither the dropable Element nor the dragable Element as argument worked for me. As well as "moveToElement(dropable)" didnt work for me, that's why I calculated the offset manually.
public void dragAndDrop(WebElement dragable, WebElement dropable,
int dropableOffsetX, int dropableOffsetY) {
Actions builder = new Actions(driver);
int offsetX = dropable.getLocation().x + dropableOffsetX
- dragable.getLocation().x;
int offsetY = dropable.getLocation().y + dropableOffsetY
- dragable.getLocation().y;
builder.clickAndHold(dragable).moveByOffset(offsetX, offsetY).release()
.perform();
}

i was also struggling with this and the solution that worked for me is below we have to add 1 to either X or Y co-ordinate.
Looks like (x,y) takes us to the edge of the element where its not clickable
Below worked for me
WebElement elm = drv.findElement(By.name(str));
Point pt = elm.getLocation();
int NumberX=pt.getX();
int NumberY=pt.getY();
Actions act= new Actions(drv);
act.moveByOffset(NumberX+1, NumberY).click().build().perform();
you could even try adding +1 to y coordinate that also works
act.moveByOffset(NumberX+1, NumberY).click().build().perform();

Please try using moveToElement. It should work.
Actions action = new Actions(webdriver);
WebElement we = webdriver.findElement(By.xpath("<XPATH HERE>"));
action.moveToElement(we).moveToElement(webdriver.findElement(By.xpath("/expression-here"))).click().build().perform();

i suggest that if your browser is not perform movetoelement and move to offset then you have put wrong offset of element
for find offset you use Cordinates plugin in chrome

Related

Eclipse Error when trying to run in windows

Exception in thread "main" java.lang.IllegalStateException: The driver executable must exist: C:\chromedriver.exe
at org.openqa.selenium.internal.Require$FileStateChecker.isFile(Require.java:315)
at org.openqa.selenium.remote.service.DriverService.checkExecutable(DriverService.java:144)
at org.openqa.selenium.remote.service.DriverService.findExecutable(DriverService.java:139)
at org.openqa.selenium.chrome.ChromeDriverService.access$000(ChromeDriverService.java:38)
at org.openqa.selenium.chrome.ChromeDriverService$Builder.findDefaultExecutable(ChromeDriverService.java:231)
at org.openqa.selenium.remote.service.DriverService$Builder.build(DriverService.java:434)
at org.openqa.selenium.chrome.ChromeDriverService.createDefaultService(ChromeDriverService.java:127)
at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:46)
at base.main(base.java:35)
Hi Guys was trying to do some practice but always this error comes up it will be really helpful if you guys can help me to understand the error. I tried setting up the selenium driver path but still error not going away. the code is on the bottom.Thank you in advance
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class base {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver", "C://chromedriver.exe");
WebDriver driver=new ChromeDriver();
//driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
WebDriverWait w =new WebDriverWait(driver,5);
String[] itemsNeeded= {"Cucumber","Brocolli","Beetroot"};
driver.get("https://rahulshettyacademy.com/seleniumPractise/");
Thread.sleep(3000);
addItems(driver,itemsNeeded);
driver.findElement(By.cssSelector("img[alt='Cart']")).click();
driver.findElement(By.xpath("//button[contains(text(),'PROCEED TO CHECKOUT')]")).click();
w.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input.promoCode")));
driver.findElement(By.cssSelector("input.promoCode")).sendKeys("rahulshettyacademy");
driver.findElement(By.cssSelector("button.promoBtn")).click();
//explicit wait
w.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("span.promoInfo")));
System.out.println(driver.findElement(By.cssSelector("span.promoInfo")).getText());
}
public static void addItems(WebDriver driver,String[] itemsNeeded)
{
int j=0;
List<WebElement> products=driver.findElements(By.cssSelector("h4.product-name"));
for(int i=0;i<products.size();i++)
{
//Brocolli - 1 Kg
//Brocolli, 1 kg
String[] name=products.get(i).getText().split("-");
String formattedName=name[0].trim();
//format it to get actual vegetable name
//convert array into array list for easy search
// check whether name you extracted is present in arrayList or not-
List itemsNeededList = Arrays.asList(itemsNeeded);
if(itemsNeededList.contains(formattedName))
{
j++;
//click on Add to cart
driver.findElements(By.xpath("//div[#class='product-action']/button")).get(i).click();
if(j==itemsNeeded.length)
{
break;
}
}
}
}
}
System.setProperty("webdriver.chrome.driver", "C://chromedriver.exe");
defines that the chrome driver binary is located at C:\chromedriver.exe. But the exception says the file does not exists there.
So just download the chrome driver from https://chromedriver.chromium.org/downloads and move + rename it to C:\chromedriver.exe and it will work.
This error message...
Exception in thread "main" java.lang.IllegalStateException: The driver executable must exist: C:\chromedriver.exe
...implies that the program was unable to find the ChromeDriver executable in the specified location.
Solution
You need to take care of a couple of things here as follows:
Ensure that you have downloaded the exact format of the ChromeDriver binary from the download location pertaining to your underlying OS among:
chromedriver_win32: For Windows OS
chromedriver_mac64: For MAC OS X
chromedriver_linux64: For Linux OS
Instead of storing the ChromeDriver executable within C:\ drive, keep it within a directory, e.g. C:\BrowserDrivers\. So effectively your line of code will be:
System.setProperty("webdriver.chrome.driver", "C://BrowserDrivers//chromedriver.exe");
Ensure that ChromeDriver binary have executable permission for the non-administrator user.
Execute your Test as a non-administrator user.

Is there any capabilities to set Firefox browser zoom level to some specific percent throughout script execution?

I'm using Firefox browser and i want to set the zoom level 90% while it executing the script.
I have tried to set using JavascriptExecutor like -
((JavascriptExecutor)driver).executeScript("document.body.style.transform='scale(0.9)'");
Its working for specific command lets say in my Listeners file i have place this if its a get command. it resize the browser after get URL and then it restored back to default once another command getting executed.
I'm looking for the solution like DesiredCapabilities of things so there i can add the zoom level for the browser.
FirefoxProfile profile= new FirefoxProfile();
profile.setPreference( "layout.css.devPixelsPerPx", "0.9" );
WebDriver driver = new FirefoxDriver(profile);
The above will set the firefox profile preference and simulate a zoom level of 90% for 110% set it to 1.1
How about something like this one -
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class A {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("http://www.google.com");
driver.manage().window().maximize();
Dimension dMax = driver.manage().window().getSize();
int mHeight = (int) (dMax.height *.9);
int mWidth = (int)(dMax.width *.9);
Dimension d = new Dimension(mWidth, mHeight);
driver.manage().window().setSize(d);
System.out.println( driver.manage().window().getSize());
}
}
There is not the capability level option is available in Firefox.
But screen size can be increased or decrease by webdriver:
driver.manage().window().setSize(value);

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

WebDriver.getWindowHandle() method

I'm new to Selenium learning. WebDriver.getWindowHandle() documentation is not very clear to me and the example is not working as given in the book, so I thought of confirming the value returned by this method.
1) Let's say I am on page PAGE1. So getWindowHandle() should return handle to PAGE1. (Correct)
2) Now from this page, I go to PAGE2 (by hyperlink and opening a new window). My book says now getWindowHandle() should return handle to PAGE2. However my program still returns handle to PAGE1.
Selenium v2.43
Reproducible on Firefox and Chrome both.
Question: What is the exact value that getWindowHandle() should return?
WebDriver wd = new ChromeDriver();
wd.get("file://D:/Projects/Selenium/Startup/web/ch3/switch_main.html");
String h1 = wd.getWindowHandle();// original handle
System.out.println("First handle = " + h1);
WebElement clickhere = wd.findElement(By.id("clickhere"));
clickhere.click();//moved to a new child page<
String h2 = wd.getWindowHandle();
System.out.println("Second handle = " + h2);// this handle is not different than h1
getWindowHandle() will get the handle of the page the webDriver is currently controlling. This handle is a unique identifier for the web page. This is different every time you open a page even if it is the same URL.
getWindowHandles() (don't forget the 's') will give you all the handles for all the pages that the web driver understands are open. Note that when you put these in a list they are listed in the order that they have been opened.
You can use SwitchTo().Window("handle") to switch to the window you desire.
You can use SwitchTo().Window("mywindowID"), if you know the window ID.
SwitchTo().Window("") will always go back to the base/main window.
SwitchTo().Frame("popupFrame") will get to the Popup that came from the window the webdriver is currently controlling.
If the link opens a new window you should have a new window handle in the WebDriver. You can loop current window handles with getWindowHandles.
See this example from http://www.thoughtworks.com/products/docs/twist/13.3/help/how_do_i_handle_popup_in_selenium2.html
String parentWindowHandle = browser.getWindowHandle(); // save the current window handle.
WebDriver popup = null;
Iterator<String> windowIterator = browser.getWindowHandles();
while(windowIterator.hasNext()) {
String windowHandle = windowIterator.next();
popup = browser.switchTo().window(windowHandle);
if (popup.getTitle().equals("Google") {
break;
}
}
When you open the new window, the WebDriver doesn't automatically switch to it. You need to use the switchTo() method to switch to the new window, either using the name of the new window, or its handle (which you can get with getWindowHandles() and searching for the one that's not the current window).
I have used this code for my project
String oldTab = driver.getWindowHandle();
public static void switchingToNewTabUsingid(WebDriver driver,WebDriverWait wait,String id,String oldTab)
{
wait.until(ExpectedConditions.elementToBeClickable(By.id(id)));
driver.findElement(By.id(id)).click();
ArrayList<String> newTab = new ArrayList<String>(driver.getWindowHandles());
newTab.remove(oldTab);
driver.switchTo().window(newTab.get(0));
}
//Perfrom Opeartion here on switched tab
public static void comingBackToOldTab(WebDriver driver,String oldTab)
{
driver.close();
driver.switchTo().window(oldTab);
}
With Selenium 2.53.1 using firefox 47.0.1 as the WebDriver in Java: You need to open the separate windows/browsers in it's own driver. I have having the same problem. No matter how many windows or tabs I opened, "driver.getWindowHandles()" would only return one handle so it was impossible to switch between tabs. I found Chrome worked way better for me.
Once I started using Chrome 51.0, I could get all handles. The following code show how to access multiple drivers and multiple tabs within each driver.
// INITIALIZE TWO DRIVERS (THESE REPRESENT SEPARATE CHROME WINDOWS/BROWSERS)
driver1 = new ChromeDriver();
driver2 = new ChromeDriver();
// LOOP TO OPEN AS MANY TABS AS YOU WISH
for(int i = 0; i < TAB_NUMBER; i++) {
driver1.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
// SLEEP FOR SPLIT SECOND TO ALLOW DRIVER TIME TO OPEN TAB
Thread.sleep(100);
// STORE TAB HANDLES IN ARRAY LIST FOR EASY ACCESS
ArrayList tabs1 = new ArrayList<String> (driver1.getWindowHandles());
// REPEAT FOR THE SECOND DRIVER (SECOND CHROME BROWSER WINDOW)
// LOOP TO OPEN AS MANY TABS AS YOU WISH
for(int i = 0; i < TAB_NUMBER; i++) {
driver2.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
// SLEEP FOR SPLIT SECOND TO ALLOW DRIVER TIME TO OPEN TAB
Thread.sleep(100);
// STORE TAB HANDLES IN ARRAY LIST FOR EASY ACCESS
ArrayList tabs2 = new ArrayList<String> (driver2.getWindowHandles());
// NOW PERFORM DESIRED TASKS WITH FIRST BROWSER IN ANY TAB
for(int ii = 0; ii <= TAB_NUMBER; ii++) {
driver2.switchTo().window(tabs2.get(ii));
// LOGIC FOR THAT DRIVER'S CURRENT TAB
}
// PERFORM DESIRED TASKS WITH SECOND BROWSER IN ANY TAB
for(int ii = 0; ii <= TAB_NUMBER; ii++) {
drvier2.switchTo().window(tabs2.get(ii));
// LOGIC FOR THAT DRIVER'S CURRENT TAB
}
Hopefully that gives you a good idea of how to manipulate multiple tabs in multiple browser windows.

How do I load a javascript file into the DOM using selenium?

I'm using Selenium WebDriver to try to insert an external javascript file into the DOM, rather than type out the entire thing into executeScript.
It looks like it properly places the node into the DOM, but then it just disregards the source, i.e. the function on said source js file doesn't run.
Here is my code:
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Example {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("http://google.com");
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.getElementsByTagName('head')[0].innerHTML += '<script src=\"<PATH_TO_FILE>\" type=\"text/javascript\"></script>';");
}
}
The code of the javascript file I am linking to is
alert("hi Nate");
I've placed the js file on my localhost, I called it using file:///, and I tried it on an external server. No dice.
Also, in the Java portion, I tried appending 'scr'+'ipt' using that trick, but it still didn't work. When I inspect the DOM using Firefox's inspect element, I can see it loads the script node properly, so I'm quite confused.
I also tried this solution, which apparently was made for another version of Selenium (not webdriver) and thus didn't work in the least bit: Load an external js file containing useful test functions in selenium
According to this: http://docs.seleniumhq.org/docs/appendix_migrating_from_rc_to_webdriver.jsp
You might be using the browserbot to obtain a handle to the current
window or document of the test. Fortunately, WebDriver always
evaluates JS in the context of the current window, so you can use
“window” or “document” directly.
Alternatively, you might be using the browserbot to locate elements.
In WebDriver, the idiom for doing this is to first locate the element,
and then pass that as an argument to the Javascript. Thus:
So does the following work in webdriver?
WebDriver driver = new FirefoxDriver();
((JavascriptExecutor) driver)
.executeScript("var s=window.document.createElement('script');\
s.src='somescript.js';\
window.document.head.appendChild(s);");
Injecting our JS-File into DOM
Injecting our JS-File into browsers application from our local server, so that we can access our function using document object.
injectingToDOM.js
var getHeadTag = document.getElementsByTagName('head')[0];
var newScriptTag = document.createElement('script');
newScriptTag.type='text/javascript';
newScriptTag.src='http://localhost:8088/WebApplication/OurOwnJavaScriptFile.js';
// adding <script> to <head>
getHeadTag.appendChild(newScriptTag);
OurSeleniumCode.java
String baseURL = "http://-----/";
driver = new FirefoxDriver();
driver.navigate().to(baseURL);
JavascriptExecutor jse = (JavascriptExecutor) driver;
Scanner sc = new Scanner(new FileInputStream(new File("injectingToDOM.js")));
String inject = "";
while (sc.hasNext()) {
String[] s = sc.next().split("\r\n");
for (int i = 0; i < s.length; i++) {
inject += s[i];
inject += " ";
}
}
jse.executeScript(inject);
jse.executeScript("return ourFunction");
OurOwnJavaScriptFile.js
document.ourFunction = function(){ .....}
Note : If you are passing JS-File as String to executeScript() then don't use any comments in between JavaScript code, like injectingToDOM.js remove all comments data.

Categories

Resources