How to perform mouseover function in Selenium WebDriver using Java? - java

I want to do mouseover function over a drop down menu. When we hover over the menu, it will show the new options.
I tried to click the new options using the xpath. But cannot click the menus directly.
So, as the manual way I am trying to hover over the drop down menu and then will click the new options.
Actions action = new Actions(webdriver);
WebElement we = webdriver.findElement(By.xpath("//html/body/div[13]/ul/li[4]/a"));
action.moveToElement(we).build().perform();

Its not really possible to perform a 'mouse hover' action, instead you need to chain all of the actions that you want to achieve in one go. So move to the element that reveals the others, then during the same chain, move to the now revealed element and click on it.
When using Action Chains you have to remember to 'do it like a user would'.
Actions action = new Actions(webdriver);
WebElement we = webdriver.findElement(By.xpath("html/body/div[13]/ul/li[4]/a"));
action.moveToElement(we).moveToElement(webdriver.findElement(By.xpath("/expression-here"))).click().build().perform();

None of these answers work when trying to do the following:
Hover over a menu item.
Find the hidden element that is ONLY available after the hover.
Click the sub-menu item.
If you insert a 'perform' command after the moveToElement, it moves to the element, and the sub-menu item shows for a brief period, but that is not a hover. The hidden element immediately disappears before it can be found resulting in a ElementNotFoundException. I tried two things:
Actions builder = new Actions(driver);
builder.moveToElement(hoverElement).perform();
builder.moveToElement(clickElement).click().perform();
This did not work for me. The following worked for me:
Actions builder = new Actions(driver);
builder.moveToElement(hoverElement).perform();
By locator = By.id("clickElementID");
driver.click(locator);
Using the Actions to hover and the standard WebDriver click, I could hover and then click.

Based on this blog post I was able to trigger hovering using the following code with Selenium 2 Webdriver:
String javaScript = "var evObj = document.createEvent('MouseEvents');" +
"evObj.initMouseEvent(\"mouseover\",true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);" +
"arguments[0].dispatchEvent(evObj);";
((JavascriptExecutor)driver).executeScript(javaScript, webElement);

This code works perfectly well:
Actions builder = new Actions(driver);
WebElement element = driver.findElement(By.linkText("Put your text here"));
builder.moveToElement(element).build().perform();
After the mouse over, you can then go on to perform the next action you want on the revealed information

Check this example how we could implement this.
public class HoverableDropdownTest {
private WebDriver driver;
private Actions action;
//Edit: there may have been a typo in the '- >' expression (I don't really want to add this comment but SO insist on ">6 chars edit"...
Consumer < By > hover = (By by) -> {
action.moveToElement(driver.findElement(by))
.perform();
};
#Test
public void hoverTest() {
driver.get("https://www.bootply.com/render/6FC76YQ4Nh");
hover.accept(By.linkText("Dropdown"));
hover.accept(By.linkText("Dropdown Link 5"));
hover.accept(By.linkText("Dropdown Submenu Link 5.4"));
hover.accept(By.linkText("Dropdown Submenu Link 5.4.1"));
}
#BeforeTest
public void setupDriver() {
driver = new FirefoxDriver();
action = new Actions(driver);
}
#AfterTest
public void teardownDriver() {
driver.quit();
}
}
For detailed answer, check here - http://www.testautomationguru.com/selenium-webdriver-automating-hoverable-multilevel-dropdowns/

I found this question looking for a way to do the same thing for my Javascript tests, using Protractor (a javascript frontend to Selenium.)
My solution with protractor 1.2.0 and webdriver 2.1:
browser.actions()
.mouseMove(
element(by.css('.material-dialog-container'))
)
.click()
.perform();
This also accepts an offset (i'm using it to click above and left of an element:)
browser.actions()
.mouseMove(
element(by.css('.material-dialog-container'))
, -20, -20 // pixel offset from top left
)
.click()
.perform();

Sample program to mouse hover using Selenium java WebDriver :
public class Mhover {
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://www.google.com");
WebElement ele = driver.findElement(By.id("gbqfba"));
Actions action = new Actions(driver);
action.moveToElement(ele).build().perform();
}
}

You can try:
WebElement getmenu= driver.findElement(By.xpath("//*[#id='ui-id-2']/span[2]")); //xpath the parent
Actions act = new Actions(driver);
act.moveToElement(getmenu).perform();
Thread.sleep(3000);
WebElement clickElement= driver.findElement(By.linkText("Sofa L"));//xpath the child
act.moveToElement(clickElement).click().perform();
If you had case the web have many category, use the first method. For menu you wanted, you just need the second method.

Try this re-usable method,
public void MoveThePoiterToElement(By by){
log.info("Moving the cursor to the element");
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(by));
action.build().perform();
log.info("Cursor moved to the element");
}

