Limiting WebDriver scope is not working as expected - java

Can anyone please explain why data.size() is coming up as 13 and why data1.size() is coming up as 364?
As per my understanding, data.size() should be 0 because <td> is not a valid xpath expression and data1.size() should be 13 as there are 13 <td> tags inside/under the precipitation element. 364 is actually the total number of "td" tags in the particular webpage.
System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Java\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://en.wikipedia.org/wiki/York");
Actions a = new Actions(driver);
WebElement precipitation = driver.findElement(By.xpath("//a[#title='Precipitation']//ancestor::tr"));
a.moveToElement(precipitation).build().perform();
List<WebElement> data = precipitation.findElements(By.xpath("td"));
List<WebElement> data1 = precipitation.findElements(By.xpath("//td"));
List<WebElement> data2 = precipitation.findElements(By.tagName("td"));
List<WebElement> data3 = precipitation.findElements(By.cssSelector("td"));
List<WebElement> data4 = driver.findElements(By.cssSelector("td"));
List<WebElement> data5 = driver.findElements(By.xpath("td"));
List<WebElement> data6 = driver.findElements(By.xpath("abcxyz"));
System.out.println("data = " +data.size());
System.out.println("data1 = " +data1.size());
System.out.println("data2 = " +data2.size());
System.out.println("data3 = " +data3.size());
System.out.println("data4 = " +data4.size());
System.out.println("data5 = " +data5.size());
System.out.println("data6 = " +data6.size());
driver.close();

Actually "td" is a valid expression, it selects the nodes with node name td, and since you are not using / or // the search doesn't start in a higher element in the DOM hierarchy. This means that
precipitation.findElements(By.xpath("td"));
is the equivalent of
driver.findElement(By.xpath("//a[#title='Precipitation']//ancestor::tr/td"));
// will locate all the matching elements in the DOM, i.e. all the <td> nodes. If you want to use precipitation as the root node and start the search from there you need to add . for current context
precipitation.findElements(By.xpath(".//td"));
for all <td>s under the <tr>, or
precipitation.findElements(By.xpath("./td"));
for direct children of the <tr>
See XPath Syntax for reference.

Selecting Nodes
XPath uses path expressions to select nodes in an XML document. The node is selected by the help of the following semantics:
So as per the discussion above once you identify the webElement precipitation
WebElement precipitation = driver.findElement(By.xpath("//a[#title='Precipitation']//ancestor::tr"));
next to get the descendent <td> tags instead of:
List<WebElement> data = precipitation.findElements(By.xpath("td"));
As per the discussion above to identify the desired descendant <td> elements in the most effective way, you need to append the / character to denote from the from which node you would initiate the search.
So effectively, your line of code will be:
List<WebElement> data = precipitation.findElements(By.xpath(".//td"));
In a single line:
List<WebElement> data = precipitation.findElements(By.xpath("//a[#title='Precipitation']//ancestor::tr//td"));
which would select for you the correct 13 nos of desired <td> nodes.

Related

Check that two span classes are equal to text and click on the correct span element after

