Element not visible error with XPath - java

I got the problem with an XPath.
I can use this xpath: //*[#id='name']//*[#class='class']//div[1] -> can run ok.
But I want use div[2] ex: //*[#id='name']//*[#class='class']//div[2] , it gives error that element is not visible.
Anyone help me plz, I don't know why div[1] can run but div[2] is not visible.
My HTML code here:
<div class="class">
<div class="action-item" data-id="24" data-actioncode="STT">
<i class="fa fa-play"></i>
S T T
</div>
<div class="action-item" data-id="29" data-actioncode="FULL">
<i class="fa fa-play"></i>
FULL
</div>
<div class="action-item" data-id="30" data-actioncode="TEACHER">
<i class="fa fa-play"></i>
TEACHER
</div>
</div>
Code I have tried:
WebElement btnElement = driver.findElement(By.xpath("//[#id='name']//[#class='class']//div[2]"));
WebDriverWait wait= new WebDriverWait(driver,10 );
wait.until(ExpectedConditions.visibilityOf(btnElement));
btnElement.click();

You can try out this code :
new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#data-actioncode='FULL']")));
driver.findElement(By.xpath("//div[#data-actioncode='FULL']")).click();

As per the HTML you have shared to click on the element with text as FULL you have to induce WebDriverWait for the element to be clickable and you can use either of the following locators :
css_selector (attribute based) :
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("div.class div.action-item[data-actioncode='FULL']"))).click();
xpath (attribute based) :
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//div[#class='class']//div[#class='action-item' and #data-actioncode='FULL']"))).click();
xpath (text based) :
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//div[#class='class']//div[#class='action-item'][normalize-space()='FULL']"))).click();

You can use CSS selector path as well like for div 2 it is :
div.action-item:nth-child(2)
Thanks.

You can make use of the action-item class to validate.
use x-path to identify the classname and then do an n-th child:
xpath("//[#id='name']//[#class='class']//[#class='action-item']:nth-child(2)"));
or you can use the index value as well, as these are inside the same class.
difference is, the index value for the second item is gonna be 1.
alternately, you can use cssContainText as well to identify by the text.

Related

Selenium, build XPath in java, to click on the button

I need please your help to build XPath, click on the button :
HTML is :
<div class="offer col-md gtm-data gtm-impression slick-slide" data-gtm-id="5608" data-gtm-title="230 גיגה Rolling Package" data-gtm-price="33.00" data-gtm-category="חבילות" data-gtm-list="homepage" data-gtm-position="4" data-slick-index="3" aria-hidden="true" tabindex="-1" style="width: 370px;" xpath="1">
<div class="upper">
<div class="title"><spam class="threshold">230</spam><spam class="units">GB</spam></div>
<div class="subtitle"><p>Rolling Package</p>
</div>
<!--<div class="comment"><span>test</span></div>-->
</div>
<div class="bottom">
<div class="price-area">
<div class="title"><spam class="price-number"><span class="number">33</span></spam> </div>
<div class="subtitle">
<span></span>
</div>
</div>
<div class="link">
Join Now
</div>
</div>
</div>
When I try to click on the button,
by XPath :
//div[contains(#data-gtm-id, '5608')] //a[#class='button red full gtm-click']
I got this error :
org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element להצטרפות is not clickable at point (951, 858). Other element would receive the click: <p>...</p>
(Session info: chrome=96.0.4664.45)
When I try :
(//a[contains(#class,'button red')])[2]
I can click on the button,
But I want the code to be more dynamic.
The data-gtm-id attribute is a Google Tag Manager attribute and the value of data-gtm-id attribute i.e. 5608 is dynamically generated. Everytime you access the application it would get changed. So you won't be able to locate the element using the attribute data-gtm-id
To click() on the element with text as Join Now you can use either of the following Locator Strategies:
linkText:
driver.findElement(By.linkText("Join Now")).click();
cssSelector:
driver.findElement(By.cssSelector("a.button.red.full.gtm-click[title='Join Now']")).click();
xpath:
driver.findElement(By.xpath("//a[#class='button red full gtm-click' and text()='Join Now']")).click();
However, as the element is a dynamic element so to click() on the element you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the following Locator Strategies:
linkText:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.linkText("Google"))).click();
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("a.button.red.full.gtm-click[title='Join Now']"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#class='button red full gtm-click' and text()='Join Now']"))).click();
I hope your element is right but it is clicking before it is loaded, so please add wait condition.
By joinNowBtn = By.xpath("//a[contains(text(),'Join Now')]");
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.elementToBeClickable(joinNowBtn));
wait.until(ExpectedConditions.visibilityOfElementLocated(joinNowBtn));
driver.findElement(joinNowBtn).click();

Finding element by using data test id in Selenium Java

