Click element by available id - java

I have a strange case where Angular element is rendering html with 2 random IDs:
WebDriverWait webDriverWait = new WebDriverWait(driver, 5);
System.out.println("Click on Sub Tab " + title_id + " using id locator " + tab_id);
WebElement webElement = webDriverWait.until(ExpectedConditions.elementToBeClickable(By.id("mat-tab-label-5-0")));
webElement.click();
OR
WebDriverWait webDriverWait = new WebDriverWait(driver, 5);
System.out.println("Click on Sub Tab " + title_id + " using id locator " + tab_id);
WebElement webElement = webDriverWait.until(ExpectedConditions.elementToBeClickable(By.id("mat-tab-label-3-0")));
webElement.click();
The order is random and I need some way to click on the available id. Is there some way to combine then for example:
By.id("mat-tab-label-3-0" OR "mat-tab-label-5-0")
Is there some solution?

You can switch to a CSS selector.
ExpectedConditions.elementToBeClickable(By.cssSelector("#mat-tab-label-3-0,#mat-tab-label-5-0"))
# indicates an ID and , indicates an OR.

Assuming those 2 listed are the only 2 ID's that show up, but it is random which one shows up, you can try this:
WebElement webElement = webDriverWait.until(ExpectedConditions.elementToBeClickable(By.id("mat-tab-label-3-0" | "mat-tab-label-5-0")));

Related

Unable to click a button inside iframe which itself is inside shadow root in Selenium WebDriver using Java

driver.get("https://thesportstak.com/");
Thread.sleep(4000);
WebElement scrollStory = driver.findElement(By.xpath("//div[#id='story3']"));
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
wait.until(ExpectedConditions.visibilityOf(scrollStory));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].scrollIntoView(true);", scrollStory);
List<WebElement> homeStories = driver.findElements(By.xpath("//div[#class=\"mainDiv \"]"));
List<WebElement> homeStoriesptag = driver.findElements(By.xpath("//div[#class=\"mainDiv \"]//p"));
for (WebElement homeStoryp : homeStoriesptag) {
System.out.println("getting home story p tag " + homeStoryp);
System.out.println("Text of home story " + homeStoryp.getText());
}
WebElement firstStory =homeStories.get(3);
firstStory.click();
Thread.sleep(3000);
WebElement shadow = driver.findElement(By
.cssSelector("div[class=\"i-amphtml-fill-content i-amphtml-story-player-shadow-root-intermediary\"]"));
// This Element is inside single shadow DOM.
SearchContext shadowroot = shadow.getShadowRoot();
Thread.sleep(1000);
WebElement iframe = shadowroot.findElement(By.cssSelector(" div:nth-child(1) > iframe:nth-child(3)"));
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(iframe));
List<WebElement> please = driver.findElements(By.xpath("//div[#class=\"letterbox\"]//p"));
System.out.println(please);
WebElement nextbutton =driver.findElement(By.cssSelector("button[aria-label='Next page']"));
for(WebElement letterstory : please) {
wait.until(ExpectedConditions.attributeToBeNotEmpty(letterstory,"class"));
wait.until(ExpectedConditions.elementToBeClickable(nextbutton));
***nextbutton.click();*** ---->>>
I am trying to click the above button. Next button.click. I have tried both xpath and css selector to find the button.
Also, I can only fetch the text from the first story above, the rest elemenets are present, but no text can be fetched from that. the p tag and the texts are present in the DOM and can be seen in the first story itself. last line.
Kindly help regarding the same.
System.out.println("stories element "+ letterstory);
***System.out.println("stories inside "+letterstory.getText());***
}

Veryfing if an elment is present in a non-editable page

