I tried to find a solution to this thing and I spent a lot of time, but it is almost imposible to me to do that.
The matter: I am using Selenium with Java in Firefox. I need to find an element (a listbox) and click on it. So, the code finds the element, but click action does not work. It works fine in Google Chrome every time, and just sometimes in Firefox (with the same Java code sometimes works, and sometimes does not).
There is the part of code with the element when the program enters on the page:
<div id="size-btn" class="size-btn">
<span class="selected-size">SELECCIONA TALLA </span>
<div class="size-select" style="display: none;">
<table>
<tbody>
<tr id="selecsize_2" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051607">
<tr id="selecsize_3" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051608">
<tr id="selecsize_4" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051609">
<tr id="selecsize_5" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051610">
</tbody>
</table>
<button class="size-guide gaViewEvent gaTrack" data-ga-props="{action:'Seleccionar_Talla', opt_label:'Guia_de_tallas'}" data-href="http://www.anyweb.com/webapp/wcs/stores/servlet/ProductGuideSizeAjaxView?catalogId=24052&categoryId=358056&langId=-5&productId=1047599&storeId=10701">Guía de tallas</button>
</div>
</div>
And there is the part of code that changes when the element is clicked:
<div id="size-btn" class="size-btn opened">
I tried many solutions and sometimes it works, but the next time I run the program, it does not work again.
Some solutions:
It finds the element, but does not run click action. I checked with xpath and cssSelector, and there are unique elements found with those expressions.
driver.findElement(By.xpath("//div[#id='size-btn' and not(contains(#class,'opened'))]/span")).click(); // Also checked with By.cssSelector("span.selected-size")
I though it was because of the time, so I tried to solve it that way.
WebElement we = driver.findElement(By.xpath("//div[#id='size-btn' and not(contains(#class,'opened'))]/span")); // By.cssSelector("span.selected-size")
Thread.sleep(3000);
we.click();
Finally, I was a little bit desperate, and I created a new function to try to do this almost 60 times, looking for the change on the element code and if there was any change, just tried to do click action again.
clickAndWaitWhileElementIsNotPresent(By.xpath("//div[#id='size-btn' and not(contains(#class,'opened'))]/span"),By.xpath("//div[#class='size-btn opened']/span")); // By.cssSelector("span.selected-size")
private void clickAndWaitWhileElementIsNotPresent(By by1, By by2) throws Exception {
for (int second = 0;; second++) {
if (second >= 60)
fail("timeout");
try {
if (isElementPresent(by2))
{
break;
}
else
{
driver.findElement(by1).click();
}
} catch (Exception e) {
}
Thread.sleep(1000);
}
}
There are the images of the element:
Does anybody know how to do that?
Finally I found an answer that works with Firefox as well as Google Chrome.
WebElement we = this.driver.findElement(By.id("size-btn"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", we);
waitForElementPresent(By.xpath("//div[#id='size-btn' and contains(#class,'opened')]/span"));
I am not sure why are you using this Xpath, if you have freedom to change Xpath then record the element using selenium IDE and use Xpath::position from drop down list of target(it picks unique path relative to html header), it will solve problem of dynamic locator. And try below mentioned events.
1- Use clickAt.
2- Use fireevent(focus) and then click. Sometime it happens some element in back ground is getting loaded, when it gets loaded, focus move there hence elementNotVisible error.
3- Use mouseDownRight.
I have the same problem in Firefox. The trick is to click the text inside of not the button itself.
I have some solution, make a class with a robot put there TAB event keys, then call that class. What it does its like a back to focus to the page. For some razon the page lost focus and never find that botton.
Robot robot;
try {
robot = new Robot();
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
} catch (AWTException e) {e.printStackTrace();}
You can try to use the Actions class from org.openqa.selenium.interactions:
WebElement element = driver.findElement(By.id("size-btn"));
Actions builder = new Actions(driver);
builder.moveToElement(element).click(element);
builder.perform();
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.click(element);
Action action = actions.build();
action.perform();
This worked for me.
Related
i have the follow problem:
I have a button inside a form (the web page have a login and password text box and a button), this button calls a js funtion and after the login and password validation, calls the main web page. The html code is this (this code is inside of a form calls "login" and method = POST):
<INPUT class="btn btn-mini btn-primary" onclick=submitForm(); type=button value="Sign On">
In Selenium i try with the follow statements, but without success:
driver.findElement(By.xpath("//input[#type='button']")).click();
driver.findElement(By.cssSelector("input[type='button'][#value='Sign On']")).click();
driver.findElement(By.xpath("//input[#value='Sign On']")).click();
when i run the script, login and password text are filled correctly, but the click in the button it's no working.
Could you help me with this?
Thanks!
Gonzalo from Chile
To click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("input.btn.btn-mini.btn-primary[value='Sign On'][onclick^='submitForm']"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#class='btn btn-mini btn-primary' and #value='Sign On'][starts-with(#onclick, 'submitForm')]"))).click();
i found the solution, reading a lots of issues related with this. I'm working with win 10 and IE 11, so, Selenium has a problem with this, because need the size of the text, apps, and others items in 100%. In my case, i had this configuration in 150%. Fixing this, i run the script one again and it works.
The code used is:
WebElement button = null;
List<WebElement> inputs = webDriver.findElements(By.tagName("input"));
for (WebElement input : inputs) {
if (input.getAttribute("value").equals("Log In")) {
button = input;
break;
}
}
if (button == null) {
System.err.println("Cannot find button!");
} else {
System.out.println("Clicking button now!");
button.click();
}
After this, i check another code more efficient:
driver.findElement(By.cssSelector("input[type='button'][value='Sign On']")).click();
This works too.
thanks all off you for your help
new programmer here-
I am trying to make a cookieclicker bot using selenium. Cookie clicker is a website game linked below
http://orteil.dashnet.org/cookieclicker/
I am attempting to locate the element, like so
WebElement element = driver.findElement(By.id("upgrades"));
and then I call it here:
upgrades = element.findElements(By.className("enabled"));
I want to make a list of "upgrades" that are "enabled". However, I get a null pointer exception on the second piece of code- but on the website there clearly is an element called "upgrades".
Thank you for your time!
edit:
this is the block of code from the game that I am trying to click
<div id="upgrades" class="storeSection upgradeBox"><div onclick="Game.UpgradesById[0].click(event);" class="crate upgrade enabled" onmouseout="Game.setOnCrate(0);Game.tooltip.shouldHide=1;" onmouseover="if (!Game.mouseDown)
and I am trying to fish out these "enabled" upgrades
<div onclick="Game.UpgradesById[0].click(event);" class="crate upgrade enabled" onmouseout="Game.setOnCrate(0);Game.tooltip.shouldHide=1;" onmouseover="if (!Game.mouseDown) {Game.setOnCrate(this);Game.tooltip.dynamic=1;Game.tooltip.draw(this,function(){return Game.crate(Game.UpgradesById[0],'store',undefined,undefined,1)();},'store');Game.tooltip.wobble();}" id="upgrade0" style="background-position:0px 0px;"></div>
I just checked on the website, your code requires modification.
Use the below code:
WebElement element = driver.findElement(By.id("upgrades"));
Actions acc=new Actions(driver);
acc.moveToElement(element).build().perform();
List<WebElement> upgrades = element.findElements(By.className("enabled"));
Let me know if this works for you.
I would like to select radio type check-box in my web application through selenium web-driver whenever is it is available
HTML:
<div class="enhanced-checkbox">
<input id="idYes" class="checkbox" type="radio" data-form-message="This is required" required="" value="Y" name="name">
<span></span>
</div>
It work with below web driver code:
if (idYes.isElementPresentAndDisplayed())
((JavascriptExecutor)driver).executeScript("arguments[0].checked = true", idYes.isElementPresentAndDisplayed());
idYes.click();
I also tried: (in this case radio button selected but not ignoring for other scenarios)
if (idYes.isElementPresentAndDisplayed()){
((JavascriptExecutor)driver).executeScript("arguments[0].checked = true", idYes.isElementPresentAndDisplayed());
idYes.click();}
or another try: (in this case radio button not selected)
if (idYes.isElementPresentAndDisplayed()){
((JavascriptExecutor)driver).executeScript("arguments[0].checked = true", idYes.isElementPresentAndDisplayed());
idYes.clickIfElement Present();}
But when above element is not available in different scenarios, then it is failing.
Expected behavior is : If element present select or ignore.
Put your code in try catch block. In catch block, ignore any error occured.
e.g.
try{
WebElement idYes = driver.findElement(By.id("idYes"));
if (idYes.isElementPresentAndDisplayed())
((JavascriptExecutor)driver).executeScript("arguments[0].checked = true",idYes.isElementPresentAndDisplayed());
idYes.click();
}catch(org.openqa.selenium.NoSuchElementException ignore){
//TODO: do nothing
}
Hope it helps.
You can also do this as:
WebDriverWait wait = new WebDriverWait(driver, 10); // Have a wait object with 10 sec(or whatever u prefer) to enforce on driver object stating for max time it should wait for the conditions
try{
wait.until(ExpectedConditions.elementToBeClickable(By.id("idYes"))).click(); // will explicitly wait for the element to be clickable, else throw timeout exception
}catch(TimeoutException toe){
System.out.println("Check box not present, hence skipping. " + toe); // here you can log or sysout the reason for skipping accompanied with exception
}
Following is HTML for source element:
<li draggable-effect-allowed="copy" draggable-data="business.domain.view.RecordViewComponentType" draggable="view-designer-drop-zone-content" class="list-group-item ng-scope ng-binding" ng-dblclick="insertComponentType(component)" ng-repeat="component in componentTypes" draggable="true">Record</li>
and following is HTML for target element:
<div droppable-on-drop="onDropComponent($event, $draggableEl, $droppableEl)" droppable="view-designer-drop-zone-content" class="layoutSection ContentAreaLayoutSection" id="CONTENT"></div>
Hence I've:
source = driver.findElement(By.xpath("//li[text()='Record']"));
target = driver.findElement(By.ID("CONTENT"));
Actions action = new Actions(driver);
In order to achieve drag and drop, I tried with following apis, but no luck:
1. action.dragAndDrop(source, target).build().perform();
2. action.clickAndHold(source).moveToElement(target).release(target).build().perform();
3. action.moveToElement(source).clickAndHold(source).moveToElement(target).release(target).build().perform();
4. action.moveToElement(source).clickAndHold().moveToElement(target).release().build().perform();
5. action.clickAndHold(source).moveToElement(target).build().perform();
Thread.sleep(3000);
action.release(target).build().perform();
I also tried with moveToElement(target, x-offset, y-offset) still didn't work.
When I tried with all of the above, it didn't throw any error and next code starts executing and visually, I can see source element is dragged but looks when it's moved to target element, it's not dropped to target element still no error is thrown.
Actually, I was expecting some error here if there is an issue with Selenium WebDriver and browser version compatibility.
If someone knows solution or workaround for this, please do answer.
The below code is working for me, try this:
Actions act = new Actions(driver);
WebElement srcElement = driver.findElement(By
.id(locator));
Thread.sleep(3000);
WebElement targetElement =driver.findElement(By
.id(locator));
Thread.sleep(3000);
act.dragAndDrop(srcElement, targetElement);
Thread.sleep(3000);
act.build().perform();
Thread.sleep(3000);
Maybe somebody can help me figure this out. I want to be able to create a chain of Actions using java and Selenium webdriver. Here is what the source of the webpage looks like:
<li id="menu-item-14" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-5 current_page_item menu-item-has-children menu-item-14">About
<ul class="sub-menu" style="display: none; visibility: hidden;">
<li id="menu-item-43" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-43">Team</li>
</ul>
</li>
Basically when you hover over the About menu a submenu name Team will appear and I want to be able to select the submenu.
This is what my code looks like
WebElement aboutMenu = _driver.findElement(By.id("menu-item-14"));
Actions builder = new Actions(_driver);
Action seriesofactions = builder
.moveToElement(aboutMenu)
.moveToElement(_driver.findElement(By.id("menu-item-43")))
.click()
.build();
seriesofactions.perform();
If I take the second moveToElement the code works just fine. Any ideas will be appreciated?
Update: Java Code used
WebElement menuHoverLink = _driver.findElement(By.id("menu-item-14"));
actions.moveToElement(menuHoverLink).perform();
try {
((JavascriptExecutor) _driver).executeScript("document.getElementByid('menu-item-14')).style.display='block'");
} catch (Exception e) {
e.printStackTrace();
}
_driver.findElement(By.id("menu-item-43")).click();
When you hover over your menu-item-14, the style on the ul class="sub-menu" will change to style="display:block; and possibly remove the visibility from the styled element. That then allows the menu-item-43 to appear for selection.
See this post for more information on using mouse over hovers in selenium.
How to do mouse hover using Selenium WebDriver in Firefox 19?