This is my HTML tree:
<div data-focusable="true" tabindex="0" class="css-1dbjc4n" data-testid="nav-Look up items-item"><div class="css-1dbjc4n"><div class="css-1dbjc4n" data-testid="nav-Look up items-item-Look up items-icon"><div class="css-1dbjc4n"><div dir="auto" class="css-901oao r-1awozwy" data-testid="nav-Look up items-item-Look up items">Look up items</div>
I am trying to locate the element by data-testid
I have used css selector and xpath which looks like the following:
#FindBy(css = "div[data-testid='nav-Look up items-item']")
#FindBy(xpath = "//div[#data-testid='nav-Look up items-item']")
But it is not able to locate the element.
Can anyone please help? Thank you.
I'm just going to re-write your tree here because this is easier for me to understand this way.
<div data-focusable="true" tabindex="0" class="css-1dbjc4n" data-testid="nav-Look up items-item">
<div class="css-1dbjc4n">
<div class="css-1dbjc4n" data-testid="nav-Look up items-item-Look up items-icon">
<div class="css-1dbjc4n">
<div dir="auto" class="css-901oao r-1awozwy" data-testid="nav-Look up items-item-Look up items">Look up items</div>
</div>
</div>
</div>
</div>
You could always try selecting the className with something like this:
WebElement element = driver.findElement(By.className("css-901oao"));
or
WebElement element = driver.findElement(By.className("r-1awozwy"));
If that doesn't work you could try using a Chrome Extension like xPath Finder to try to find the absolute xPath and find it using something like:
WebElement element = driver.findElement(By.xpath("/html/body/div/div/div/div/div"));
But as your trying to select a div the className is more likely to work
You should use it like this
#FindBy(xpath = "//div[#data-testid='nav-Look up items-item']")
WebElement lookUpItems;
and you can (let's say wanna perform .click)
lookUpItems.click();

selenium get li element based on index position and click the checkbox

I have this HTML now using Selenium I ant to toggle the li element with given index position say 1, where it indicates I want to click the toggle checkbox for spring.
<ul id="todo-list" data-woven="abc">
<li class="active" data-index="0">
<div class="view">
<input class="toggle" type="checkbox">
<label>Java</label>
<button class="destroy"></button>
</div>
<input class="edit">
</li>
<li class="active" data-index="1">
<div class="view">
<input class="toggle" type="checkbox">
<label>Spring</label>
<button class="destroy"></button>
</div>
<input class="edit">
</li></ul>
I am completely new to selenium so not able to understand how can we achieve this.
I know to get the UL elements using the code:
driver.findElement(By.id("todo-list"));
Now how can get the li element based on its index and click the corresponding checkbox.
To click on the checkbox element with respect to the ancestor <li> nodes index attribute you can use either of the following Locator Strategies:
cssSelector:
driver.findElement(By.cssSelector("ul#todo-list li.active[data-index='1'] input")).click();
xpath:
driver.findElement(By.xpath("//ul[#id='todo-list']//li[#class='active' and #data-index='1']//input")).click();
You can use xpath to locate an element with data-index=1
driver.findElement(By.xpath("//li[#data-index='1']//input[#class='toggle']"));
Or with cssSelector
driver.findElement(By.cssSelector("[data-index='1'] .toggle"));
You could find the element you are looking for directly with the answer #Guy gave you and that would be the right way if you knew exactly what the data-index attribute would be set to, but you could also find a collection of the li elements and then proceed to do what you need within each like this:
var container = driver.findElement(By.id("todo-list"));
var elements = container.findElements(By.tagName("li"));
with elements you can loop through each or go directly to the one you want.

cannot navigate to the target tag in DOM by using numbers in bracket, like div[4]

I am using Java and Selenium to write a test. I have this at DOM:
...
<div class='a'>
<div class='b'>
<div class='1'></div>
<div class='2'></div>
</div>
/div>
...
I am using this Xpath:
//div[#class='a']//div[2]
to get to <div class='1'></div>
but I am taken to:
<div class='2'></div>
in simple words please explain why and how to handle this situation. I do know I can use the class attribute to get to an element like :
//div[#class='1']
but I want to use numbers in bracket style like div[and-a-number-here]
Is there any way to get all divs under a tag and the select the one by the number?
In your xpath:
//div[#class='a']//div[2]
you are searching for any div which is second descendant of the div with a class=a. That's why it's returning you the 2nd div with class=2.
To get the desired element use xpath like this:
//div[#class='a']/div/div[1]

getText() returning blank

<div class="header"> Account</div>
<div class="header"> Email</div>
<div class="value ng-binding">$50</div>==$0
Above is the HTML snippet, i am trying to fetch text: $50, with getText().To locate the element i have used className and xpath.
The problem that i am facing is that, Selenium is able to locate the element but return blank,in place of $50.
it is a good practice if u use 'id' to fetch data in javascript. For your problem you can try like the code below:
<div class="header"> Account</div>
<div class="header"> Email</div>
<div id="value" class="ng-binding">$50</div>==$0
and then try
driver.findElements(By.cssSelector("#value.ng-binding")).getText();
You should instead try using .getAttribute("innerHTML"); on the ClassName to return $50.
agree with Saurabh Gaur
C#
IWebElement div = driver.FindElement(By.CssSelector(".value.ng-binding"));
Console.WriteLine(div.Text);
Use following approach :-
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement el = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".value.ng-binding")));
String text = el.getText();
System.out.println(text);
Output: $50
Hope it will help you..:)

Categories