Selenium- getting correct menu count - selenium

I am trying to get a count of links from top menu.
http://test1.absofttrainings.com/
Here is the xpath I am using:
List<WebElement> home_menu=br.driver.findElements(By.xpath("//a[contains(#href,'http://test1.absofttrainings.com/')]/following-sibling::*//a"));
System.out.println(home_menu.size());
Problem: It prints out 17 while I am expecting 6. What would be the correct way of writing xpath so that it prints out 6?
More info:
List<WebElement> home_menu=br.driver.findElements(By.xpath("//a[contains(#href,'http://test1.absofttrainings.com/')]/following-sibling::*//a"));
System.out.println(home_menu.size());
for(WebElement e: home_menu){
System.out.println(e.getText());
}
print out:
17
Home
Shop
Cart
My Account
Test Pages
How to Use

Try to use below XPath to get required (6) elements only
//ul[#id='top-menu']/li/a

By executing $x("//a[contains(#href,'http://test1.absofttrainings.com/')]/following-sibling::*//a") in the browser console, there are 17 objects.
There is a hidden menu for mobile devices in the website, and your xpath cannot get rid of it. By deleting , now there are 8 objects left.
These 8 links are actually the first 6 menu items + 2 sub-menu items under "Test Pages". In other words, the search button is not captured by your xpath as well.
For selecting the first 6 menu items, execute this xpath,
$x("//nav[#id='top-menu-nav']/ul/li/a")

public static void Count_menu() {
List<WebElement> links = driver.findElements(By.xpath("//a[contains(#href,'http://****=')]"));
System.out.println("Total menu are "+links.size());
int no=1;
for (int i = 1; i<links.size(); i=i+1)
{
if(links.get(i).getText().isEmpty()) {
}
else
{
System.out.println(links.get(i).getText());
no++;
}
}
System.out.println("Total final menu are "+no);
}

Related

How to get all count of all options in a drop down list?

I am trying to calculate all the options displayed inside the 'All tools' dropdown menu on https://smallpdf.com/word-to-pdf
So the total count should be 18 but code calculates as 12 for the options displayed inside the drop down menu
when i run the code, can you check this site and help me with correct code for calculating correct count of sub menu items for 'All menu' drop down.
Here is my code and screenshots:
{
driver.get("https://smallpdf.com/word-to-pdf");
driver.manage().window().maximize();
driver.findElement(By.xpath("//div[#class='smpdf_BsrfvsQ6t09wiN']")).click();
Thread.sleep(2000);
int count=driver.findElements(By.xpath("//div[#class='col-xs-12 ']//ul[#class='smpdf_2Rdvmu2rysHgyv']/child::li")).size();
System.out.println(count);
}
example
Your xpath is not pointing to the correct options list.
you can find the div of the expected div first and then find the expected list options using the above div element
Edit:
working code:
driver.get("https://smallpdf.com/word-to-pdf");
driver.manage().window().maximize();
driver.findElement(By.xpath("//div[#class='smpdf_BsrfvsQ6t09wiN']")).click();
WebElement container=driver.findElement(By.xpath("//div[#class='smpdf_379Xjwyb9lWVFS smpdf_2-apaRtNmCROQL']"));
int count=container.findElements(By.xpath(".//li/ul/li")).size();
System.out.println("Count :"+count);
Try this xpath and code
List<WebElement> elemlist= driver.findElements(By.xpath("//div[#class='smpdf_379Xjwyb9lWVFS smpdf_2-apaRtNmCROQL']//li/ul/li"));
int count = elemlist.size();
System.out.println(count);
Use this xPath:
//div[#class='smpdf_379Xjwyb9lWVFS smpdf_2-apaRtNmCROQL']//li/ul/li
Full code:
driver.manage().window().maximize();
driver.findElement(By.xpath("//div[#class='smpdf_BsrfvsQ6t09wiN']")).click();
Thread.sleep(2000);
int count = driver.findElements(By.xpath("//div[#class='smpdf_379Xjwyb9lWVFS smpdf_2-apaRtNmCROQL']//li/ul/li")).size();
System.out.println(count);
Output:
18
EDIT:
you have asked to show you how I have found the xPath. Here is a screenshot, that shows:

How to click child links of each menu in Selenium with Java