I have two span elements and I need to check that my text: Frat Brothers (2013) is equal to text inside this span clases and that click on this element.
<a href="/frat-brothers" class="">
<span class="name-content-row__row__title">Frat Brothers</span>
<span class="name-content-row__row--year">(2013)</span>
</a>
My code:
String title = "Frat Brothers (2013)";
List<WebElement> content = driver.findElements(By.cssSelector("span[class*='name-content-row__'"));
for (WebElement e : content) {
System.out.println("elememts is : " + e.getText());
if (e.getText().equals(title)) {
click(e);
}
output:
elememts is : Frat Brothers
elememts is : (2013)
if statment isn't executed.
if statment did not execute, cause you have
String title = "Frat Brothers (2013)";
change that to
String title = "Frat Brothers";
and you should be good to go.
also do not use click(e); instead it should be e.click();
driver.findElements method accepts By parameter while you passing it a String.
In case you want to select elements according to this CSS Selector you can do this:
List<WebElement> content = driver.findElements(By.cssSelector("span[class*='name-content-row__'"));
Also, you will get 2 span elements, first with text Frat Brothers and second with text (2013).
No one of these elements text will NOT be equal to Frat Brothers (2013).
You can check if title contains these texts
You can try the following xPath: //a[normalize-space()='Frat Brothers (2013)']
So that there would be no need for extra code. Like:
String title = "Frat Brothers (2013)";
WebElement content = driver.findElement(By.xpath("//a[normalize-space()='" + title + "']"));
content.click();
P.S. - Here is the xPath test: http://xpather.com/V9cjThsr
Text verification, add testng dependency in your pom.xml
String title = "Frat Brothers (2013)";
// storing text from the element
String first = driver.findElements(By.cssSelector("span[class*='name-content-row__'")).get(0).getText();
String second = driver.findElements(By.cssSelector("span[class*='name-content-row__'")).get(1).getText();
// validating the text
Assert.assertTrue(title.contains(first), "checking name is available in the element");
Assert.assertTrue(title.contains(second), "checking year is available in the element");

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"));

Is there any tool available to identify particular text in the href element?

Lets consider below href element, here I need to identify "cn=" text in the all the available href links.
My page has 1000 href elements, in that I need to identify the href url which has "cn=" text.
href="/software-advice/article/maternity-benifits-of-office-cn=welcome-inc"
You can use following css selector to identify the number of elements whose href value contains cn=
List<WebElement> listElement=driver.findElements(By.cssSelector("a[href*='cn=']"));
System.out.println("Total number of elements :" + listElement.size());
Or identify the anchor tag and then get the attribute value and then check the value contains
List<WebElement> listelement=driver.findElements(By.cssSelector("a[href]"));
for(WebElement ele:listelement)
{
if(ele.getAttribute("href").contains("cn="))
{
System.out.println("Text found");
}
}
You can use selenium webDriver. and the code snippet is given below
//Get all the webelement starts with tagname a
List<WebElement> urllinks = driver.findElements(By.tagName("a"));
//Iterate one by one until last element present
for (int i = 0; i < urllinks.size(); i++) {
WebElement urllink = urllinks.get(i);
//Get Attribute
String link = urllink.getAttribute("href");
if (link.contains("cn=") {
System.out.println("href contains cn=");
System.out.println(link)
}
Sure go with XPath
//a[contains(#href,'cn=')]
it will identify all the href which has cn= present in it on the page.
if you are sure there is only one element then
WebElement desiredElement=driver.findElements(By.xpath("//a[contains(#href,'cn=')]"));

How to get Selenium Text But When Product Has Discount Element Changes

(JAVA) I select random product from the site. Sometimes it has discount sometimes it does not.
For example:
How can I get 748(product without discount)
or How can I get 419 (product with discount)
When Product has discount The element is :
<div class="pb-basket-item-price">748 TL</div>
When Other Product doesnt have discount The element is :
<div class="pb-basket-item-price">
<span>499 TL</span>
"419 TL"</div>
List<WebElement> elements = driver.findElements(By.xpath("//div[contains(#class, 'pb-basket-item-price')]"));
for (WebElement element : elements) {
String str = element.getText();
System.out.println("original string: " + str);
if (str.contains("\"")) {
str = str.split("\"")[1];
}
System.out.println("this is what you need: " + str);
}
, below is the running log:
original string: 748 TL
this is what you need: 748 TL
original string: 499 TL "419 TL"
this is what you want: 419 TL
EDIT
Modify according to the question owner's comments.
Suppose: HTML looks like:
<div class="pb-basket-item-price">748 TL</div>
<div class="pb-basket-item-price">
<span>499 TL</span>
"419 TL"</div>
<div class="pb-basket-item-price">
<span>3.374,34 TL</span>
2.339 TL</div>
code:
List<WebElement> elements = driver.findElements(By.xpath("//div[contains(#class, 'pb-basket-item-price')]"));
for (WebElement element : elements) {
String str = element.getText();
int cntTL = (str.length() - str.replace("TL", "").length()) / 2;
if (2 == cntTL) {
str = str.split("TL")[1].replace("\"", "") + " TL";
}
System.out.println("this is what you need: " + str);
// str is what you want!
}
You need to get the elements first of all like:
List<WebElement> elements = driver.findElements(By.xpath("//div[contains(#class, 'pb-basket-item-price')]"));
Then you may iterate through the List of Webelements and check for the specific text the element should have.
Grab the product tag and then proceed inwards checking if it has a span or not.
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement outertag = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[contains(#class, 'pb-basket-item-price')")));
List<WebElement> innertag = outertag.findElements(By.xpath("//span"));
if(innertag.size()>0){
System.out.println(innertag.get(0).getText());
}
else{
System.out.println(outertag.getText());
}
So the idea behind is,
you first need to figure out the elements and convert them to list.
$x("//div[contains(#class, 'pb-basket-item-price')]")
Once you have the list in place, you need to find the lastChild for each element in the list.
$x("//div[contains(#class, 'pb-basket-item-price')]")[1].lastChild -> 499 TL
$x("//div[contains(#class, 'pb-basket-item-price')]")[2].lastChild -> 748 TL
Now you have everything in place, try putting this logic in code.
To print the texts you can use either of the following Locator Strategies:
748
Using css_selector and get_attribute():
print(driver.find_element_by_css_selector("div.pb-basket-item-price").get_attribute("innerHTML"))
Using xpath and text attribute:
print(driver.find_element_by_xpath("//div[#class='pb-basket-item-price']").text)
419
Using css_selector and textContent:
print(driver.execute_script('return arguments[0].lastChild.textContent;', driver.find_element_by_css_selector("div.pb-basket-item-price")).strip())
Using xpath and textContent:
print(driver.execute_script('return arguments[0].lastChild.textContent;', driver.find_element_by_xpath("//div[#class='pb-basket-item-price']).strip())

Reading webpage's inspect element data using java

I have a requirement . I am reading file from a dynamic web page , and the values which i require from the webpage lies within
<td>
, and this is visible when i inspect this element . So my question is , is it somehow possible to print the data contained in the inspect element using java?
Using JSOUP. Here is the cookbook
ArrayList<String> downServers = new ArrayList<>();
Element table = doc.select("table").get(0);
Elements rows = table.select("tr");
for (int i = 1; i < rows.size(); i++) {
Element row = rows.get(i);
Elements cols = row.select("td");
// Use cols.get(index) to get the data from td element
}
I found the solution to this one , leaving this answer in case if anyone stuck into this in future.
To print whatever you see inside inspect element can be tracked down using selenium.
Here's the code which i used `
WebDriver driver= new ChromeDriver();
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("http://www.whatever.com");
Thread.sleep(1000);
List<WebElement> frameList = driver.findElements(By.tagName("frame"));
System.out.println(frameList.size());
driver.switchTo().frame(0);
String temp=driver.findElement(By.xpath("/html/body/table/thead/tr/td/div[2]/table/thead/tr[2]/td[2]")).getText();
read here for more .

Categories

Resources