I'm using WebDriver and I have a WebElement that has a few root tags, each of these div tags has multiple div tags within them. Is there a way to get just the root tags?
Eg.
WebElement grabbed from the "someid" field below contains the following data within. I'd like to grab the root div tags from this element (example below has three) By default it grabs the root, and any div tags within, is there a way to just grab those three div tags? There is not specific names or id to grab them, but if I can get the root div tags, I can loop through them easier to locate the data I need in each. Thanks for any direction, or let me know if I need to get more information. Thanks
<div id="someid">
<div><more html that has div tags></div>
<div><more html that has div tags></div>
<div><more html that has div tags></div>
</div>
WebElement weMain = driver.findElement(By.id("someid"));
// Looking for a way to just grab the root divs to my WebElement
List<WebElement> weSomeElements = weMain.findElements(By.tagName("div"));
Thanks for any direction
Try:
driver.findElements(By.xPath("//div[#id='someid']/div")
I think that should return the 3 divs.
try this
List<WebElement> weSomeElements =
driver.findElements(By.CssSelector("div[id='someid'] div"));
Then you can do something like this:
WebElement element = weSomeElement.select(n).findElements(by.tagName("div"));
var elementText = element.Text();
Related
how to add the second css selector or xpath where the same element appears more than once.
WebElement element = driver.findElement(By.cssSelector("span.mat-content"));
I need to add the same css selector again but for the 2nd element
how do it do that.
This is for the first one which I have added as seen above:
HTML:
<span class="mat-content ng-tns-c143-2587"> = first one
HTML which I need to add -
<span class="mat-content ng-tns-c143-2589"> = How do I add the css selector using this html tag.
WebElement element2 = driver.findElement(By.cssSelector("span.mat-content")); = In this place how do I add it for the second element
If this span.mat-content represent multiple web element in HTMLDOM.
You can use findElements to grab them all.
List<WebElement> elements = driver.findElements(By.cssSelector("span.mat-content"));
Now elements is a list in Java-Selenium bindings.
You could do, elements.get(1) and this shall represent the second web element.
or You can iterate the entire list like this:
for (WebElement element : elements){
element.getText(); //Note that each `element` is a web web element.
}
If you do not wish to have the above way. You can try xpath indexing.
(//span[contains(#class,'span.mat-content')])[1]
should represent the first element.
and
(//span[contains(#class,'span.mat-content')])[2]
should represent the second element and so on..
[3], [4], .... [n]
just replace css with xpath. xpath indexing is not preferred choice.
List<WebElement> elements= driver.findElements(By.cssSelector("span.mat-
content"));
WebElement element2 = elements.get(1);
Should work
I have below jQuery selector. I check it with data from the browser developer console.
jQuery("iframe#msg_body").contents().find("html body div span").text()
And I need to use this for cssSelector in selenium.
for example as below format
By expectedOutput = By.cssSelector(The_expression_I_need);
Can any one tell me how to do that ?
As Rory McCrossan mentioned, You can't just access the element using CSS selector since it is inside an iframe.
You have to switch to the iframe and search for the element.
new WebDriverWait(driver,30).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("msg_body"));
By expectedOutput = By.cssSelector("html body div span");
Then you can get the element using the locator.
The locator will return all the span tag inside a div tag inside the body tag. So I'm guessing it will most probably get more than one element.
I am trying to select these elements in webdriver, after I click a button which opens a drop down menu. I can click the button fine and it drops down with.
WebElement providers = driver.findElement(By.id("providers"));
providers.click();
HTML
<input id="providers" class="providersOff" type="button">
<div id="providers-list" class="">
<ul>
<li ng-click="searchProvider(0)">
<div class="imageContainer">
<span>Google</span> <--TRYING TO SELECT THIS
I'm trying to select the Google element.
I have tried both of these and it doesn't work:
driver.findElement(By.cssSelector(".imageContainer[Google]"));
driver.findElement(By.cssSelector(".providers-list > li[ng-click*= searchProvider(0)]"));
It runs these perfectly fine:
// Assign search-bar & send keys
WebElement searchbar = driver.findElement(By.id("txtSearch"));
searchbar.sendKeys("Pizza");
// Assign provider drop-down & click
WebElement providers = driver.findElement(By.id("providers"));
providers.click();
It should be:
div.imageContainer > span
which basically means:
give me the span element which is a direct child of a div element with class="imageContainer".
To get the actual text, use .text:
WebElement span = driver.findElement(By.cssSelector("div.imageContainer > span"));
System.out.println(span.text);
If you want to match the span by text, you can approach it with xpath:
WebElement google = driver.findElement(By.xpath("//div[#class='imageContainer']/span[. = 'Google']"));
google.click();
Or, you can also rely on ng-click attribute of the li element:
WebElement span = driver.findElement(By.cssSelector("li[ng-click$='(0)'] > div.imageContainer > span"));
where $= is an ends-with selector.
It may be good for you to familiarize yourself with basic CSS selectors. Try playing this game, I've learned a lot from it: https://flukeout.github.io/
Now back to your original question. Based on the part of the code you provided the shortest possible selector is simply span
driver.findElement(By.cssSelector("span")); - it says give me a html tag
But I assume you have a lot of spans on your page so this selector may not be unique.
driver.findElement(By.cssSelector("#providers-list span")); - search for an element with id=providers-list and within this element search for a tag span. This probably will be enough, but in case you have many spans within this particular div you may do:
driver.findElement(By.cssSelector("#providers-list .imageContainer span")); - search for element with id=providers-list, within this element search for a descendant with class attribute containing imageContainer and then for a tag span.
You may also provide the full path to the element:
driver.findElement(By.cssSelector("#providers-list > ul > li > .imageContainer > span")); - '>' says go to direct child while space means go to a descendant (no matter how deep).
EDIT
If ng-click is the only unique attribute then the code will look like this
driver.findElement(By.cssSelector("#providers-list li[ng-click='searchProvider(0)'] > .imageProvider > span"));
EDIT2
You probably need to wait for element to become visible after you expand dropdown (after you do providers.click())
WebDriverWait wait = new WebDriverWait(driver, 10);
String selector = "#providers-list li[ng-click='searchProvider(0)'] > .imageProvider > span";
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(selector)));
I am using selenium to test my web application and I can successfully find tags using By.xpath. However now and then I need to find child nodes within that node.
Example:
<div id="a">
<div>
<span />
<input />
</div>
</div>
I can do:
WebElement divA = driver.findElement( By.xpath( "//div[#id='a']" ) )
But now I need to find the input, so I could do:
driver.findElement( By.xpath( "//div[#id='a']//input" ) )
However, at that point in code I only have divA, not its xpath anymore... I would like to do something like this:
WebElement input = driver.findElement( divA, By.xpath( "//input" ) );
But such a function does not exist.
Can I do this anyhow?
BTW: Sometimes I need to find a <div> that has a certain decendent node. How can I ask in xpath for "the <div> that contains a <span> with the text 'hello world'"?
According to JavaDocs, you can do this:
WebElement input = divA.findElement(By.xpath(".//input"));
How can I ask in xpath for "the div-tag that contains a span with the
text 'hello world'"?
WebElement elem = driver.findElement(By.xpath("//div[span[text()='hello world']]"));
The XPath spec is a suprisingly good read on this.
If you have to wait there is a method presenceOfNestedElementLocatedBy that takes the "parent" element and a locator, e.g. a By.xpath:
WebElement subNode = new WebDriverWait(driver,10).until(
ExpectedConditions.presenceOfNestedElementLocatedBy(
divA, By.xpath(".//div/span")
)
);
For Finding All the ChildNodes you can use the below Snippet
List<WebElement> childs = MyCurrentWebElement.findElements(By.xpath("./child::*"));
for (WebElement e : childs)
{
System.out.println(e.getTagName());
}
Note that this will give all the Child Nodes at same level ->
Like if you have structure like this :
<Html>
<body>
<div> ---suppose this is current WebElement
<a>
<a>
<img>
<a>
<img>
<a>
It will give me tag names of 3 anchor tags here only . If you want all the child Elements recursively , you can replace the above code with
MyCurrentWebElement.findElements(By.xpath(".//*"));
Hope That Helps !!
I also found myself in a similar position a couple of weeks ago. You can also do this by creating a custom ElementLocatorFactory (or simply passing in divA into the DefaultElementLocatorFactory) to see if it's a child of the first div - you would then call the appropriate PageFactory initElements method.
In this case if you did the following:
PageFactory.initElements(new DefaultElementLocatorFactory(divA), pageObjectInstance));
// The Page Object instance would then need a WebElement
// annotated with something like the xpath above or #FindBy(tagName = "input")
The toString() method of Selenium's By-Class produces something like
"By.xpath: //XpathFoo"
So you could take a substring starting at the colon with something like this:
String selector = divA.toString().substring(s.indexOf(":") + 2);
With this, you could find your element inside your other element with this:
WebElement input = driver.findElement( By.xpath( selector + "//input" ) );
Advantage: You have to search only once on the actual SUT, so it could give you a bonus in performance.
Disadvantage: Ugly... if you want to search for the parent element with css selectory and use xpath for it's childs, you have to check for types before you concatenate...
In this case, Slanec's solution (using findElement on a WebElement) is much better.
I'm using Java and Jsoup to parse HTML pages and I want to get all the divs that not contains another divs inside it to print the text it contains.
But for example, if a div contains a table, and the table costains a div, I don't want it. I want only the div at the most bottom level, with none another div inside it (another tags are ok).
How I do this?
Primarilly, I want to know if there is some syntax that can I use with the select() method.
Document doc; //comes as parameter
Elements divs = doc.getElementsByTag("div");
for(Element div: divs){
if(div.getElementsByTag("div").size() == 1){
//is a div with no divs inside it
}
}