Selenium can not click on GWT tree item - java

I can't give access to the webapp but here is the code and HTML of the button
we = driver.findElement(By.xpath("//div/div/div[2]/div/div/div/div/div/div/div/div/div/div/div"));
int width = we.getSize().getWidth();
action.moveToElement(we, width/2, 9).click().build().perform();
.
<div style="display: inline; background-color: rgb(255, 179, 0);" class="gwt-TreeItem gwt-TreeItem-selected" role="treeitem" id="gwt-uid-102" aria-level="9" aria-setsize="4" aria-posinset="1" aria-selected="true">

Xpath=//tagname[#attribute='value']
the above is how we should write the XPath in a code you did just give a tag name but no attribute so try to change how you give XPath
Actions action=new Actions(driver);
we = driver.findElement(By.xpath("//div/div/div[2]/div/div/div/div/div/div/div/div/div/div/div"));
action.moveToElement(we).click().build().perform();

May be the element is not clickable when you are trying to click it. You can wait for element to become clickable and then try clicking it, as shown below:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div/div/div[2]/div/div/div/div/div/div/div/div/div/div/div")));
driver.findElement(By.xpath("//div/div/div[2]/div/div/div/div/div/div/div/div/div/div/div")).click();
If above code does not work for you, then you can use Javascriptexecutor as a workaround, as shown below:
JavascriptExecutor e = (JavascriptExecutor)driver;
e.executeScript("arguments[0].click();", driver.findElement(By.xpath("//div/div/div[2]/div/div/div/div/div/div/div/div/div/div/div")));
Let me know, whether above solution works for you.

When you run selenium TCs, make sure that the browser maximized. Sometimes, it may happen that elements overlap due to smaller resolution.

Related

Unable to clear textarea which auto inputs text on clear and blur using Selenium WebDriver

I'm using Selenium WebDriver using Java.
I'm having a textarea and I would like to clear default content and enter new content in it. Functionality is such that if I clear text from textarea and hit Tab button, then default text will auto fill.
Below is HTML of textarea:
<textarea autocomplete="off" class="form-control rd-control rd-control--textarea empty" cols="20" data-bind="value: offerTitle, expandedTextArea: offerTitle, valueUpdate: 'afterkeydown', customerRequiredFieldsBinding" id="CheckoutWelcomeTitle" name="CheckoutWelcomeTitle" placeholder="ex. Here comes the best offer" rows="1" type="text" data-autosize-on="true" style="overflow-y: hidden; height: 35.9792px;" onblur="setTextColorDefault(this)" oninput="setTextColor(this)">Let's bid on a discount code!</textarea>
I tried using:
driver.findElement(By.id("CheckoutWelcomeTitle")).clear()
But this didn't work.
I also tried this:
driver.findElement(By.id("CheckoutWelcomeTitle")).sendKeys(Keys.CONTROL + "a")
driver.findElement(By.id("CheckoutWelcomeTitle")).sendKeys(Keys.DELETE)
This sometimes works but not always. Sometimes it clears data and refills default text.
Is there any other way I can clear this textarea in a way that it would work every time?
In case if it helps, developers have used JavaScript to refill the text box on blur event.
Edit: I have used explicit wait with the condition of the element to be clickable.
Use Java Script executor it should work.
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("document.getElementById('CheckoutWelcomeTitle').value=''");
The desired element is a dynamic element so to locate the element you have to induce WebDriverWait for the element to be clickable and you can use either of the following Locator Strategies:
cssSelector:
WebElement myElement = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("textarea.form-control.rd-control.rd-control--textarea.empty#CheckoutWelcomeTitle")));
myElement.click();
myElement.clear();
xpath:
WebElement myElement = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//textarea[#class='form-control rd-control rd-control--textarea empty' and #id='CheckoutWelcomeTitle']")));
myElement.click();
myElement.clear();
I think it's worth mentioning a solution that works without custom scripts; to take in account all the possible permutations of drivers and os, the most up-to-date solution to the problem is:
private fun clearField(element: WebElement) {
element.sendKeys(Keys.chord(Keys.SHIFT, Keys.ARROW_UP), Keys.DELETE)
element.sendKeys(Keys.chord(Keys.CONTROL, "a"), Keys.DELETE)
element.clear()
}
This is the quite redundant solution to the fact that clear does not always work, and to the fact that the first works on mac and the second on windows.
All the three combined has been tested also on react app with validation and input mask.
The namespace to import is import org.openqa.selenium.Keys.
This is an example code, to avoid stale elements you should not pass WebElements around.