I tried that and it worked normal
action = ActionChains(driver)
element = driver.find_element_by_xpath("XPath_selector")
action.move_to_element(element).perform()

Related

Holding and moving element (window)

I have a little problem and I don't know why code does not work.
I have element on site (window) which I want to resize (clicking on corner and pulling).
#Test
public void ResizeWindow()
{
driver.get(URL);
WebElement resizeableWindow = driver.findElement(By.xpath("//*[#id='resizable']/div[3]"));
Actions actions = new Actions(driver);
actions.moveToElement(resizeableWindow);
actions.clickAndHold(resizeableWindow);
actions.moveByOffset(50,50);
}
But this piece of code does not want to resize window (code does not have problem with finding element). Any tips? Or hint on what should I change?
You need to call perform() as last command to execute the previous commands
actions.perform();
The methods from Actions class return this, so you can chain them
Actions actions = new Actions(driver);
actions
.moveToElement(resizeableWindow)
.clickAndHold(resizeableWindow)
.moveByOffset(50,50)
.perform();

Selenium handling duplicate xpaths of same type in java

I am trying to dynamically select items from a drop down menu based on input. This isn't really a problem unless values share a name. For instance if this is my Cucumber statement
When I go to the "Inventory" / "Inventory" application
When I call this method:
#When("^I go to the \"([^\"]*)\" / \"([^\"]*)\" application$")
public void i_go_to_the_application(String hoverMenu, String subMenuName) throws Throwable {
Actions actions = new Actions(driver);
WebElement menuHoverLink = driver.findElement(By.linkText(hoverMenu));
actions.moveToElement(menuHoverLink);
Thread.sleep(1000);
WebElement submenu = driver.findElement(By.xpath("//span[.='" + subMenuName + "']"));
actions.moveToElement(submenu);
actions.click().perform();
Thread.sleep(4000);
My test crash because it cannot find the subMenuElement. This code works swimmingly if the menu names are different such as Inventory > Items.
Now I've already checked this question
Selenium: handling multiple inputs with same xpath
However the solution provide doesn't seem to be helpful since both elements are in the drop down menu with one being a submenu to that one: Inventory > Inventory
I ran this through the selenium IDE and no matter how many ways I've tried to "find" the Inventory element it only ever finds one item. Since the user of my tests can select any number of items from a drop down menu and then subsequent submenus, I can't rely on IDs. Is there a way to select the first menu item for sure and then select the submenu item.
Change this from a partial link text to a xpath search
WebElement menuHoverLink = driver.findElement(By.linkText(hoverMenu));
to below
WebElement menuHoverLink = driver.findElement("//a[.='" + hoverMenu + "']");
You just need the 2 xpaths to be different so even if the names are same you will get your result.
It seems submemu Inventory element existing inside main menu Inventory element. Then you should try to find submemu element on the main menu context as below :-
Actions actions = new Actions(driver);
WebElement menuHoverLink = driver.findElement(By.linkText(hoverMenu));
actions.moveToElement(menuHoverLink);
WebElement submenu = new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfNestedElementLocatedBy(menuHoverLink, By.xpath(".//span[.='" + subMenuName + "']")))
actions.moveToElement(submenu);
actions.click().perform();

MoveToElement only works when using xOffset and yOffset

In a sidebar menu I want to move to a menu item. I'm using this code:
#FindBy(xpath = ".//*[#id='sidebar-wrapper']/ul//a[contains(text(), 'Contact')]")
WebElement contactLink;
public void clickHamburgerMenuAndContactLink() {
Actions action = new Actions(driver);
action.click(hamburgerMenu).moveToElement(contactLink, 0, 0).click().perform();
}
This works most of the time although it also fails from time to time (behavior seems to be unstable).
First I tried to move without mentioning the x and y Offset using only the webelement contactlink as an argument in the moveToElement method. This don't work at all, I don't understand why. I tried also with build() before the perform() but this makes no difference.
The unstable behaviour is probably due to the animation effect which makes the contact link unsteady. I would wait for the close button since it is displayed once the menu reaches its final position:
public void clickHamburgerMenuAndContactLink() {
WebDriverWait wait = new WebDriverWait(driver, 10000);
hamburgerMenu.click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("menu-close")));
contactLink.click();
}

How to select a portion of page using selenium?

