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());
}
Related
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.
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);
}
I need to select all the checkboxes from here one-by-one after every 3 second. I tried couple of xpaths with list,none of them have worked
Tried xpaths:
//div/div[#class='filters-list sdCheckbox ']
Using input and type. But none of them worked. Can you please help me out?
Reference website: https://www.snapdeal.com/products/storage-devices?sort=plrty
->Capacity at the left hand corner
By.xpath("//a[#class='filter-name']") this one listed out all the filters of page.
The xPath "//div[#data-name='Capacity_s']/div[#class='filters-list sdCheckbox ']/input" will fetch you the list of all input elements that you need to check.
There is a container DIV that holds all the filters of a certain type, e.g. Brand, Capacity, etc. The one for Brand is shown below.
<div class="filter-inner " data-name="Brand">
Under that container, all the LABEL tags are what you need to click to check the boxes. So, we can craft a CSS selector using the grouping as a filter to reach only the checkboxes we want.
"div[data-name='Brand'] label"
Since this is something I assume you will reuse, I would write this as a function.
public static void CheckFilters(String filterGroup)
{
WebDriverWait wait = new WebDriverWait(driver, 10);
List<WebElement> filters = driver.findElements(By.cssSelector("div[data-name='" + filterGroup + "'] label"));
// System.out.println(filters.size()); // for debugging
for (int i = 0; i < filters.size(); i++)
{
filters.get(i).click();
// wait for the two overlays to disappear
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("div.searcharea-overlay")));
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("div.filterLoader.hidden")));
// reload the element list after the refresh so you don't get StaleElementExceptions
filters = driver.findElements(By.cssSelector("div[data-name='" + filterGroup + "'] label"));
}
}
and you would call it like
driver.get("https://www.snapdeal.com/products/storage-devices?sort=plrty");
CheckFilters("Brand");
How can I automate to click the links enumerated by an item list.
*A
*B
*C
*D
*E
xpath of "*A" is html/body/ul/li[1]/a
xpath of "*B" is html/body/ul/li[2]/a
...
Is it possible to click all the items using findElements(By.xpath)?
You can use here findElement method here you can use option to find element it will be more helpful for you. If you want example code than i can provide you feel free to ask me
First answer is yes but! in case that after click you will be not redirected to other page.
you need to create collection that will contain all the li.
IList<IWebElement> liCollection = driver.FindElement(By.Xpath("html/body/ul")).FindElements(By.TagName("li");
you need to loop them one by one and invoke the click
for(int i = 0 ; i < liCollection.Count ; i++)
{
liCollection[i].FindElement(By.TagName("a")).Click;
//Thread.Sleep(2000);
liCollection = driver.FindElement(By.Xpath("html/body/ul")).FindElements(By.TagName("li"));
}
!!!STACKOVERFLOW CODE FORMAT PROBLEM!!!
try this may help you
//count the list
List<WebElement> ButtonNamelist=driver.FindElements(By.Xpath("html/body/ul"));
int listcount=ButtonNamelist.size();
for(int i=1;i<=listcount;i++){
driver.findElement(By.xpath("html/body/ul/li["+i+"]/a")).click();
//you need to navigate back here to click on the other elements use waits to load the element and click again
}
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.