Need your help in locating proper XPath for findElements method in Selenium. Below are the details:
URL - http://www.cleartrip.com/hotels/info/hotel-royal-heritage-30km-before-mount-abu-713374/
From the above URL, I want to extract only the below headers available on right hand side of the page.
1) Basic Amenities
2) Food & Beverages
3) Travel
4) Personal Services
5) Other Amenities
I have tried below XPaths till now:
1) html/body/div[1]/div[4]/div[2]/*
This extracts everything along with amenities listed under the headers.
2) html/body/div[1]/div[4]/div[2]/h3/*
this doesn't work.
3) html/body/div[1]/div[4]/div[2]/h[*]
this doesn't work either.
Any ideas please?
Thanks,
Bharat.
You can try these
//*[#class='col col8']/h3
//*[#class='hotelInfo row']/div[2]/h3
You can iterate using this:
List<WebElement> expected = driver.findElements(By.xpath("//*[#class='col col8']/h3"));
for (int i=0; i<expected.size(); i++){
System.out.println(expected.get(i).getText());
}
Which prints
Basic amenities Food & Beverage Travel Personal Services Other
Amenities Hotel Amenities Basic Room Amenities
Why not store all the elements in a list?
List<WebElement> list = getDriver().findElements(By.xpath(.//*[#id='HotelTabs']/li));
This will make it easy for you to iterate over the headers and do what you need to do.
Below is xpath which can help you to identify the expected webelements.
Xpath: (//*[contains(#class,'amenitiesDescription ')]/div)[3]/following-sibling::div/strong
-> Strategy Used
-- Structure based locator (i.e. xpath)
-- tried to identified an element first and later tried to get the below siblings.
-- Added all the identified webelements to a list.
-- Used a for-each loop to iterate and get the inner text from the element and print on the console.
List<WebElement> eleList = driver.findElements(By.xpath("(//*[contains(#class,'amenitiesDescription ')]/div)[3]/following-sibling::div/strong");
for(WebElement ele: eleList){
System.out.println(ele.getText());
}
Related
First one in list is easy since you can use find Element. I find the element and need to get information from preceding and following divs. For the "n" element in the list, what is the xPath syntax for moving/backwards to other associated divs?
I have tried various x path following syntax such as:
following-sibling::div
/following-sibling::div
./following-sibling::div
And many others. I just have not found the documentation for the correct syntax.
Preceding:
Select all nodes that come before the current node as shown in the below screen.
Following-sibling:
Select the following siblings of the context node. Siblings are at the same level of the current node as shown in the below screen. It will find the element after the current node.
Here you can find the correct syntax with examples.
You can also use drive.findElements(); method in order to find similar elements. It will return you the collection of elements which you can iterate to get the information.
This answer is entirely dependent on what HTML is displayed on the page you are trying to automate.
Without that context, I can only provide a generic answer, but here's how I would loop through a list of elements and grab information from preceding / following div's:
// locate the elements you want to iterate
List<WebElement> elements_to_iterate = driver.findElements(By.xpath(someLocatorHere))
// iterate the elements in a foreach loop
for (WebElement element : elements_to_iterate) {
// get preceding sibling
WebElement preceding_element = element.find_element_by_xpath("./preceding-sibling::div")
print(preceding_element.getText())
// get following sibling
WebElement following_element = element.find_element_by_xpath("./following-sibling::div")
print(following_element.getText())
}
As I mentioned, this is just a generic solution to give you an idea of how this would work. If you want some assistance with the locator strategy, posting your HTML would be helpful.
If you want to find multiple elements then please find below example for your reference. Based on your site you need to implement same kind of logic.
Please refer above screenshot where I am trying to get label of two highlighted button from google
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.google.com"); // URL in the browser
driver.manage().window().maximize(); // Maximize the browser
String expectedTooltip="Search";
List<WebElement> Listelements = driver.findElements(By.xpath("//div[#class='FPdoLc VlcLAe']//input"));
for (WebElement element: Listelements)
{
System.out.println("Element Text::"+element.getAttribute("aria-label"));
}
driver.close();
}
output:
Element Text::Google Search
Element Text::I'm Feeling Lucky
since the first one is easy; each elementList has a current-time and at least one picture
for (i=1; i < elementList.size(); i++) {
WebElement nextInList = elmentList(i);
WebElement getTime = nextInList.findElement(By.xpath("following::div[contains(#class, 'current-time')]"));
.
.
.
WebElement picture = nextInList.findElement(By.xpath("preceding::a[1]"));
.
}
I use Appium with Java to automate tests for mobile application. I'm looking for a way to find element by 2 parameters. I.e. by accessibilityId and by xPath within this element. So really rough example to visualize what I mean
Element el = driver.findElementByAccessibilityId("name").isDisplayed();
Assert.assertTrue(el.findElement(By.xPath("//android.widget.TextView[#text='texty']")));
Is this correct way to do this? Is there a better way? Ideal would be one liner because it is easier to understand
isDisplayed() does not return MobileElement/WebElement it returns a Boolean so a valid way is something like mentioned below
WebElement el = driver.findElementByAccessibilityId("name");
if (e1.isDisplayed()){
WebElement e2 = el.findElement(By.XPath("//android.widget.TextView[#text='texty']"))
}
Assert.assertTrue(e2.isDisplayed());
You can chain any number of findElement e.g.
WebElement innerElement =
driver.findElement(By.AccessbilityID("someID"))
.findElement(By.xpath("someXpath"))
.findElement(By.cssSelector(".aValidCSSClass"));
If you use findElements you have to use it like this as it return List of WebElement or List of MobileElement
WebElement innerElement =
driver.findElements(By.AccessbilityID("someID"))
.get(2) //get 2nd element
.findElements(By.xpath("someXpath"))
.get(1) //get 1st element
.findElement(By.cssSelector(".aValidCSSClass"));
I am using Selenium 3.x with Appium and working on Native iOS App which uses XCUITest as Automation name.
I can access individual element with Accessibility ID and it works fine e.g. driver.findElement(MobileBy.AccessibilityId("Location")).click();
Is there way to get a list of all Accessiblilty IDs (or the values) on a single page / form?
Thanks in advance.
You can try something like below, only you have tochange first line of the code as per android schema, as I'm not aware where all the elements are contained in an app.
Following example identifies the name (or accessibility id attribute in your case) for all the div elements, so you just need to tweak the first line:
List<WebElement> allElems = driver.findElements(By.xpath("//body//div"));
System.out.println("Avaialable Accesible ids :");
int c=0;
for(WebElement ele : allElems) {
c++;
System.out.print("for element " + c +" Accessibility ID is :");
System.out.println(ele.getAttribute("name"));
//or
System.out.println(ele.getAttribute("content-desc"));
}
I have gone through every related question but none of them seems to provide the correct solution. I am writing a program to fetch the friend list from Facebook using selenium code. To do so, I am using for loop to scroll page down and fetch friends name link text from it using tagname keyword. While doing so, I get mutual friends and number of friends each friend have, also in the result.
I noticed that each friend id starts with js_X where X can be any value.
I need to know how I can use any wild card search/Regular expression to search and fetch the results to me.
Below is my code(I know its poor programming, but please help me):
--code for opening facebook and reaching till Friendlist page here---
WebElement box = d.findElement(By.xpath(".//*[#id='pagelet_timeline_app_collection_100000641984658:2356318349:2']/ul")); **//This find the first box containing friend list**
List<WebElement> FinalList = box.findElements(By.tagName("a")); **//All Names are fetched and added in Final List**
jse.executeScript("scroll(0, 2500)"); **//Scrolled below to second box**
Thread.sleep(15000L);
box = d.findElement(By.xpath(".//*[#id='pagelet_timeline_app_collection_100000641984658:2356318349:2']/ul[2]"));**//This finds second box and fetches all the friends name from that box**
List<WebElement> IntermediateList; **//Temporarylist created**
for(int i=3,k=7; i<17||k<20; i++){
if(i<17){
box = d.findElement(By.xpath(".//*[#id='pagelet_timeline_app_collection_100000641984658:2356318349:2']/ul["+i+"]"));
if(box.isDisplayed()){
IntermediateList = box.findElements(By.tagName("a"));
FinalList.addAll(IntermediateList);
jse.executeScript("scroll(0, "+k+"000)"); **//This is for increasing scroll everytime as sometimes box is further down**
Thread.sleep(15000L);
k++;
}else{
break;
}
}
FinalList.addAll(IntermediateList);
Instead of tagname("a") I want to use "id" to find the friend name link text and use Regular expression/wild card in it to search.
For example : IntermediateList = box.findElements(By.id("js_(wild card parameter)"));
any Suggestion would help, Thanks in advance!!
You already used xpath in your example so why don't you use xpath to find the desired links?
XPATH:
IntermediateList = box.findElements(By.xpath("//*[contains(#id,'js_')]"));
(Find any element which ID contains js_)
CSS:
IntermediateList = box.findElements(By.cssSelector("a[id^='js_']"));
(Find a link <a href...> which ID starts with js_)
I am using Selenium to test a website, does this work if I find and element by more than one criteria? for example :
driverChrome.findElements(By.tagName("input").id("id_Start"));
or
driverChrome.findElements(By.tagName("input").id("id_Start").className("blabla"));
No it does not. You cannot concatenate/add selectors like that. This is not valid anyway. However, you can write the selectors such a way that will cover all the scenarios and use that with findElements()
By byXpath = By.xpath("//input[(#id='id_Start') and (#class = 'blabla')]")
List<WebElement> elements = driver.findElements(byXpath);
This should return you a list of elements with input tags having class name blabla and having id id_Start
To combine By statements, use ByChained:
driverChrome.findElements(
new ByChained(
By.tagName("input"),
By.id("id_Start"),
By.className("blabla")
)
)
However if the criteria refer to the same element, see #Saifur's answer.
CSS Selectors would be perfect in this scenario.
Your example would
By.css("input#id_start.blabla")
There are lots of information if you search for CSS selectors. Also, when dealing with classes, CSS is easier than XPath because Xpath treats class as a literal string, where as CSS treats it as a space delimited collection
Based #George's repply, the same code for C# :
//reference
using OpenQA.Selenium.Support.PageObjects;
...
int allElements = _driver.FindElements(new ByChained(
By.CssSelector(".sc-pAyMl.cnszJw"),
By.Id("base-field")
)).Count();