I need to copy the contents of a page except header and footer only using mouse select+drag+mouseup+ctrl+C kind of copy.
I am using Selenium Actions class.
FirefoxDriver driver = new FirefoxDriver();
Actions builder = new Actions(driver);
driver.get("http://connectatgrace.org/im-new/what-to-expect");
builder.click(driver.findElement(By.className("block-holder")))
.keyDown(Keys.CONTROL).keyDown(Keys.SHIFT)
.click(driver.findElement(By.id("footer")));
System.out.println("CLICKED");
Is it possible?
Experts please help.
If all you want is the text, you can get it by using .getText() on the right element.
WebDriver driver = new FirefoxDriver();
driver.get("http://connectatgrace.org/im-new/what-to-expect");
String text = driver.findElement(By.id("main")).getText().trim();
EDIT
I understand now what you are looking for. I was able to get it to work with the code below.
Basically the code moves the mouse to the bottom-right corner of the element that contains all the desired text, <div id="content full-width">. Click and hold the mouse button down, move to the top-left corner of the element, and then CTRL+C. I've also validated that the correct text gets into the clipboard.
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("http://connectatgrace.org/im-new/what-to-expect");
WebElement content = driver.findElement(By.id("content full-width"));
Actions builder = new Actions(driver);
builder.moveToElement(content, 0, 0).clickAndHold().moveToElement(content,
content.getSize().getWidth(), content1.getSize().getHeight()).release();
builder.build().perform();
content.sendKeys(Keys.chord(Keys.CONTROL, "c"));
System.out.println("CLICKED");
NOTE: If you use moveToElement(), it moves to the center of the element. That's why there's code to get the width/height and divide by 2.
EDIT 2
After OP noticed that I had a typo, I went back and did some investigations on the .moveToElement() methods. From the docs,
moveToElement(WebElement toElement)
Moves the mouse to the middle of the element.
moveToElement(WebElement toElement, int xOffset, int yOffset)
Moves the mouse to an offset from the top-left corner of the element.
So corrected the code to use .moveToElement(e, 0, 0) to start the selection at the top left of the element and then moved the selection to the bottom right using .moveToElement(content, content.getSize().getWidth(), content1.getSize().getHeight()). This should work correctly now.
This works!!!
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("http://connectatgrace.org/im-new/what-to-expect");
WebElement content = driver.findElement(By.id("content full-width"));
Actions builder = new Actions(driver);
builder.moveToElement(content, content.getSize().getWidth() / 2, content.getSize().getWidth() / 2).clickAndHold().moveToElement(content, -content.getSize().getHeight() / 2, -content.getSize().getHeight() / 2);
builder.build().perform();
Basically you forgot to place height i.e. getHeight() instead of getWidth().
Now its working fine.

Move slider in Selenium Webdriver with Java and Firefox

I have a problem using Selenium Webdriver (version 2.32.0) and Firefox (21.0), trying to change the values on a slider.
I wrote a Java code like this:
private void selectGiftCardPrice() throws TestingException {
try {
WebElement slider = getDriver().findElement(
By.cssSelector("div.sliderHandle"));
Actions move = new Actions(getDriver());
move.dragAndDropBy(slider, 90, 0);
move.build().perform();
sleep(4000);
} catch (Exception e) {
log.info(e);
throw new TestingException("e");
}
I tried out every code I found on the Web, every change, and it still does not work. It does not show any problem, just finds the element, and does nothing. Any idea what it is, or what can I do?
EDIT from comment:
I finally made it working with jQuery slider demo
driver.get("http://jqueryui.com/resources/demos/slider/multiple-vertical.html");
WebElement slider = driver.findElement(By.xpath("//div[1]/a[contains(#class,'ui-slider-handle')]"));‌
But it is still not working for me with jQuery UI Slider demo page using Xpath //div[#id='slider']/a. What is the problem?
This code works absolutely fine for me.
program handles slider of website : Homeshope18.com
Check it out:
WebDriver driver = new FirefoxDriver();
driver.get("http://www.homeshop18.com/fashion-jewellery/category:15143/filter_Theme:%28%22Traditional+Wear%22+%22Cuff+%26+Kada%22+%22Daily+Wear%22+%22Maang+Tikka%22+%22Openable+Round%22+%22Round%22+%22Openable+Oval%22%29/sort:Popularity/inStock:true/?it_category=HP&it_action=JW-HPSP01&it_label=HP-HPSP01-131021235900-PD-JW-ZC-VK-SC_DiwaliFestWeddingJewellery&it_value=0");
WebElement slider = driver.findElement(By.xpath("//*[#id='slider-range']/a[1]"));
Thread.sleep(3000);
Actions moveSlider = new Actions(driver);
Action action = moveSlider.dragAndDropBy(slider, 30, 0).build();
action.perform();
Using Actions class, firs use clickAndHold("WebElemnt");
Then to move horizontally we need to move in the Y direction of the screen so we can use movebyoffset, i.e X-axis: 0 & Y axis: 40px
To move vertically we need to move in the X direction of the screen so we can use movebyoffset, i.e X-axis: 40px & Y axis: 0
The sample code would be :
Actions slider=new Actions(driver);
slider.clickAndHold("WebElemnt");
slider.movebyoffset(0,40).build.perform();

Categories

Resources