selenium element.click() not working (doesn't click) - selenium

String selector = ".rmcAlertDialog .buttons :first-child";
RemoteWebElement selection = (RemoteWebElement) driver.findElement(By.cssSelector(selector));
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(selection));
if (element == selection) selection.click();
But the element in question (a button) is not responding to the click.
If I click the button manually it works so its not the web page at fault, but the automation.
I have verified the button is there by comparing it's text content.
updated for clarification
This code works (or worked) for most buttons. The code is from a script interpreter which is parsing:-
select ".rmcAlertDialog .buttons :first-child" click
This code was working prior to more recent versions of chrome/selenium/chromedriver.
The code now doesn't work for some buttons.
selection.click() IS being called (verified in a debugger), as element will always equal selection, it just is not working.
.buttons is the class name of the container div for the button(s)

The selector is not directing to the element with button class. You have a space between .button and :first-child in the selector. Remove the space. The given selector is searching for a child element of the tag with button class. But I'm assuming you are trying to click on the first element with button class not the child node of the button class element.
Use this:
String selector = ".rmcAlertDialog .buttons:first-child";

I think the main reason it's failing is because your if statement will never be true. I've never done any comparisons like this but you can simplify your code significantly and still get the desired effect.
A few suggestions:
Don't define locators as Strings, define them as Bys. The By class is defined for just such a task and makes using and passing them around MUCH easier.
String selector = ".rmcAlertDialog .buttons:first-child";
would turn into
By locator = By.cssSelector(".rmcAlertDialog .buttons:first-child");
Note the correction that S Ahmed pointed out in his answer.
You don't need to find the element to wait for it to be clickable. There is an overload that takes a By locator, use that instead.
RemoteWebElement selection = (RemoteWebElement) driver.findElement(By.cssSelector(selector));
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(selection));
becomes
WebElement element = new WebDriverWait(driver, 60).until(ExpectedConditions.elementToBeClickable(locator));
Skip the RemoteWebElement and WebElement comparison. I don't think this will work and there's no need for it anyway. Your locator will locate the same element consistently.
So your final code should look something like
By locator = By.cssSelector(".rmcAlertDialog .buttons:first-child");
new WebDriverWait(driver, 60).until(ExpectedConditions.elementToBeClickable(locator)).click();

Related

waiting for an element while condition is still fullfilled

The wait helpers are very useful functions. But it seems they can wait only for an element to exist (Until...)
Is there a wait to say "wait while condition is still fullfilled" ?
Example, click some element and wait for some other element to disappear
You can try (at least with Java, I'm not sure if it's in the other languages) is the ExpectedConditions.not the method, which you can wrap around another ExpectedConditions.
An example would be something like:
new WebDriverWait(driver, 20).until(ExpectedConditions.not(ExpectedConditions.presenceOfElementLocated(By.cssSelector('#loading-spinner'))));
or you can try
new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector('#loading-content')))
Selenium in Java has
wait.until(ExpectedConditions.invisibilityOfElementLocated(element));
and
wait.until(ExpectedConditions.stalenessOf(element));
methods.
Selenium in Python has invisibility_of_element_located and staleness_of methods too.
So you can create a method clicking on some element and waiting for it to disappear, like this:
public void clickVisibleDisappear(By element){
wait.until(ExpectedConditions.visibilityOfElementLocated(element)).click();
wait.until(ExpectedConditions.invisibilityOfElementLocated(element));
}
Or clicking on one element and waiting for some other element to disappear as you asked, like this:
public void clickVisibleDisappear(By element1, By element2){
wait.until(ExpectedConditions.visibilityOfElementLocated(element1)).click();
wait.until(ExpectedConditions.invisibilityOfElementLocated(element2));
}

How to make xPath for ul li a href tags

I am working on this project were I need to verify that each item in list is loaded on page. However I am a bit confused how to create the xpath as the text is inside an tag.
I first need need get the element and then assert if that item is displayed. The below first line works however assertion gives an error.
WebElement costRequest = driver.findElement(By.xpath("//a[contains(text(),'Cost')]"));
Assert.assertEquals(true, costRequest.isDisplayed());
log.info("Verify cost request");
You should use expected conditions - wait for the element to be visible instead of what you are doing now since driver.findElement returns the web element at the moment the element exists, but still not completed so it's not yet displayed.
So do something like this:
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//a[contains(text(),'Cost')]")));
WebElement costRequest = driver.findElement(By.xpath("//a[contains(text(),'Cost')]"));
Assert.assertEquals(true, costRequest.isDisplayed());
log.info("Verify cost request");

Cant insert text - a msg that the element is not visible is displayed