I am trying to use the link https://www.bloomingdales.com/
Click child links of each menu .Below is the code i tried .
public void iClickOnFOBSShouldVerifyTheRespectivePages() throws Throwable {
List allElements = Elements.findElements(By.xpath("//ul[#id='mainNav']/li/a"));
for (int i = 0; i <= allElements.size(); i++) {
List<WebElement> links = Elements.findElements(By.xpath("//ul[#id='mainNav']/li/a"));
WebElement ele = links.get(i);
ele.click();
List<WebElement> childlinks = Elements.findElements("left_facet.left_nav");
for (int j = 0; j <= childlinks.size(); j++) {
List<WebElement> ele2 = Elements.findElements(By.xpath("left_facet.left_nav"));
WebElement ele3 = links.get(i);
ele3.click();
Navigate.browserBack();
}
}
Below is the error i am getting
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
Try This::List<WebElement>ele = driver.findElements(By.xpath("//ul[#id='mainNav']/li/a"));
Actions act =new Actions(driver);
Thread.sleep(4000);
for (int i = 0; i <= ele.size(); i++) {
WebElement a =ele.get(i);
act.moveToElement(a).build().perform();
Thread.sleep(2000);
List<WebElement>ChildMenu=driver.findElements(By.xpath("//nav[#id='nav']/div[2]/div/div/div[#class='flyoutCol']/div/ul/li"));
System.out.println("Sub-Menu="+ChildMenu.size());
for(int j=0;j<ChildMenu.size();j++){
ChildMenu.get(i).click();
Thread.sleep(2000);
driver.navigate().back();
Thread.sleep(2000);
act.moveToElement(a).build().perform();
On clicking any of the links, the browser will open a new page. At that moment the elements in the page corresponding to allElements, ele and ele2 disappear ("element is not attached to the page document") in the browser and are thus not valid anymore. I would expect that the first click on a submenu child would work but anything after that will fail.
What you could do is first check how many children each submenu has, store this in an array and then create a double loop somewhat similar to what you have already done. For each submenu and submenu child click, you can't use any of the webelements in memory of your program because their state was changed so you would need to initialize a completely new webelement.
With xpath you should be able to reference directly to an element like 'parent - 3rd submenu - 7th submenu child'.
I am unfortunately not able to quickly create working code, otherwise I would have done so.
What I am wondering is: what is the purpose of this code? You don't do any assertions, so if any submenu child click leads to an error page, your code will not fail. Is this desired? It might not even fail if clicking doesn't even open an error page. I guess this code would fail if some of the submenu children are present in the HTML but for some reason not visible.
If this is meant to be a test, I would recommend to make a handful of separate tests that cover a few examples (and assert that clicking leads to the expected page) instead of looping through everything. This will make the tests far more understandable for yourself and others.

In selenium, how to click all elements in long list of lazy loaded elements?

What do I have - I'm automating one website where there is a big list of elements but not loaded all at once. Say for example I have 200 elements in the list, but only 10 elements are loaded at the moment, and out of these 10 only 5 are visible on the screen.
What I want to do - Now I want to select all of these elements 1 by 1, by clicking on them, because clicking on element selects check box in front of each (Basically i want to tick checkbox). So i will 1st select 5 elements which are visible on page, then i will scroll down to select another visible group, like wise i want to select all 200 elements.
What Problem I'm facing - webdriver.findElements(..) method is returning list of 10 elements which are loaded. But it is not returning list in the order in which the elements are displayed on the page. I'm using for loop to iterate over the list and clicking on elements one by one.
As a result if 6th element is clicked which is not displayed in page, page scrolls till that element and click it, now after that if 2nd element got chance to be clicked, then page should scrolls up to click it, but this time since DOM has loaded again due to scrolling, I get StaleElementReferenceException. If I handle this exception within try catch and get element list again by finding elements, it is not guaranteed to be in the correct order and does not solve my problem.
Solution?? - Is there any way in selenium to get list of elements in order it is displayed on page? Or please let me know what should be the approach to achieve above scenario?
Any suggestions are much appreciated.
Note - JAVA is being used as a programming laungage.
If you also post the HTML that would be more helpful to explain the solution. I am trying to give you a solution by making some assumptions.
Taking a sample HTML code
<div id "checkbox_container>
<input type="checkbox " id="checkbox1 ">
<input type="checkbox " id="checkbox1 ">
<input type="checkbox " id="checkbox1 ">
<input type="checkbox " id="checkbox1 ">
.
.
.
<input type="checkbox " id="checkbox1 ">
</div>
Now write the locators that will give the count of the available checkbox elements and a locator that will select the specific checkbox.
public class SamplePageObjects {
//This locator will select all available checkboxes
public static By ALL_CHECK_BOX = By.xpath("//div[#id='checkbox_container']//input");
//This locator will select the particular element for the given index
public static getMeExpectedCheckBox(int index, int maxCount) {
if (index < 0 || index > maxCount) {
throw new IlleagalArgumentException(index+" is not a valid index");
}
return By.xpath("//div[#id='checkbox_container']//input[" + index + "];
}
}
Now, write your page class
public class SamplePage{
//Gives the count of available elements
public int getCountOfAvailableCheckBox(WebDriver driver){
return driver.findElements(SamplePageObjects.ALL_CHECK_BOX).size();
}
//Selects the specific element
public void selectWebElement(WebDriver driver,int index){
driver.findElement(SamplePageObjects.getMeExpectedCheckBox(index).click();
}
//Selects all available element one by one
public void click(){
int totalCount = getCountOfAvailableCheckBox();
for(int i=0; i< totalCount-1; i++){
try{
selectWebElement(i,totalCount);
} catch(StaleElementReferenceException e){
selectWebElement(i,totalCount);
}
}
}
So first get the list of all available checkboxes. After getting the count, just pass the index value to the locator and perform the action.
Hope it will help you.

how to print all sugession came in auto suggetions?

i Just started with selenium so i want to know how to handle below thing ...
when type some thing on google it gives us suggestions i want print them on console .
i have tried this
driver.findElement(By.id("lst-ib")).sendKeys("cognizant i");
List<WebElement> lst=driver.findElements(By.tagName("li"));
int ii = lst.size();
System.out.println(lst.get(3).getText());
System.out.println(lst);
for(int i=0;i<lst.size();i++){
System.out.println("hi" + lst.get(i).getText());
}
But not printing any thing on console. plz Guide me where i went wrong .
Following code waits for the suggestions to appear after you have entered some value in google search bar and then prints them one by one in console:
driver.findElement(By.name("q")).sendKeys("Cognizant i");
List <WebElement> allItems = driver.findElements(By.xpath("//*[#id='sbtc']/div[2]/div[2]/div[1]/div/ul//li/div[contains(#id,'sbse')]"));
while(allItems.size() <1)
{}
System.out.println("Total no of elements :" + allItems.size() );
for(int i=0; i< allItems.size() ;i++){
value1= allItems.get(i).getText();
System.out.println(value1);
}
Your code actually runs, and does output the suggestions - however you are grabbing all 'li' elements on the page which results in a large number of empty or irrelevant elements being present in your List lst.
You can see this if you open the Console in your browser on the google home page and search for li tags which is effectively what your code is doing.
Make your code more specific to the list items you want to collect - which reside inside a tag with the role "listbox".
The following will output the suggestions to the console:
driver.findElement(By.id("lst-ib")).sendKeys("cognizant i");
WebElement suggestionList = driver.findElement(By.cssSelector("[role ='listbox']"));
List<WebElement> suggestions = suggestionList.findElements(By.tagName("li"));
for(WebElement suggestion : suggestions){
System.out.println(suggestion.getText());
}

Selecting multiple elements with Selenium

I'm creating List of all available elements with below Xpath.
IList<IWebElement> test= Driver.FindElements(By.XPath("//*[#id='middle-container']//div[#class='middle-section match-list']//div[contains(#class,'title')]//span[contains(text(),'" + Event.Trim() + "')]//..//..//..//..//div[contains(#class,'drop-down-content')]//table[contains(#class,'hidden-xs')]//tr//td[contains(#class,'bettype')]//a[#class='bet']`//span"));
So all the elements available in that Xpath need to be clicked. Running foreach loop:
foreach (var item in availableSports)
{
item.Click();
}
}
My problem is let's say if test contains more than, I think, 10 elements, it is stopping the click event after around 8 to 9 clicks, and raising this error:
StaleElementReferenceException
So just wondering how can I write the method which will continue click until last available element without fail.
You are getting StaleElementReferenceException because something has changed in the DOM after you performed the FindElements operation.
You have mentioned that you are clicking on the items in the list. Does this click action reload the page or navigate to a different page. In both cases the DOM has changed. Hence the Exception.
You can handle this(hopefully) with the following logic. I am a JAVA guy and the following code is in JAVA. But I think you get the idea.
IList<IWebElement> test= Driver.FindElements(By.XPath("//*[#id='middle-container']//div[#class='middle-section match-list']//div[contains(#class,'title')]//span[contains(text(),'" + Event.Trim() + "')]//..//..//..//..//div[contains(#class,'drop-down-content')]//table[contains(#class,'hidden-xs')]//tr//td[contains(#class,'bettype')]//a[#class='bet']`//span"));
// Instead of using the for each loop, get the size of the list and iterate through it
for (int i=0; i<test.length; i++) {
try {
test.get(i).click();
} catch (StaleElementReferenceException e) {
// If the exception occurs, find the elements again and click on it
test = test= Driver.FindElements(By.XPath("//*[#id='middle-container']//div[#class='middle-section match-list']//div[contains(#class,'title')]//span[contains(text(),'" + Event.Trim() + "')]//..//..//..//..//div[contains(#class,'drop-down-content')]//table[contains(#class,'hidden-xs')]//tr//td[contains(#class,'bettype')]//a[#class='bet']`//span"));
test.get(i).click();
}
}
Hope this helps you.