Unable to find element with Xpath - Selenium - c#

I'm trying to click an Element but having some issues.
First, there's a pop up window which I'm switching to, which seems to be written ok.
foreach (string handle in _webdriver.WindowHandles)
{
if (!handle.Equals(parentHandle))
{
_webdriver.SwitchTo().Window(handle);
}
}
Then, I'm trying to click an element inside this pop up by this code:
var myElement = wait.Until(x => x.FindElement(By.XPath("//td[#id='firstname_d']/div[#class='ms-crm-Input-Container']/input[#id='firstname']")));
myElement.SendKeys("foo");
I'm getting an Error:
Unable to find element with Xpath
The HTML is as follow:
<tr valign="top">
<td class="ms-crm-FieldLabel-LeftAlign FormSection_CellPadding ms-crm-Field-Recommended" id="firstname_c">
<td id="firstname_d" style="overflow: hidden;" formxmlcolspan="1">
<div class="ms-crm-Input-Container focus" id="firstname_container">
<input tabindex="1010" class="ms-crm-Input ms-crm-Text" id="firstname" style="ime-mode: active;" type="text" maxlength="50" attrformat="text" attrpriv="7" attrname="firstname" req="1" value=""/>
What am I doing wrong?

You can try with the id
driver.FindElement(By.Id("firstname")).SendKeys("foo");
Or using contains
driver.FindElement(By.XPath("//input[contains(#id, 'firstname')]")).SendKeys("foo");
Edit
You can switch to the <iframe> after the window switch
foreach (string handle in _webdriver.WindowHandles)
{
if (!handle.Equals(parentHandle))
{
_webdriver.SwitchTo().Window(handle);
}
}
_webdriver.SwitchTo().Frame("foo");
_webdriver.FindElement(By.Id("firstname")).SendKeys("foo");

u can write following code and try it
Set st=driver.getWindowHandles();
Iterator it= st.iterator();
String parent=t.next();
String child=it.next();
driver.switchTo().frame(child);
WebElement ele= driver.findElement(By.id("id="firstname_container"));
ele.sendKeys("foo

Related

Xpath to get href that contain id?

I am trying to get all links that contain ids.I have tried for name and price which is working perfectly but not able to get links which is related to that stuff.
For name I am using this code but for getting links it is not working.
//For Name
var name=scorenodesdoc.DocumentNode.SelectNodes("//[contains(#id,'item')]/ul[1]/li1]/span");
//for Links
var Links= doc.DocumentNode.SelectNodes("//a[contains(#id, 'item')]/#href");
xpath for link is://*[#id="item5d86882c07"]/div[1]/div/a
//This is the code I am try to get the href link
<li id="item5d86882c07" _sp="p2045573.m1686.l8" listingid="401689029639" class="sresult lvresult clearfix li" r="1">
<div class="lvpic pic img left" iid="401689029639">
<div class="lvpicinner full-width picW">
<a href="https://www.ebay.com/itm/Microsoft-Xbox-One-X-White-Console-1TB-Forza-Special-Edition-Bundle-White/401689029639?hash=item5d86882c07:g:lgwAAOSwoZJcQY5s" class="img imgWr2">
<img src="https://i.ebayimg.com/thumbs/images/g/lgwAAOSwoZJcQY5s/s-l225.jpg" class="img" alt="Microsoft Xbox One X White Console 1TB & Forza Special Edition Bundle - White'">
</a>
</div>
</div>
</li>
Ok this is how I resolve my issue.First it gets get anchor tag information then by using getattributevalue to get value of href.
var URLnodes = doc.DocumentNode.SelectNodes("//*[contains(#id,'item')]/div[1]/div/a");
var AllURL = URLnodes.Select(node => node.GetAttributeValue("href",null));

How could I get the text is inside of a span which has no ID but a class

I was testing WebBrowser, but there's no method to getElemments by class, but by tag.
I have something like this.
html:
<div class="Justnames">
<span class="name">Georgia</span>
</div>
So i'd like to get the string "Georgia", which is inside of that span.
I tried:
Var example = Nav.Document.GetElementsByTagName("span");
But it return null, and I've no idea why.
Sorry my english and thanks a lot of the help! :)
This may help:
var elementCollection = default(HtmlElementCollection);
elementCollection = webBrowser1.Document.GetElementsByTagName("span");
foreach (var element in elementCollection)
{
if (element.OuterHtml.Contains("name"))
// we reach here, we get <span class="example"
}
Or:
foreach (var element in elementCollection)
{
if (element.GetAttribute("className") == "name")
// we reach here, we get <span class="example"
}
You can do this using jquery :
var test = $(".name").text();
alert(test):
Because you tagged "C#" and ".net" i assume you have a aspx page and try to access it from server code. To access it from server side you have to add the runat="server" tag to the span:
<span class="name" runat="server">Georgia</span>
Otherwise you only can access it from client side (JavaScript)

Show related data using Razor Syntax

I have two classes: Store and Machine.
Right now I have constructed a view where I show the Stores associated to the logged user:
public async Task<IActionResult> Index()
{
var Tiendas = await _context.Stores.Where(t => t.Usuario == User.Identity.Name).Include(t => t.Machines).ToListAsync();
LiqIndexData Liquid = new LiqIndexData()
{
StoreL = Tiendas,
};
return View(Liquid);
}
In this code I also added the Machines asociated to each Store.
The View:
In my View I would like to present, for each Store, all of the Machinesregistered. For this I'm using nav-tabs
Nav Tab based on the number of Stores
<ul class="nav nav-pills">
#foreach (var item in Model.StoreL)
{
<li>#item.StoreName</li>
}
</ul>
<div class="tab-content">
#foreach (var item in Model.StoreL)
{
<div class="tab-pane fade in active" id="#item.StoreID"></div>
}
The Problem:
Info shown in the body of each Nav-tab:
I'm trying to access the information of each Machine associated with each Store. For this I'm trying to use:
#foreach (var item in Model.StoreL)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Machines
.Where(m=>m.StoreID==item.StoreID))
</td>
But I don't know how to access the property. If I try:
#Html.DisplayFor(modelItem => item.Machines
.Where(m=>m.StoreID==item.StoreID).PropertyXYZ)
I get:
'IEnumerable' does not contain a definition for 'PropertyXYZ' and no extension method 'PropertyXYZ' accepting a first argument of type 'IEnumerable' could be found (are you missing a using directive or an assembly reference?)
Any advice?
As the error is trying to tell you, your collection of Machines has no PropertyXYZ.
Depending on what you actually want to do, you can either use First() to get only one Machine (and no others), or use a loop to go through all of them.