I am trying to verify if an element is present or not in a non editable page or not. This is my html file:
<select name="sys_readonly.req_item.state" aria-readonly="true" aria-disabled="true" id="sys_readonly.sc_req_item.state"><option value="1" selected="SELECTED" role="option" disabled="disabled">Open</option><option value="2" role="option" disabled="disabled">Work in Progress</option></select>
I am trying to verify that that the select name="sys_readonly.req_item.state" has the option "open". This is what I have done till now:
new WebDriverWait(driver,60).until(
ExpectedConditions.or(
ExpectedConditions.visibilityOf(driver.findElement(By.id("sys_readonly.req_item.state")))
)
);
Select droplist = new Select(driver.findElement(By.name("new WebDriverWait(driver,60).until(
ExpectedConditions.or(
ExpectedConditions.visibilityOf(driver.findElement(By.id("sys_readonly.req_item.state")))
)
);
Select droplist = new Select(driver.findElement(By.name("sys_readonly.req_item.state")));
WebElement o = droplist.getFirstSelectedOption();
String selectedoption = o.getText();
System.out.println("Selected element: " + selectedoption);
I am getting the error:
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element:{"method":"css selector","selector":"#sys_readonly.req_item.state"}
Can someone please help?
As per the HTML given by you, the id used is incorrect:
driver.findElement(By.id("sys_readonly.req_item.state"));
Try to use:
driver.findElement(By.xpath("//*[#id='sys_readonly.sc_req_item.state']"));
OR
driver.findElement(By.id("sys_readonly.sc_req_item.state"));
I have tried to use the code and got the below result:
Code:
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement ele = driver.findElement(By.name("sys_readonly.req_item.state"));
wait.until(ExpectedConditions.visibilityOf(ele));
Select droplist = new Select(ele);
WebElement o = droplist.getFirstSelectedOption();
String selectedoption = o.getText();
System.out.println("Selected element: " + selectedoption);
for (WebElement selectList : droplist.getAllSelectedOptions()) {
System.out.println(selectList.getText());
}
Screenshot:
There are several issues here:
You are using a wrong locator. sys_readonly.req_item.state is the element name attribute value, not id.
You are asking about element presence but validating it's visibility. These are not the same. Element can be presented (existing) on the page, but not be visible.
So, you can get the element and then extract it option attribute and validate if open value is existing there
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.presenceOfElementLocated(By.name("sys_readonly.req_item.state")));
String option_val = driver.findElement(By.name("sys_readonly.req_item.state"))..getAttribute(option);
Assert.assertTrue(option_val.contains("open"));

Searching and adding product in cart of bigbasket using selenium

I was trying to search and add product in the cart using selenium but was not able to successfully do it
driver.get("https://www.bigbasket.com/cl/fruits-vegetables/?nc=nb");
List<WebElement> product = driver.findElements(By.xpath("//div[#qa=\'product\']"));
System.out.println("prdoduct=" + product.size());
for(int i=0;i<product.size();i++)
{
String name = product.get(i).getText();
System.out.println("NAME is" + name);
String xp= "(//button[#qa=\'add\'])" + "["+i+ "]";
System.out.println("xp="+xp);
if(name.contains("Cauliflower"))
{
System.out.println("xp" +xp);
driver.findElement(By.xpath(xp)).click();
}
}
In this previous product is getting selected but when I was debugging it was on the cauliflower but still the previous product is getting selected
there is a chance that some time the element get overlapped by another element. At this time, the normal selenium click will try to click on the overlapped element. so it is better to use js click, it will click the exact element even if it is overlapped
WebElement element= driver.findElement(By.xpath(xp));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", element);
There is also a chance for issue in your xpath. Since list starts at 0 , you may need to change i in to i+1 in xp for getting current selection add button.do try this xpath too
String xp= "(//button[#qa=\'add\'])" + "["+(i+1)+ "]";
Induce WebDriverWait() and wait for visibilityOfAllElementsLocatedBy() and use following css selector and xpath.
driver.get("https://www.bigbasket.com/cl/fruits-vegetables/?nc=nb");
List<WebElement> product =new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("div[qa='product_name']>a")));
System.out.println("prdoduct=" + product.size());
for(int i=0;i<product.size();i++)
{
String name = product.get(i).getText();
System.out.println("NAME is" + name);
if(name.contains("Cauliflower"))
{
driver.findElement(By.xpath("//div[#qa='product_name']//a[text()='" + name + "']/following::button[1]")).click();
}
}