How to find element either by "a class" or "span class"?

I'm trying to click on an element but I always get the error "cannot locate an element using..".
I've tried it with find by class, by csselector, and by XPath. I also tried the a class first and then the span class element but it's still not working. It's definitely the correct frame, too.
It's really weird because it worked two weeks ago, I didn't change anything in the code and now it's not working. Is it possible that the element is constantly changing? If so, how can I make sure that it still finds the element without adjusting my code every time?
<a class="ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all" href="#" aria-label="Close" role="button">
<span class="ui-icon ui-icon closethick">
::after
</span>
</a>
This is my current code now which still isn't working:
driver.switchTo().defaultContent();
driver.switchTo().frame("frame_vehicleFileTab");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
WebElement closePrint = (new WebDriverWait(driver, 10)).until(
ExpectedConditions.elementToBeClickable(By.xpath("//*[#aria-label='Close']")));
closePrint.click();
After trying DebanjanB's suggestion by searching for the element:
driver.findElement(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']")).click();
I get this error: org.openqa.selenium.ElementNotInteractableException: Element could not be scrolled into view
Update: I fixed it by getting the Selenium IDE extension for Firefox and then choosing the xpath that was generated by the extension together with the javascript executor:
WebElement closePrint = (new WebDriverWait(driver, 10)).until(
ExpectedConditions.presenceOfElementLocated(By.xpath("//div[#id='FileTab:Form:j_id674351400_da78919']/div/a/span")));
JavascriptExecutor js1 = (JavascriptExecutor)driver;
js1.executeScript("arguments[0].click();", closePrint);
I don't know why that xpath works now but I'm glad it does. Thanks everyone for your suggestions!
It will be tough to locate the element through the <span> tag as it is a pseudo element. To locate the element you can use either of the following Locator Strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("a.ui-dialog-titlebar-icon.ui-dialog-titlebar-close.ui-corner-all[aria-label='Close']"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']"))).click();
As far as I can see in the HTML you have provided:
You can use By.XPATH with this XPATH: "//*[#aria-label='Close']".
Like this:
d.findElement(By.xpath("//*[#aria-label='Close']")).click();
EDIT:
Try using Actions with an Offset this helps if there is an element covering it, this happens with iFrames.
Here is a code snip:
WebElement closePrint = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']")));
int width = closePrint.getSize().getWidth();
Actions clicker= new Actions(driver);
act.moveToElement(closePrint).moveByOffset((width/2)-2, 0).click().perform();
Hope this helps you!
In addition to DebanjanB's suggestion, I would also suggest you to use below JavaScript utility to scroll down till the element is visible.
WebElement element = driver.findElement(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);

Unable to locate and click checkbox ::before using Selenium Webdriver

I'm trying to click a checkbox but it's keep clicking the link 'terms and conditions'. Although my xpath (mentioned below) work on a minimized window but it's failing to click the checkbox when the window is maximized because the href (image) appears in the second line next to checkbox. Looking for some suggestions on clicking the checkbox widget on maximized window. I need to get a focus on it.
Interestingly, when i hover over the ::before (css selector) only than the widget gets highlighted.
<div class="checkbox u-mar-bot-5">
<div class="checkbox__container">
<input class="checkbox__input" type="checkbox" id="basket-contact-terms" required data-parsley-multiple="basket-contact-terms" style>
<label class="checkbox__label checkbox__label--has-link checkbox__label--small" for="basket-contact-terms" style>
::before
"I have read and agree to " <a class="text-link text-link--base text-link- small" href="/terms-conditions" target="_blank">Terms and Conditions</a>
</label>
</div>
</div>
image: Terms and Conditions
I tried a few options that keep failing to check the box and instead the link 'terms and conditions' gets the click. I must be missing something basic.
driver.findElement(By.xpath("//label[#for='basket-contact-terms']")).click();
driver.findElement(By.xpath("//label[contains(#class,'checkbox__label checkbox__label--has-link checkbox__label--small')]")).click();
I did looked around and found someone suggested to use this (below) so i tried but didn't work:
WebElement elem = driver.findElement(By.xpath("//div[contains(#class,'checkbox u-mar-bot-5')]"));
Actions action = new Actions(driver);
action.moveToElement(elem).click().build().perform();
Any suggestion would be appreciated.
Since you tried the ID of the INPUT and it threw an error that it wasn't visible, I would first try a wait to see if it will become visible. (I'm assuming it won't but it's worth a try first).
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.id("basket-contact-terms"))).click();
If that doesn't work, I would next try to click a different position on the element. By default, Selenium clicks on the center of the element. In your case, I think this is what's causing the issue. You can use Actions to click the upper left (1,1) of the element.
WebElement label = driver.findElement(By.xpath("//label[#for='basket-contact-terms']"));
new Actions(driver).moveToElement(label, 1, 1).click().perform();
You can try with
WebElement elem = driver.findElement(By.id("basket-contact-terms"))