how to use selenium wait.until with anchor element in java

i have selenium project written in c# and i want to migrate it to java, but i have a problem that i could not solve by myself.
lets say i have a webElement elem1 and i want to find another element elem2 using elem1 as the anchor.
so in java i can do it like that:
WebElement elem1 = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("div.uiContextualLayer.uiContextualLayerBelowLeft"))) ;
WebElement elem2 = elem1.findElement(By.tagName("li"));
now, my problem starts when i want to do the same but with wait.until() for elem2. the thing is that elem1 is always appear in the DOM, but elem2 will appear in the DOM only after some time (it depends on some code that is not relevant for this issue), so using the above code will throw an exception.
in c# i used lambda expression and it was very simple:
IWebElement elem1 = wait.Until((d) => { return d.FindElement(By.CssSelector("div.uiContextualLayer.uiContextualLayerBelowLeft")); });
IWebElement elem2= wait.Until((d) => { return **elem1**.FindElement(By.TagName("li")); });
in java i cant find a way to do the wait.until AND use elem1 as the anchor for the findElement function.
here is a sample of the html i'm working on:
<div class="uiContextualLayer uiContextualLayerBelowLeft">
<div style="width: 240px;">
<div class="uiTypeaheadView uiContextualTypeaheadView">
<ul id="typeahead_list_u_jsonp_2_2" class="search" role="listbox">
<li id="js_2" class="user" aria-label="whatEver" role="option" aria-selected="false">
…
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
i don't want to get all the elements that has the "li" tagName into a list and than go over each element to find the element i need. i'm pretty sure i'm missing something which is very basic, and would appreciate any suggestion/explanation.
The most Java-style way is to have methods that return locators and write your own inline ExpectedCondition that uses these methods.
public By getElem1Locator() {
return By.cssSelector(....);
}
public By getElem2Locator() {
return By.tagName(....);
}
...
WebElement elem2 = wait.until(new ExpectedCondition<WebElement>() {
public WebElement apply(WebDriver driver) {
try {
return driver.findElement(getElem1Locator()).findElement(getElem2Locator());
} catch (NoSuchElementException e) {
return null;
}
});
...
The reason why we want to use locators and not final WebElement instances is that if DOM changes while we are waiting, the WebElement can become stale.
A quick and dirty solution is to use a single Xpath selector for the second element
WebElement elem2 = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[contains(concat(' ',normalize-space(#class),' '),' uiContextualLayer ') and contains(concat(' ',normalize-space(#class),' '),' uiContextualLayerBelowLeft ')]//li"));
You should also take a look at Page Factory

Retrieving Text between <span>Text</span> in Selenium C#

I am facing problem in retrieving Subject title of a mail from Unread mails using Selenium webdriver-C#.
Here's the HTML code :
<div class="ae4 UI UJ" gh="tl">
<div class="Cp">
<div>
<table id=":8e" class="F cf zt" cellpadding="0">
<colgroup>
<tbody>
<tr id=":8d" class="zA zE">
<td class="PF xY"></td>
<td id=":8c" class="oZ-x3 xY" style="">
<td class="apU xY">
<td class="WA xY">
<td class="yX xY ">
<td id=":87" class="xY " role="link" tabindex="0">
<div class="xS">
<div class="xT">
<div id=":86" class="yi">
<div class="y6">
**<span id=":85">
<b>hi</b>
</span>**
<span class="y2">
</div>
</div>
</div>
</td>
<td class="yf xY "> </td>
<td class="xW xY ">
</tr>
I am able to print 'emailSenderName' in console but unable to print 'text' (subject line i.e. "hi" in this case) as it is between span tags. Here's my code.
//Try to Retrieve mail Senders name and Subject
IWebElement tbl_UM = d1.FindElement(By.ClassName("Cp")).FindElement(By.ClassName("F"));
IList<IWebElement> tr_ListUM = tbl_UM.FindElements(By.ClassName("zE"));
Console.WriteLine("NUMBER OF ROWS IN THIS TABLE = " + tr_ListUM.Count());
foreach (IWebElement trElement in tr_ListUM)
{
IList<IWebElement> td_ListUM = trElement.FindElements(By.TagName("td"));
Console.WriteLine("NUMBER OF COLUMNS=" + td_ListUM.Count());
string emailSenderName = td_ListUM[4].FindElement(By.ClassName("yW")).FindElement(By.ClassName("zF")).GetAttribute("name");
Console.WriteLine(emailSenderName);
string text = td_ListUM[5].FindElement(By.ClassName("y6")).FindElement(By.TagName("span")).FindElement(By.TagName("b")).Text;
Console.WriteLine(text);
}
I had also tried by directly selecting the Text from tag of 5th Column (td), which contains the subject text (in my case), but no results.
I might went wrong somewhere or may be there is some other way of doing it.
Please suggest, Thanks in advance :)
The 'getText' method available in the Java implementation of Selenium Web Driver seems to do a better job than the equivalent 'Text' property available in C#.
I found a way of achieving the same end which, although somewhat convoluted, works well:
public static string GetInnerHtml(this IWebElement element)
{
var remoteWebDriver = (RemoteWebElement)element;
var javaScriptExecutor = (IJavaScriptExecutor) remoteWebDriver.WrappedDriver;
var innerHtml = javaScriptExecutor.ExecuteScript("return arguments[0].innerHTML;", element).ToString();
return innerHtml;
}
It works by passing an IWebElement as a parameter to some JavaScript executing in the Browser, which treats it just like a normal DOM element. You can then access properties on it such as 'innerHTML'.
I've only tested this in Google Chrome but I see no reason why this shouldn't work in other browsers.
Using GetAttribute("textContent") instead of Text() did the trick for me.
Driver.FindElement(By.CssSelector("ul.list span")).GetAttribute("textContent")
Try this
findElement(By.cssSelector("div.y6>span>b")).getText();
I had the same problem. Worked on PhantomJS. The solution is to get the value using GetAttribute("textContent"):
Driver.FindElementsByXPath("SomexPath").GetAttribute("textContent");
Probably too late but could be helpful for someone.
IWebElement spanText= driver.FindElement(By.XPath("//span[contains(text(), 'TEXT TO LOOK FOR')]"));
spanText.Click();
IWebElement spanParent= driver.FindElement(By.XPath("//span[contains(text(), 'TEXT TO LOOK FOR')]/ancestor::li"));
spanParent.FindElement(By.XPath(".//a[contains(text(), 'SIBLING LINK TEXT')]")).Click();
bonus content here to look for siblings of this text
once the span element is found, look for siblings by starting from parent. I am looking for an anchor link here. The dot at the start of XPath means you start looking from the element spanParent
<li>
<span> TEXT TO LOOK FOR </span>
<a>SIBLING LINK TEXT</a>
</li>
This worked for me in Visual Studio 2017 Unit test project. I'm trying to find the search result from a typeahead control.
IWebElement searchBox = this.WebDriver.FindElement(By.Id("searchEntry"));
searchBox.SendKeys(searchPhrase);
System.Threading.Thread.Sleep(3000);
IList<IWebElement> results = this.WebDriver.FindElements(By.CssSelector(".tt-suggestion.tt-selectable"));
if (results.Count > 1)
{
searchResult = results[1].FindElement(By.TagName("span")).GetAttribute("textContent");
}

Categories