I m trying to find the element "import" using Selenium Webdriver in C#. Have tried the following codes but nothing find it.
driver.FindElement(By.XPath("//*[#class='menu_bg']/ul/li[3]")).Click();
driver.FindElement(By.XPath("//*[#id='import']/a")).Click();
driver.FindElement(By.CssSelector("#import>a")).Click();
driver.FindElement(By.XPath("//*[#class='menu_bg']/ul/li[3]/a")).Click();
driver.FindElement(By.CssSelector("ul[#class='menu_bg']>li[value='3']")).Click();
Please help me out. Design page looks like below:
<body>
<div class="header_bg"></div>
<div class="menu_bg">
<ul class="menu">
<li id="retrieve"></li>
<li id="scan" class="test"></li>
<li id="import">
<a target="main" href="import/import.aspx" onclick="clickme(this,'import')">Import</a>
</li>
<li id="admin"></li>
<li id="help"></li>
<li style="float: right;"></li>
</ul>
</div>
</body>
All the time I got the error as below:
unable to find the element
XPath indexers are 1-based, as opposed to most other languages whereby they are 0-based.
This means you are actually targetting the 2nd li element, which has no anchor element.
So:
//*[#class='menu_bg']/ul/li[3]/a
However, this XPath query is not great and is too strict on position - thus although this newly fixed XPath above should work, I'd advise you to think of something else.
By reviewing this link(Thanks to #Arran), the above issue was fixed. 'switching' to the current IFrame directs Selenium to show any requests to that frame instead.
driver.SwitchTo().Frame()
You can do this by chaining Selenium 'FindElement' like so;
driver.FindElement(By.Id("import")).FindElement(By.TagName("a"));
which will give you the child of the element with ID that has a tag of 'a'.
Another way you could do this is by casting your Driver to an IJavascriptExecutor and executing javascript directly in the browser using a JQuery selector. I find this better for more complex Selenium lookups;
((IJavascriptExecutor)Driver).ExecuteScript("$("a[target='main'][href='import/import.aspx'])").click();
Related
I am trying to iterate <li> items of <ul> object in Selenium with C#. I am very new to it and trying to find a easy way write a code for my test project.
here is my sample html code, I would like to access those links below...
<ul class="list-menu">
<li>
<ul>
<li><a class="head" href="/seramik-banyo-urunleri">Seramik Banyo Ürünleri</a></li>
<li>Lavabo</li>
<li>Klozet</li>
my c# code is like below
IList<IWebElement> results = driver.FindElements(By.XPath("//div[#class='list-menu']/li/lu/li"));
but it doesn't get the links. what can I do to fix this?
You have a typo in the XPath expression, replace:
//div[#class='list-menu']/li/lu/li
with:
//div[#class='list-menu']/li/ul/li
Or, you can use a more compact CSS selector instead:
driver.FindElements(By.CssSelector(".list-menu > li > ul > li"));
where > means a direct parent-child relationship.
I have tried many different formats and am unable to locate the link that I need to click using xpath. Please help me learn the magic of xpath...
IWebElement TCE = driver.FindElement(By.XPath("//div[*/text()='Recently Visited']/child::a[#title='Time Clock Entry']"));
TCE.Click();
The code in the webpage for the link is as follows...
<div id="RecentlyVisitedWidget" class="recentlyVisitedWidget">
<h2 id="ctl00_12_12_RecentlyVisitedLabel">Recently Visited</h2>
<ul class="recentlyVisitedLinks">
<li>
<span id="ctl00_12_12_Repeater1_ctl00_link">
<a title="Time Clock Entry" onclick="recentlyVisitedSelect('pages/VIEW/UTMEntry.aspx?USParams=PK=ESS!MenuID=2147!PageRerId=2147!ParentRerId=72','72','2147','2147', false, false, 'Time Clock Entry', true)" href="#"> Time Clock Entry</a>
</span>
</li>
</ul>
</div>
I am able to accomplish this using the following code within a webBrowser Control in a form.
HtmlElement link = (from HtmlElement elem in webBrowser1.Document.GetElementsByTagName("a")
where elem.InnerHtml == "Time Clock Entry"
select elem).ElementAt(0);
link.InvokeMember("Click");
I am unable to find this link when trying to do this in a stand alone browser such as IE or Firefox.
I have tried searching by CssSelector, linkText, Partial linkText, link, XPath, and the Id all returning a message telling me that the element could not be found.
Any ideas on why I would be able to locate this element in a webBrowser Control but not in a browser?
Your XPath should be something like this
//div[#id='RecentlyVisitedWidget']//a[#title='Time Clock Entry']
or
//div[h2[text()='Recently Visited']]//a[#title='Time Clock Entry']
Does it have to be an XPath?
driver.findElement(By.cssSelector("ul.recentlyVisitedLinks a[title='Time Clock Entry']")).click();
I would avoid XPaths, when possible, because they are more error prone and slower.
I'm using C# and Selenium Webdriver and I'm trying to find a div Element in my html code which looks like this:
<div class="x-grid-cell-inner" style="text-align: left;" unselectable="on">
phys_tag_desc
</div>
I cant find a method to search for the value of the div Element with Selenium Webdriver. I already searched this site and checked the Selenium Webdriver Documentation, but couldn't find anything.
Well if text value is unique, then solution is simple. Try the xpath below:
//div[text()='phys_tag_desc']
If the text is not exact match. Try following:
//div[contains(text(),'phys_tag_desc')]
I have two ways.
Way 2 is more complex but more effective.
Way 1;
You can loop in all divs and look for some equals
Example:
foreach(HtmlElement o in webbrowser.Document.GetElementByTagName("div"))
{
HtmlElement yourElement;
if(o.GetAttribute("class")=="x-grid-cell-inner"&&o.GetAttribute("style")=="text-align: left;")
{
yourElement=o;
break;
}
DoSomethingWith(yourElememt);
}
The other way is follow elements path;
You can find the closer element that has a ID
Example:
<div id="element">
<div>content..</div>
<div>
<div class="x-grid-cell-inner" style="text-align: left;" unselectable="on">
phys_tag_desc
</div>
</div>
</div>
The closest element that have id on this example is
<div id="element">
your element's parent is 2. children of id="element" div
You can get it and follow path like this
yourElement = webbrowser.Document.GetElementById("element").Children[1].Children[0];
In other situation you can use the XPATH Boolean operators.
Try the xpath below:
By.XPath("//div[contains(#class,'*x-grid-cell-inner*') and contains(#unselectable, '*on*') and contains(text(),'*phys_tag_desc*')]")
Bye
I will like to know how to disable ChoiceC from this menu if the user is not logon to the
current site using the loging page.
The ChoiceC option will be only available to the user which have connected to the site had been approved.
Can you provide me link or example on how to perform this task with C# ?
I tried to had the class="disabled" but it didn't do anything ie the option is still available.
<div id="menu">
<ul id="menua"; class="ul menua">
<li style="text-align:center;padding:9px;" class="smallwhitetext"></li>
<li>ChoiceA</li>
<li>MenuA
<ul>
<li>option 1</li>
<li>option 2</li>
</ul>
</li>
<li>Choice B</li>
<li class="disabled">
Choice C
</li>
</ul>
</div>
I'd recommend a two-step approach. First, don't have the C# code output the link in the list item if they're not logged in. Second, change the style of the list item by applying a class to that item to indicate to the user that they're not logged in and thus the item is unavailable.
Simply applying a class to that item wont work.
I'm not sure what method you use to build the menu and choices, but normally this could best be done when the page is generated at the server. Just wrap your conditional choice inside an if-statement where you check the approval. Here is some pseudo code for the old style:
<ul>
<li>ChoiceA</li>
<li>MenuA
<ul>
<li>option 1</li>
<li>option 2</li>
</ul>
</li>
<li>ChoiceB</li>
<% if( userIsAuthenticated) { %>
<li>ChoiceC</li>
<% } %>
</ul>
Now I know there are many ways to go about outputting HMTL with MVCs and templates and stuff, but since you didn't mention any specific technique I went for the old style.
Hope it helps!
EDIT
You could also skip the mixing of C# and HTML like one used to do in ASP and still do in PHP and others by simply:
if(userIsAuthenticated) {
Response.Write(#"<li>Choice C</li>");
}
The downside is that when you get a lot of quotes its easier to miss some and a bit harder to read. Plus you wont get code coloring for the HTML.
Note: The # is for verbatim string literals which escape every special character except quotes. You escape these using double quotes instead of the usual \.
<ul id="menua"; class="ul menua">
<li>Option A</li>
<li>Option B</li>
<% if(userIdAuthenticated) { %>
<li>Option C </li>'
<% } %>
</ul>
This is working but still have a small error.
The only error I got is the top ul which is underline in green with the following error message Validation (XHTML5) Text is not allowed between the opening and closing tag for element ul.
I tried to get HTML Source in the following way:
webBrowser1.Document.Body.OuterHtml;
but it does not work. For example, if the original HTML source is :
<html>
<body>
<div>
<ul>
<li>
<h3>
Manufacturer</h3>
</li>
<li><a href="/4566-6501_7-0.html?
filter=1000036_3808675_100021_10194772_">Sony </a>(44)</li>
<li><a href="/4566-6501_7-0.html?
filter=1000036_108496_100021_10194772_">Nikon </a>(19)</li>
<li><a href="/4566-6501_7-0.html?
filter=1000036_3808726_100021_10194772_">Panasonic </a>(37)</li>
<li><a href="/4566-6501_7-0.html?
filter=1000036_3808769_100021_10194772_">Canon </a>(29)</li>
<li><a href="/4566-6501_7-0.html?
filter=1000036_2913388_100021_10194772_">Olympus </a>(21)</li>
<li class="seeAll"><a href="/4566-6501_7-0.html?
sa=1000036&filter=100021_10194772_" class="readMore">See all manufacturers </a></li>
</ul>
</div>
</body>
</html>
but the output of webBrowser1.Document.Body.OuterHtml is:
<body>
<div>
<ul>
<li>
<h3>
Manufacturer</h3>
<li>Sony (44)
<li>Nikon (19)
<li><a href="/4566-6501_7-0.html?filter=1000036_3808726_100021_10194772_">Panasonic
</a>(37)
<li>Canon
(29)
<li>Olympus
(21)
<li class="seeAll"><a class="readMore" href="/4566-6501_7-0.html?sa=1000036&filter=100021_10194772_">
See all manufacturers </a></li>
</ul>
</div>
</body>
as you can see, many </li> are lost.
is there a way to get HTML source in WebBrower control correctly? Note that in my application, I try to use WebBrowser to add coordinate info to every node and output its HTML source with coordinate info which is added as attributes of nodes.
anybody can do me a favor?
Try using DocumentText or DocumentStream properties.
Thank you all. My final solution is: first,using body.outlineHtml to get html source. because body.outlineHtml may miss end-tag for <li> and <td>, so the second step is using tidy to repair the HTML source. after these, we can get the HTML source without error
have you tried WebBrowser1.DocumentText
If you want to grab the entire HTML source of the WebBrowser control then use this - WebBrowser1.Document.GetElementsByTagName("HTML").Item(0).OuterHtml. This of course assumes you have properly formatted HTML and the HTML tag exists. If you want to narrow it down to just the body then obviously change the HTML tag to the BODY tag. This way you grab any and all changes after "DocumentText" has been set. Sorry, I'm a VB guy, convert as needed ;)
Have a look at this.
WebBrowser on MSDN
Alternative you could use Webclient.DownloadString from System.Net (it also has WebClient.DownloadStringAsync...) Here is the description: WebClient on MSDN