Find the elements bellow the ul element, as per the following sample HTML:
<ul _ngcontent-nkg-43="" ngmodelgroup="option">
<span _ngcontent-nkg-17="" style="cursor: pointer;">Option 1</span>
<span _ngcontent-nkg-17="" style="cursor: pointer;">Option 2</span>
<span _ngcontent-nkg-17="" style="cursor: pointer;">Option 3</span>
</ul>
var yourParentElement = driver.FindElement(By.XPath(".//ul[ngmodelgroup='option']"));
var children = yourParentElement.FindElements(By.XPath(".//*"))
This latter call will return all children elements of yourParentElement
If you're trying to fetch the span elements you could do:
driver.FindElement(By.Xpath(".//ul[ngmodelgroup='option']")).FindElements(By.TagName("span"));
Related
Dropdown - On clicking on div,Ul style attribute is changed to display:block from display:none but this happens in fraction of second unable to take list of li elements from ul
<div id="main_filter" class="drop-select-wrap">
<span data-title="Active Clinic Patients" data-value="101" class="optionValue ov-gradient">Active Clinic Patients ▼</span>
<ul class="dropSelect" id="parentFilter" style="display: none; width: 175px;">
<li id="filterTypes" data-value="102" onclick="tier1FilterChanged(this);" data-rel="My Active Patients">
<span data-title="My Active Patients">My Active Patients</span>
</li>
<li id="filterTypes" data-value="101" onclick="tier1FilterChanged(this);" data-rel="Active Clinic Patients">
<span data-title="Active Clinic Patients">Active Clinic Patients</span>
</li>
<li id="filterTypes" data-value="126" onclick="tier1FilterChanged(this);" data-rel="Inactive Patients">
<span data-title="Inactive Patients">Inactive Patients</span>
</li>
</ul>
</div>
Initial :
On page load, i am having dropdown of above code where - UL tag is having attribute style="display: none; , so all li elements are hidden . Only span value i.e. default selected value is displayed.
In this case, for dropdown on page load - Active Clinic Patients is displayed.
On Click of dropdown :
Once i click on dropdown, UL attribute is changed to style="display: block;"
and li elements are visible.
Problem Faced :
On clicking on span , dropdown values are displayed for fraction of second - so unable to handle Ul style attribute changes and selecting value from li.
I am struggling for this, it would be great if anyone can provide some solution.
Thanks in advance.
Tried Code Snippet :
private IWebElement parentFilter => driver.FindElement(By.XPath("//div[#id='main_filter'][1]/span"));
public void SelectFilter(string filterOption)
{
IWebElement elementToShow = driver.FindElement(By.XPath("//ul[#class='dropSelect']"));
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].style='display: block;'", elementToShow);
IWebElement option = elementToShow.FindElement(By.XPath("//li/span[contains(text(),'" + filterOption + "')]"));
Actions action = new Actions(driver);
action.ClickAndHold(parentFilter).MoveToElement(option).Click().Build().Perform();
}
It looks like your code is attempting to directly modify the style using ExecuteScript. Instead, the code should emulate what a user does by executing a Click() method on elementToShow. This should open the list, allowing you to find your target option.
I want to click on div[#id='main_filter'] and then select a li element from the dropdown.
But the problem i am facing is, parent tag has attribute
style = display: none, so li items are hidden. so I am unable to get elements from the li tag.
I am creating a generic method to selectfromdropdown.
<div id="main_filter" class="drop-select-wrap">
<span data-title="Active Clinic Patients" data-value="101" class="optionValue ov-gradient">Active Clinic Patients ▼</span>
<ul class="dropSelect" id="parentFilter" style="display: none; width: 175px;">
<li id="filterTypes" data-value="102" onclick="tier1FilterChanged(this);" data-rel="My Active Patients">
<span data-title="My Active Patients">My Active Patients</span>
</li>
<li id="filterTypes" data-value="101" onclick="tier1FilterChanged(this);" data-rel="Active Clinic Patients">
span data-title="Active Clinic Patients">Active Clinic Patients</span>
</li>
<li id="filterTypes" data-value="126" onclick="tier1FilterChanged(this);" data-rel="Inactive Patients">
<span data-title="Inactive Patients">Inactive Patients</span>
</li>
</ul>
</div>
my solution :
private IWebElement parentFilter => driver.FindElement(By.XPath("//div[#id='main_filter'][1]/span"));
public void SelectFilter(string filterOption)
{
ElementHandler.Click(parentFilter);
IWebElement element = driver.FindElement(By.Id("parentFilter"));
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].removeAttribute('style')", element);
IWebElement filterName = element.FindElement(By.XPath("//li/span[contains(text(),'" + filterOption + "')]"));
//driver.FindElement(By.XPath("/ul[#id='parentFilter']/li/span[contains(text(),'"+ filterOption + "')]"));
ElementHandler.SelectFromDropdown(parentFilter, filterName);
}
public static void SelectFromDropdown(IWebElement element1,IWebElement element2)
{
Actions action = new Actions(driver);
action.ClickAndHold(element1).Build().Perform();
action.ClickAndHold(element1).MoveToElement(element2).Click().Build().Perform();
}
You could try executing some Javascript on the hidden ul element to change its style attribute and display it. I see you're already trying to remove the style attribute, but let me show you an approach I've taken before that has worked:
IWebElement elementToShow = driver.FindElement(By.XPath("//ul[#class='dropSelect']"));
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].style.display = 'block';", elementToShow);
If that works, then you should be able to click on the li elements.
One of the core features of Selenium is that when a Webdriver tries to interact with an element that is covered or hidden, it will fail to do so. This is a good thing, since it allows us to detect such anomalies in our testing environments instead of exposing such behaviour to our users.
This can be a bit confusing at times, though. For example, a Webdriver that tries to click a <div> that is covered by another transparent <div> will fail to do so since it is covered, although it might look like a clickable element to a human eye.
Having issues accessing the child node of a li element. Looking to print out all text within a list (which acts as a dropdown on the webpage). But all of the text is within an li element under an a> (the third a> tag) tag.
Here is an example of the DOM structure that I am trying to work with. This was given to me and I have no room to change it.
<div class="navbar-collapse collapse" id="navbar-mobile">
<ul class="nav navbar-nav">
<li data-ng-show="!vm.inIdentity" class="dropdown width-250
open">
<a href="" class="dropdown-toggle ng-binding" data-
toggle="dropdown" aria-expanded="true">
<i class="icon-database position-left"></i> Select a
repository <span class="caret"></span>
</a>
<ul class="dropdown-menu width-250 overflow-auto"
style="max-height: 500px">
<li class="dropdown-header">Repositories</li>
<!-- ngRepeat: repository in vm.repositories --><li
data-ng-repeat="repository in vm.repositories"
class="ng-scope" style="">
<a href="" data-ng-
click="vm.selectRepository(repository)"
class="ng-
binding"><i class="icon-database4"></i> **Akzo
Nobel**</a>
</li><!-- end ngRepeat: repository in vm.repositories
--><li data-ng-repeat="repository in
vm.repositories" class="ng-scope">
<a href="" data-ng-
click="vm.selectRepository(repository)"
class="ng-binding"><i class="icon-database4"></i>
AltAir Paramount</a>
</li><!-- end ngRepeat: repository in vm.repositories
-->
IWebElement dropdown = driver.FindElement(By.XPath("//*
[#id='navbar-mobile']/ul[1]/li[1]/ul/li[2]/a"));
Console.WriteLine(dropdown.Text);
IList <IWebElement> ele =
dropdown.FindElements(By.XPath("//li"));
foreach (var li in ele)
{
Debug.WriteLine(li.Text);
}//end foreach loop
I am expecting the values to print out. Values such as "Akzo Nobel", "AltAir Paramount" etc. Which are located under the li elements and a> tags. But for some reason I am only able to see the text of "Select Repository" in the debugger window.
suppose I have the following list:
<div id='page_competition_1_block_competition_left_tree_2'>
<div>
<ul>
<li>
<a href="#" />
<ul>
<li>
<a href="#">
</li>
</ul>
</li>
<li>
<a href="#" />
...
how can I get the first a tag for each li?
I tried using:
HtmlNodeCollection compsLi = doc.DocumentNode
.SelectNodes("div[#id='page_match_1_block_competition_left_tree_2']//div//ul/li[1]");
but this will return null
You need to specify a single / instead of //, so:
HtmlNodeCollection compsLi = doc.DocumentNode.SelectNodes("div[#id='page_match_1_block_competition_left_tree_2']//ul/li/a");
Essentially:
/: search for the current node.
//: search from the root document node.
You should be able to iterate through the compsLi object you retrieve. Additionally, I don't think you need the [1] in your selector. Once you get the <li> item you should be able to do something like this:
foreach(var node in compsLi)
{
var aNode = node.SelectSingleNode("./a");
...
}
You can take a look here for something similar.
I'm working on a page, where page loads dynamically and the data gets added while scrolling. To identify the properties of an item, I identified the parent div, where to identify the address, I have to locate an XPath from the parent to span element.
Below is my DOM structure:
<div class = "parentdiv">
<div class = "search">
<div class="header">
<div class="data"></div>
<div class="address-data">
<div class="address" itemprop="address">
<a itemprop="url" href="/search/Los-Angeles-CA-90025">
<span itemprop="streetAddress">
Avenue
</span>
<br>
<span itemprop="Locality">Los Angeles</span>
<span itemprop="Region">CA</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
Here I want to locate the three spans, where I' currently in parent div.
Can someone guide how to locate an element using XPath from particular div?
You can try the following XPaths,
To locate the street address:
//div[#class="parentdiv"]/div/div/a/span[#itemprop="streetAddress"]
To locate the locality/city:
//div[#class="parentdiv"]/div/div/a/span[#itemprop="Locality"]
To locate the state:
//div[#class="parentdiv"]/div/div/a/span[#itemprop="Region"]
To print the list of <span> tagged WebElements with texts like Avenue with respect to div class = "parentdiv" node you can use the following block of code :
IList<IWebElement> myList = Driver.FindElements(By.CssSelector("div.parentdiv > div.address > a[itemprop=url] > span"));
foreach (IWebElement element in myList)
{
string my_add = element.GetAttribute("innerHTML");
Console.WriteLine(my_add);
}
Your DOM might become fairly large, since it adds elements while scrolling, so using CSS selectors might be quicker.
To get all the span tags in the div, use:
div[class='address'] span
To get a specific span by using the itemprop attribute use:
div[class='address'] span[itemprop='streetAddress']
div[class='address'] span[itemprop='Locality']
div[class='address'] span[itemprop='Region']
You can store the elements in a variable like so:
var streetAddress = driver.FindElement(By.CssSelector("div[class='address'] span[itemprop='streetAddress']"));
var locality = driver.FindElement(By.CssSelector("div[class='address'] span[itemprop='Locality']"));
var region = driver.FindElement(By.CssSelector("div[class='address'] span[itemprop='Region']"));