I run automation on a site that after I click on a button and a screen of PayPal is opened for inserting details. The PayPal is opened in another tab. I added a syntax that move the testing to the relevant tab and then I insert a syntax that checks that the "email input" field exists (to check that it is really goes to the correct tab) - and the result of this test :- field exists.
Then - I add a syntax for the same field to insert the email and the test is failed - the text is not inserted and there is a msg that the field is not visible.
No need to do scroll because the filed is in the top of the screen.
What can I do in this case?
This is the relevant code:
String oldTab = driver.getWindowHandle();
comOps.clickOrChose(PLS.buyButton);
Thread.sleep(4000);
ArrayList<String> newTab = new ArrayList<String> (driver.getWindowHandles());
newTab.remove(oldTab);
driver.switchTo().window(newTab.get(0));
comOps.verifyElementExist(PLP.payPalEmail);
comOps.insertText(PLP.payPalEmail, "paypal-buyer#makeitleo.com");
The reason you get this error message is that the element apparently exists but is not visible when you try to enter text to it. There are a lot of possible reasons why the element is not visible.
Given that a new tab is opended a probable reason is that the page (and its elements) is still loading. If this is the case, you need to wait for the visiblity of the element, e.g. using this piece of code (before inserting text):
WebDriverWait wait = new WebDriverWait(driver, 300); //waiting up to 5 minutes
ExpectedCondition<WebElement> condition =
ExpectedConditions.visibilityOf(PLP.payPalEmail);
wait.until(condition);
Note: that this solution assumes that PLP.payPalEmail is of type org.openqa.selenium.WebElement. If it is of type org.openqa.selenium.By use visibilityOfElementLocated(By locator).
Telling from your code snippet, I assume that comOps is an object of a class wrapping all Selenium actions. So, it is a good idea to place the above code in some method inside that class which could look like this:
public void verifyElementVisible(WebElement element) {
WebDriverWait wait = new WebDriverWait(driver, 300); //ToDo: use configurable timeout
ExpectedCondition<WebElement> condition =
ExpectedConditions.visibilityOf(element);
wait.until(condition);
}
and call it like this
comOps.verifyElementVisible(PLP.payPalEmail);

Selenium and capture object

Using firefox and marking a link in my web-app I get among other things, this code which I think I can use to caprture an object:
cb_or_somename_someothername cb_area_0219
This string is "classname" in Firebug.
Going to the script I type in:
WebElement rolle = driver.findElement(By.className("cb_or_somename_someothername cb_area_0219"));
But the script does not find the element when executing.
Other onfo in the Firebug panel is:
class="cb_or_somename_someothername cb_area_0219"
onclick="jsf.util.chain(this,event,'$(this).attr(\'disabled\', \'disabled\');return true;','mojarra.jsfcljs(document.getElementById(\'fwMainContentForm\'),{\'fwMainContentForm:j_idt156:2:selectRole \':\'fwMainContentForm:j_idt156:2:selectRole\'},\'\')');return false"
href="#"
id="fwMainContentForm:j_idt156:2:selectRole"
Is my script referring the element in a wrong way?
You cannot use search by compound class name (name with spaces). Try to use search by CSS selector instead:
WebElement rolle = driver.findElement(By.cssSelector(".cb_or_somename_someothername.cb_area_0219"));
or by XPath:
WebElement rolle = driver.findElement(By.xpath("//*[#class='cb_or_somename_someothername cb_area_0219']"));
Also you still can use search by one of two class names:
WebElement rolle = driver.findElement(By.className("cb_or_somename_someothername"));
or
WebElement rolle = driver.findElement(By.className("cb_area_0219")); // Note that this class name could be generated dynamically, so each time it could has different decimal part
Update
If you get Element is not clickable... exception it seem that your element is covered by another element at the moment you try to click on it. So try to wait until this "cover" is no more visible:
new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//p[#class='environtment-banner']"));
WebElement rolle = driver.findElement(By.className("cb_area_0219"));
rolle.click();

Element is not clickable when another element covers it

I am writing a test that at some point navigates to another page. The first thing that page is will be to run a javascript that pops up a span with a message. After some seconds, that span will dissapear.
I am trying to click a link that will go below the span and chromedriver does not seem to allow that.
System.InvalidOperationException: unknown error: Element is not
clickable at point (165, 177). Other element would receive the click:
...
This is really an expected behavior and also a bit impresssive.
Can I click the link without waiting for the span to dissapear?
I have no suggestion how to click the element as long as the massage is displayed but you could skip waiting for it to disappear by removing it on your own using javascript and webDriver.executeScript:
How to make a DIV visible and invisible with JavaScript
I would suggest you to use "smart" wait that will verify that the window has disappeared.
It's implemented using WebDriverWait and ExpectedConditions.
Example in Java:
WebDriverWait wait = new WebDriverWait(driver, 10); //timeout after 10 seconds
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.ByCssSelector("CSS_POP_UP_SELECTOR")));
Or, you can try to use the following script to make element visible:
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("document.getElementById('BUTTON_ELEMENT_ID').style.display='block';");
Or, to try and hide the message:
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("document.getElementById('BUTTON_ELEMENT_ID').style.display='none';");
If you want your elements to keep their size when the not visible/visible, instead of 'display' change the 'visibility':
document.getElementById('BUTTON_ELEMENT_ID').style.visibility = 'hidden';
document.getElementById('BUTTON_ELEMENT_ID').style.visibility = 'visible';