Not able to click a button using Selenium and Java. It has "style=display: none" in html which is causing issue

I have tried with different xpaths etc but not able to click a 'Continue' button in my application. Following is one of the attempt to handle the same:-
WebDriverWait wait2 = new WebDriverWait(driver,20);
WebElement continueBtn = wait2.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[#type = 'submit' and #class = 'btn btn--primary']")));
When I inspect element I find follwing details in it: -
<button class="btn btn--primary" type="submit" data-bind="enable: !processing() && !$root.accountLocked()">
<svg xmlns="http://www.w3.org/2000/svg" class="icon shape--loader" style="display: none;" viewBox="0 0 16 16" focusable="false" data-bind="visible: processing()">
<title>Processing</title>
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#shape--loader" />
</svg>
Continue
</button>
The error thrown is as follow:-
Exception in thread "main" org.openqa.selenium.TimeoutException: Timed out after 20 seconds waiting for element to be clickable: By.xpath: //*[#type = 'submit' and #class = 'btn btn--primary']
However the object/element was already loaded so not sure why it couldn't click the element.
I also tried JavaScript executor but to no avail.
Please help me resolve it. Thanks in advance !!!
Just to clear the air, is the XPath given above is unique?
If yes did you give it a try with JSExecutor?
Try with below code:
WebElement element = driver.findElement(By.xpath("//*[#type = 'submit' and #class = 'btn btn--primary']")));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
If it is difficult to findelement with attributes, then find it based on button name. If there is only one Continue button in the page like.
WebElement continueBtn = wait2.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(),'Continue')]")));
Finally I got the solution. Before reaching solution I tried explicit wait, code of which I had pasted in question itself and then tried with JavaScript executor but it also didn't work. Following is the solution:-
Actions action = new Actions(driver);
action.sendKeys(Keys.ENTER).build().perform();
It worked perfactly fine. Thank you guys who all contributed their time and efforts.

Selenium - webDriver not stable-error stack trace

I am not able to click on the submit button inside the modal. It only works sometimes - it's not stable.
Below is my HTML element:
<button id="submit-btn" name="submit" data-dismiss="modal" type="submit" class="btn btn-info btn-sm submit projectSaveBtn">Submit</button>
Here I'm using id for locating the element, but I'm not able to click on the submit button inside the modal.
My Java code:
WebElement element1 = driver.findElement(By.id("submit-btn"));
Actions actions = new Actions(driver);
actions.moveToElement(element1).build().perform();
wait.until(ExpectedConditions.elementToBeClickable(element1)).click();
When we use the action class, selenium takes mouse and keyboard controls. If we interact with mouse or keyboard at the time of test execution (specially the actions statement execution), it may fail some times.
You can try with actions class and don't interact until it completes the test execution. it may solve your issue.
Instead of using the id attribute you can use an xpath as follows :
WebElement element1 = driver.findElement(By.xpath("//button[#id='submit-btn']"));
element1.click();
or
WebElement element2 = driver.findElement(By.xpath("//button[#class='btn btn-info btn-sm submit projectSaveBtn' and #id='submit-btn']"));
element2.click();
If it's a windows modal dialog box, you might want to first switchTo() to the modal and then perform accept() on it.
driver.switchTo().alert().accept();
driver.switchTo().window("");
I solved the issue, it was timing issue .Modal was opened before the page loaded properly so giving the time before clicking/opening modal solves the issue .
Here is my code -->
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement add = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.btn.projectAddBtn")));
add.click();
This solved my issue.Thank you all for the support :-)

Categories