Selenium Webdriver: How to wait untill progressbar vanishes and click on the button [duplicate]

I used explicit waits and I have the warning:
org.openqa.selenium.WebDriverException:
Element is not clickable at point (36, 72). Other element would receive
the click: ...
Command duration or timeout: 393 milliseconds
If I use Thread.sleep(2000) I don't receive any warnings.
#Test(dataProvider = "menuData")
public void Main(String btnMenu, String TitleResultPage, String Text) throws InterruptedException {
WebDriverWait wait = new WebDriverWait(driver, 10);
driver.findElement(By.id("navigationPageButton")).click();
try {
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(btnMenu)));
} catch (Exception e) {
System.out.println("Oh");
}
driver.findElement(By.cssSelector(btnMenu)).click();
Assert.assertEquals(driver.findElement(By.cssSelector(TitleResultPage)).getText(), Text);
}
WebDriverException: Element is not clickable at point (x, y)
This is a typical org.openqa.selenium.WebDriverException which extends java.lang.RuntimeException.
The fields of this exception are :
BASE_SUPPORT_URL : protected static final java.lang.String BASE_SUPPORT_URL
DRIVER_INFO : public static final java.lang.String DRIVER_INFO
SESSION_ID : public static final java.lang.String SESSION_ID
About your individual usecase, the error tells it all :
WebDriverException: Element is not clickable at point (x, y). Other element would receive the click
It is clear from your code block that you have defined the wait as WebDriverWait wait = new WebDriverWait(driver, 10); but you are calling the click() method on the element before the ExplicitWait comes into play as in until(ExpectedConditions.elementToBeClickable).
Solution
The error Element is not clickable at point (x, y) can arise from different factors. You can address them by either of the following procedures:
1. Element not getting clicked due to JavaScript or AJAX calls present
Try to use Actions Class:
WebElement element = driver.findElement(By.id("navigationPageButton"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
2. Element not getting clicked as it is not within Viewport
Try to use JavascriptExecutor to bring the element within the Viewport:
WebElement myelement = driver.findElement(By.id("navigationPageButton"));
JavascriptExecutor jse2 = (JavascriptExecutor)driver;
jse2.executeScript("arguments[0].scrollIntoView()", myelement);
3. The page is getting refreshed before the element gets clickable.
In this case induce ExplicitWait i.e WebDriverWait as mentioned in point 4.
4. Element is present in the DOM but not clickable.
In this case induce ExplicitWait with ExpectedConditions set to elementToBeClickable for the element to be clickable:
WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.elementToBeClickable(By.id("navigationPageButton")));
5. Element is present but having temporary Overlay.
In this case, induce ExplicitWait with ExpectedConditions set to invisibilityOfElementLocated for the Overlay to be invisible.
WebDriverWait wait3 = new WebDriverWait(driver, 10);
wait3.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("ele_to_inv")));
6. Element is present but having permanent Overlay.
Use JavascriptExecutor to send the click directly on the element.
WebElement ele = driver.findElement(By.xpath("element_xpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
In case you need to use it with Javascript
We can use arguments[0].click() to simulate click operation.
var element = element(by.linkText('webdriverjs'));
browser.executeScript("arguments[0].click()",element);
I ran into this error while trying to click some element (or its overlay, I didn't care), and the other answers didn't work for me. I fixed it by using the elementFromPoint DOM API to find the element that Selenium wanted me to click on instead:
element_i_care_about = something()
loc = element_i_care_about.location
element_to_click = driver.execute_script(
"return document.elementFromPoint(arguments[0], arguments[1]);",
loc['x'],
loc['y'])
element_to_click.click()
I've also had situations where an element was moving, for example because an element above it on the page was doing an animated expand or collapse. In that case, this Expected Condition class helped. You give it the elements that are animated, not the ones you want to click. This version only works for jQuery animations.
class elements_not_to_be_animated(object):
def __init__(self, locator):
self.locator = locator
def __call__(self, driver):
try:
elements = EC._find_elements(driver, self.locator)
# :animated is an artificial jQuery selector for things that are
# currently animated by jQuery.
return driver.execute_script(
'return !jQuery(arguments[0]).filter(":animated").length;',
elements)
except StaleElementReferenceException:
return False
You can try
WebElement navigationPageButton = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("navigationPageButton")));
navigationPageButton.click();
Scrolling the page to the near by point mentioned in the exception did the trick for me. Below is code snippet:
$wd_host = 'http://localhost:4444/wd/hub';
$capabilities =
[
\WebDriverCapabilityType::BROWSER_NAME => 'chrome',
\WebDriverCapabilityType::PROXY => [
'proxyType' => 'manual',
'httpProxy' => PROXY_DOMAIN.':'.PROXY_PORT,
'sslProxy' => PROXY_DOMAIN.':'.PROXY_PORT,
'noProxy' => PROXY_EXCEPTION // to run locally
],
];
$webDriver = \RemoteWebDriver::create($wd_host, $capabilities, 250000, 250000);
...........
...........
// Wait for 3 seconds
$webDriver->wait(3);
// Scrolls the page vertically by 70 pixels
$webDriver->executeScript("window.scrollTo(0, 70);");
NOTE: I use Facebook php webdriver
If element is not clickable and overlay issue is ocuring we use arguments[0].click().
WebElement ele = driver.findElement(By.xpath("//div[#class='input-group-btn']/input"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
The best solution is to override the click functionality:
public void _click(WebElement element){
boolean flag = false;
while(true) {
try{
element.click();
flag=true;
}
catch (Exception e){
flag = false;
}
if(flag)
{
try{
element.click();
}
catch (Exception e){
System.out.printf("Element: " +element+ " has beed clicked, Selenium exception triggered: " + e.getMessage());
}
break;
}
}
}
In C#, I had problem with checking RadioButton,
and this worked for me:
driver.ExecuteJavaScript("arguments[0].checked=true", radio);
Can try with below code
WebDriverWait wait = new WebDriverWait(driver, 30);
Pass other element would receive the click:<a class="navbar-brand" href="#"></a>
boolean invisiable = wait.until(ExpectedConditions
.invisibilityOfElementLocated(By.xpath("//div[#class='navbar-brand']")));
Pass clickable button id as shown below
if (invisiable) {
WebElement ele = driver.findElement(By.xpath("//div[#id='button']");
ele.click();
}

How to scroll down of specific div to locate an element and make it clickable via selenium webdriver in java

I need to click on a button 'NEW'. The element button is visible on DOM but it's not clickable because it's overlapped and i need to scroll down left side of the page to make it clickable. I was trying inject some javascript but it didn't help in my case:
JavascriptExecutor js = ((JavascriptExecutor) driver);
js.executeScript("scroll(" + driver.findElement(By.xpath(//div[#class = 'save-new'])).getLocation().getX() + "," + driver.findElement(By.xpath(//div[#class = 'save-new'])).getLocation().getY() + ")");
As i feel #damian should worked but you can also tried my code I used it so mny times
Use this code:
WebElement element = driver.findElement(By.xpath("Value"));
((JavascriptExecutor)driver).executeScript(“arguments[0].scrollIntoView();”, element);
element.click();
Try:
targetElement = driver.findElement(By.xpath("your xpath"));
JavascriptExecutor js = ((JavascriptExecutor) driver);
// This:
js.executeScript("arguments[0].scrollIntoView(true);", targetElement);
targetElement.click();
// Or maybe even just:
js.executeScript("arguments[0].click();", targetElement);
You can try this way:--
JavascriptExecutor js = ((JavascriptExecutor) driver);
//Scroll your page to down using below code
((JavascriptExecutor)driver).executeScript(“window.scroll(100,2000)”);
// click on button
driver.findElement(By.xpath(//div[#class ='save-new'])).click()
Hope this help you :)

Categories

Resources