I'm having troubles regarding webdriver not being able to click checkboxes sometime and just skipping them, both in Firefox and Chrome.
I've tried different solutions such as
click();
action.moveToElement(checkbox).clickAndHold(checkbox).release().perform();
jse.javascriptExecutor(argument[0].click(),checkbox).
Here I provide the Javascript code I have for the click event
...
var selectCorrectOption = function () {
if ($(this).hasClass('selected')) {
$(this).removeClass('selected');
$(this).find('> input').prop('checked', false);
} else {
$(this).addClass('selected');
$(this).find('> input').prop('checked', true);
}
};
$('.option > .input-container').on('click', selectCorrectOption);
...
the HTML code where it is attached the javascript click event
<div class="input-container selected" data-choice-id="2">
<input type="radio">
</div>
the Java code data uses a data-attribute to access the element is question. Notice also that once the div is clicked, a 'selected' class appears(which is the current state) on the code below.
WebDriverWait wait = new WebDriverWait(driver, 20);
JavascriptExecutor jse = (JavascriptExecutor)driver;
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("[data-choice-id='"+ wrongOptionVal +"']")));
radio=wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("[data-choice-id='"+ wrongOptionVal +"']")));
jse.executeScript("arguments[0].scrollIntoView()", radio);
jse.executeScript("arguments[0].click()", radio);
I expected it to be consistent ,most of the times work, but there are always that one or two times it fails.
I do not know why this happens, I do however know how this can be addressed. You can implement a FluentWait with polling mechanism, which will do three things:
locate the element,
select the radio box,
return getAttribute("class").contains("selected") value.
If getAttribute("class").contains("selected") will result in false the process should repeat.
FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)
.pollingEvery(Duration.ofMillis(300))
.withTimeout(Duration.ofSeconds(10));
fluentWait.until(new Function<WebDriver, Boolean>() {
#Override
public Boolean apply(WebDriver driver) {
WebElement element = driver.findElement(By.cssSelector(radioCssSelector));
element.click();
return element.getAttribute("class").contains("selected");
}
});
Related
I have react generated web page which has this kind of structure:
div
...
div
div
div class=x_1
<span randomtag=y> text1 </span>
div class=x
<span randomtag=z> text2 </span>
div class=x
<span randomtag=q> text3 </span>
div
div
div
...
div
I am trying to click on the randomtag=z. I have tried:
xpath:
I can find the randomtag y's div with just tossing in the structure up to the div (no other identificators) with .../div[2]/div[1]
I can NOT get the second div with xpath (.../div[2]/div[1] works but .../div[2]/div[2] does not work)
css:
The following is not working either
css=div > span[randomtag="z"]
css=div.x span[randomtag="z"]
I am a bit lost with the possibilities here to select the correct element.
The Robot code is just basic
wait until element is visible | locator (whatever it is)
eg.
wait until element is visible css=div.x span[randomtag="z"]
wait until element is visible xpath=<previous path here>/div[2]/div[2]
Any ideas? Is the react reason for this?
I get "Element not visible in x seconds". For timeout I have tried 5-30 seconds.
EDIT:
I also tried to find the xpath with the search tool (behind dev tools on browser) and it finds the element when I insert either the xpath or css locator to the search.
public static void waitUntilElementIsVisible(WebElement element, WebDriver driver)
{
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
wait.pollingEvery(250, TimeUnit.MILLISECONDS);
wait.withTimeout(2, TimeUnit.MINUTES);
wait.ignoring(ElementNotVisibleException.class); //make sure that this exception is ignored
Function<WebDriver, WebElement> function = new Function<WebDriver, WebElement>()
{
public WebElement apply(WebDriver driver) {
System.out.println("Checking for the element!!");
if(element.isDisplayed() != true)
{
System.out.println("Target element is not visible");
}
return element;
}
};
wait.until(function);
}
then call this:
WebDriver el = driver.FindElement(By.css("yourcss"));
waitUntilElementIsVisible(el, driver);
I have a query on mouseover action in Selenium Webdriver Java.
Consider i have a background image with id "Lfade" with opacity 0.5. If i hover the mouse then a button would be shown.
I want to click on the button to take me to another screen. How do i do this ???
I have tried this, but it does not work
Actions builder = new Actions(driver);
WebElement tagElement = driver.findElement(By.id("Lfade"));
builder.moveToElement(tagElement).build().perform();
Html
div id="homeslant"
div id="wrapper"
div id="lFade" class="learn" style="opacity: 0.5; visibility: visible;"
Button
div class="descbtn"
a class="btn dwmbutton" href="/learn/index.html">KNOW MORE</a>
Not sure about what you are trying to do but I notice an error here:
builder.moveToElement(tagElement).build().perform();
Actually, the .perform() includes a .build().
May be you were referring to .click() so
builder.moveToElement(tagElement).click().perform()
As a pattern for your objective I would:
find the first image
move to the image
wait
find the button
click the button
I used Robot class for mouse hover. Please try the below code.
Robot robot = new Robot();
Point MyPoint = tagElement.getLocation();
robot.mouseMove(MyPoint.getX(), MyPoint.getY());
After that use the normal selenium click to click on the button.
You need to move to the button and perform a click.
Move to the image
wait
Move to the button and click
Actions act = new Actions(driver);
WebElement tagElement = driver.findElement(By.id("Lfade"));
act.moveToElement(tagElement).click().build().perform();
WebElement _button= driver.findElement(By...);
act.moveToElement(_button).click().build().perform();
Try this
#FindBy(xpath="//*[#id='chromemenu']/span/a") WebElement menuHoverLink;
#FindBy(xpath="//*[#id='dropmenu1']/a[1]") WebElement subLink;
Actions maction = new Actions(driver);
maction.moveToElement(menuHoverLink).build().perform();
Thread.sleep(2000);
subLink.click();
Use this code it will work :
Actions builder = new Actions(driver);
WebElement tagElement = driver.findElement(By.id("Lfade"));
WebElement buttonElement = driver.findElement(By.classname("btn"));
builder.moveToElement(tagElement).moveToElement(buttonElement).click().perform();
Try this
public void HoverAndClickObject(WebDriver driver, String property1, String property2, String path) throws SAXException, IOException, ParserConfigurationException
{
//get object properties from the xml file repository
Actions action = new Actions(driver);
String[] element1 = xmlParser(path, property1);
String[] element2 = xmlParser(path, property2);
switch (element1[0].toUpperCase())
{
case "XPATH":
driver.findElement(By.xpath(element1[1])).click();
action.moveToElement(driver.findElement(By.xpath(element2[1]))).click().build().perform();
break;
case "ID":
driver.findElement(By.id(element1[1])).click();
break;
case "NAME":
driver.findElement(By.name(element1[1])).click();
break;
case "LINKTEXT":
driver.findElement(By.linkText(element1[1])).click();
break;
case "CSSSELECTOR":
driver.findElement(By.cssSelector(element1[1])).click();
break;
}
}
I'm trying to click all links in drop down. Some links will open a new browser window where some link will be loaded in the same page.
So, I want to switch to new window only whenever new window is opened and also need to confirm whether the new page is loaded properly.
I have already code to switch windows. But its trying to switch new window even though new window is not opened.
Could someone help me here.
Below is the relevant piece of HTML:
<html>
<div class="column span-8">
<div class="search-container align-center">
<div class="search">
<div class="search-dropdown" onclick="showHideUtilMenu(event, 'SearchMenu');">
<span id="searchoptionValue">Consumer</span>
<span id="dropdownarrow"</span>
<span id="searchurlValue" style="display: none;">http://</span>
<div id="SearchMenu" class="utility-menu combobox visible">
<ul class="menu-list">
<li class="menu-link">
<li class="menu-link divider">
<a onclick="getSearchOption('Consumer','http://');">Consumer</a>
...
Here is the code that I have used so far:
List<WebElement> list = driver.findElements(By.xpath("//*[#class='search-dropdown']/div[1]/ul/li"));
for (WebElement option : list)
{
String strLabel = option.getText();
if(strlabel.equalsIgnoreCase(value1) && country.equals("US"))
{
option.findElement(By.linkText(strLabel)).click();
CommonFunctions.waitForPageLoad();
CommonFunctions.switchWindow();
}
}
I hope you need methods something like below
class CommonFunctions {
/**
* It will wait for an element until it loads completely
*/
public static void waitForPageToLoad() {
int i=0;
while(isElementPresent(By.id("<specifySomeLocator>")))
{
Thread.sleep(100);
if(++i>500)
{
break;
}
}
}
/**
* It will Switch the control to new window if exist.
*/
public static boolean switchToWindow(String mainWindowHandle) {
Set<String> windowhandles=driver.getWindowhandles();
if(windowhandles.size()>1) {
windowhandles.remove(mainWindowHandle);
driver.switchTo().window((String)windowhandles.toArray()[0]);
return true;
} else {
return false;
}
}
}
And you try to implement your code something like below
List<WebElement> list = driver.findElements(By.xpath("//*[#class='search-dropdown']/div[1]/ul/li"));
for (int i=0;i<list.size();i++)
{
String strLabel = driver.findElements(By.xpath("//*[#class='search-dropdown']/div[1]/ul/li")).get(i).getText();
if(strlabel.equalsIgnoreCase(value1) && country.equals("US"))
{
String mainWindowHandle=driver.getWindowHandle();
option.findElement(By.linkText(strLabel)).click();
CommonFunctions.waitForPageToLoad();
if(CommonFunctions.switchToWindow(mainWindowHandle)){
//do your operation in new window
//close new window using ==> driver.close();
//switch back to main window ==> driver.switchTo().window(mainWindowHandle);
} else {
//do your operations in main window itself
}
}
}
FYI : If you iterate list of WebElements like below, it will throw StaleElementReferenceException while trying access second element in that list if page reloads while doing other operations with first element.
for (WebElement option : list)
{
String strLabel = option.getText();
//do some operations
}
For isElementPresent Method implementation click here
This is a general advice, rather than a direct answer to your question.
You can navigate from the current web-page to another web-page, using any of the following options:
driver.get(...);
driver.navigate().to(...);
driver.switchTo().frame(...);
driver.switchTo().window(...);
However, once you do that, any of the elements that you have obtained from the DOM of the previous web-page, may become "stale".
In order to avoid this, it is recommended that you first obtain all the URLs (strings) that you want to go to, and navigate to each one of them only afterwards.
Taking the code in your question as an example, you can change it as follows:
List<String> strLabels = new ArrayList<String>();
List<WebElement> list = driver.findElements(By.xpath("//*[#class='search-dropdown']/div[1]/ul/li"));
for (WebElement option : list)
{
String strLabel = option.getText();
if (strlabel.equalsIgnoreCase(value1) && country.equals("US"))
strLabels.add(strLabel);
}
for (String strLabel : strLabels)
{
driver.findElement(By.linkText(strLabel)).click();
CommonFunctions.waitForPageLoad();
CommonFunctions.switchWindow();
}
Creating a calculator-like dialog, I noticed that quickly clicking on a button in IE will not fire the click event twice (Chrome/FF work as expected), but rather throws the click event, then a double-click event. Experimenting with some simple code, I essentially want to duplicate this behavior:
<script language=javascript>
function minus(num)
{
var i = document.getElementById('0001');
if (i.value > 1)
{
i.value -= num;
return true;
}
}
</script>
<input type="button" onclick="minus(1);" ondblclick="minus(1);" value="minus">
<input type="text" id="0001" name="0001" value=10>
I need to do this in ExtJS 3.1, but my efforts have been stymied. Here is the code I have tried:
Button btn = new Ext.Button(new ButtonConfig()
.text(text)
.tooltip(tooltip)
.tooltipType("title")
.scope(this)
.handler(delgateFunction)
.x(x)
.y(y)
.tabIndex(_tabIndex++)
.width(width).height(height)
.ToDictionary());
btn.addListener("mouseenter", new EventHandler(mouseHandler));
btn.addListener("mouseover", new EventHandler(mouseHandler));
btn.addListener("mouseout", new EventHandler(mouseLeave));
if (Ext.isIE)
{
//btn.on("dblclick", new EventHandler(DoubleClick));
//btn.addListener("dblclick", new EventHandler(DoubleClick));
//btn.addListener("ondblclick", new EventHandler(DoubleClick));
}
None of those three lines seemed to work. Any suggestions?
try the following after the button is rendered:
btn.el.on("dblclick", new EventHandler(DoubleClick));
Ext.Button itself hasn't the "dblclick" event (check the api) while its underlying el(Ext.Element) has.
Complete Sample:
new Ext.Button({id:'btn', text:'dblclick', renderTo:Ext.getBody() });
Ext.getCmp('btn').el.on('dblclick', function(){alert('db click');});
Mr. Zhu led me to the correct answer:
Events.AddEvent(_zeroBtn.getEl().dom, "dblclick", DoubleClickZero);
I need help with a script to add an "active" class to a div when a hidden checkbox is checked. This all happening within a somewhat complex form that can be saved and later edited. Here's the process:
I have a series of hidden checkboxes that are checked when a visible DIV is clicked. Thanks to a few people, especially Dimitar Christoff from previous posts here, I have a few simple scripts that handle everything:
A person clicks on a div:
<div class="thumb left prodata" data-id="7"> yadda yadda </div>
An active class is added to the div:
$$('.thumb').addEvent('click', function(){
this.toggleClass('tactive');
});
The corresponding checkbox is checked:
document.getElements("a.add_app").addEvents({
click: function(e) {
if (e.target.get("tag") != 'input') {
var checkbox = document.id("field_select_p" + this.get("data-id"));
checkbox.set("checked", !checkbox.get("checked"));
}
}
});
Now, I need a fourth ( and final ) function to complete the project (using mootools or just plain javascript, no jQuery). When the form is loaded after being saved, I need a way to add the active class back to the corresponding div. Basically reverse the process. I AM trying to figure it out myself, and would love to post an idea but anything I've tried is, well, bad. I thought I'd at least get this question posted while I work on it. Thanks in advance!
window.addEvents({
load: function(){
if (checkbox.checked){
document.getElements('.thumb').fireEvent('click');
}
}
});
Example: http://jsfiddle.net/vCH9n/
Okay, in case anyone is interested, here is the final solution. What this does is: Create a click event for a DIV class to toggle an active class onclick, and also correlates each DIV to a checkbox using a data-id="X" that = the checkbox ID. Finally, if the form is reloaded ( in this case the form can be saved and edited later ) the final piece of javascript then sees what checkboxes are checked on page load and triggers the active class for the DIV.
To see it all in action, check it out here: https://www.worklabs.ca/2/add-new/add-new?itemetype=website ( script is currently working on the third tab, CHOOSE STYLE ). You won't be able to save/edit it unless you're a member however, but it works:) You can unhide the checkboxes using firebug and toggle the checkboxes yourself to see.
window.addEvent('domready', function() {
// apply the psuedo event to some elements
$$('.thumb').addEvent('click', function() {
this.toggleClass('tactive');
});
$$('.cbox').addEvent('click', function() {
var checkboxes= $$('.cbox');
for(i=1; i<=checkboxes.length; i++){
if(checkboxes[i-1].checked){
if($('c_'+checkboxes[i-1].id))
$('c_'+checkboxes[i-1].id).set("class", "thumb tactive");
}
else{
if($('c_'+checkboxes[i-1].id))
$('c_'+checkboxes[i-1].id).set("class", "thumb");
}
}
});
// Add the active class to the corresponding div when a checkbox is checked onLoad... basic idea:
var checkboxes= $$('.cbox');
for(i=1; i<=checkboxes.length; i++){
if(checkboxes[i-1].checked){
$('c_field_tmp_'+i).set("class", "thumb tactive");
}
}
document.getElements("div.thumb").addEvents({
click: function(e) {
if (e.target.get("tag") != 'input') {
var checkbox = document.id("field_tmp_" + this.get("data-id"));
checkbox.set("checked", !checkbox.get("checked"));
}
}
});
});