When I do this...
<li>
<a href="#">
<img src="#" width="#" height="#" alt="#" />
<ol class="#">
<li>#</li>
<li>#</li>
<li>#</li>
</ol>
</a>
</li>
It renders it in Firefox like this...
<li>
<a href="#">
<img src="#" width="#" height="#" alt="#" />
</a>
<ol class="#">
<li>a href="#">#</a></li>
<li>a href="#">#</a></li>
<li>a href="#">#</a></li>
</ol>
</li>
Seems to render properly in Webkit. Any ideas?
Although HTML5 now permits <a> elements to contain block-level elements (e.g. ol), Firefox's parser traditionally didn't accept that, instead converting them into a sequence of separate <a> inside the block level elements such that they only surrounded inline level elements, which is what you see.
Because Firefox was the only one of the major browser makes that did that, the Mozilla people accepted the HTML5 change, agreed to alter their parser to permit the <a> element to wrap block content. (It's just one of many parser changes for HTML5, although it seems to be possibly the most prominant one)
That change has happened in Firefox 4, so you won't see the problem there, but Firefox 3.x still uses the old behaviour.
Workarounds, include using a <div> with an onclick attribute instead of the <a>, and using JavaScript to wrap the block in an <a> element, but there's no non-JS solution. Given that (a) the page should still be usable as is, and (b) that Firefox 3.x should die out in the not too distant future, one reasonable option is just to accept the quirky Firefox 3 behaviour for now.
The <a> tag has a default style of display:inline; which makes it unsuitable for containing block level elements.
However, you can get around the problem by changing the display property of the <a> element to either block or inline-block, depending on how you want it to display.
(I note that you're using HTML5, so you'll be fine. Be aware that in xhtml, it is simply not allowed to enclose block-level elements inside an <a> tag. This won't affect you in this case, but it's worth knowing in case you ever have to work with code with an xhtml doctype)
Related
This is the current situation: There are several files and folders in a specific location.
Once you hover over a file or a folder, an icon appears then you can click on that icon and a menu will appear. From that menu a user can select any action(rename, move,etc). The problem is that the XPath which is provided by FirePath is broken whenever a new file/folder is created/added in the location.
This is the initial line of code which works fine until the XPath is broken:
webDriver.findElement(By.xpath("//*[#id='main_files_view']/ol/li[6]/ul/li[4]")).click();
Whenever a new item is added in the location, the index with value "6" can change to "7" (new position of the file) and the XPath generated is now slightly different:
webDriver.findElement(By.xpath("//*[#id='main_files_view']/ol/li[7]/ul/li[4]")).click();
How can I change that XPath and makes it robust so that no matter the number of items added/removed, the XPath will not break?
Below is the section of the HTML which is related to the XPath provided by FirePath.
When the XPath is provided, the last class is also highlighted.
<li class="storage_item document file_object even ui-draggable" data-thumb-translation="Translated" data-possible-actions="Rename Delete Share Move View" data-file-size="0 bytes" data-item-type="file" data-display-name="solids_A" data-name="solids_A.raas" data-id="bd48453c752043d98afb237b86ee88a3">
<a class="file_name" href="#/Item/Details?id=bd48453c752043d98afb237b86ee88a3&itemtype=File&tab=Default">
<img class="file_list_icon" width="16" height="16" src="https://api-staging.autodesk.com/content/gateway/2013.1.307595.626/z/Content/images/fileIcons/small/raas.png"/>
<div class="name_container">
<ul class="tools">
<li class="preview_trigger"/>
<li class="comment_balloon none has_tooltip" data-tooltip-contents="#comment_balloon_tooltip" data-comments="0">
<li class="categorize action has_tooltip" data-tooltip="Categories"/>
<li class="document_tools has_tooltip" data-tooltip="Actions"/>
</ul>
</li>
I am using Selenium 2.0, on Eclipse IDE.
If the data-name is unique, then you have
//*[#id='main_files_view']/ol/li[#data-name='solids_A.raas']/ul/li[contains(#class, 'document_tools')]
Css Selector is even better than XPath in this case:
#main_files_view li[data-name='solids_A.raas'] .document_tools
Try this:
By.XPath("//*[#id='main_files_view']/ol/li/ul/li[4]")
You do not have to define every index in an xpath and often if it's just one that change, removing that index will work.
In general you should avoid xpaths in your tests. Css selectors are faster (especially in IE) and more readable. If data-name is unique then this should work:
webDriver.findElement(By.cssSelector("#main_files_view li[data-name='solids_A.raas'] li.document_tools"));
If you really need an xpath the one provided by user1177636 will also do the job.
Consider that you land on a category webpage, whose sole purpose it is to direct you to the appropriate sub-category by informing you what's inside each with an image and a short title.
When it comes to UX considerations — it was suggested that the following arrangement would be the most optimal (text before image):
Each photo and text combination would link to the respective sub-category.
Considering semantic HTML5, since these are titles of sub-categories and not exactly captions, would it be appropriate to use the <figcaption> element? Or is something else?
Using figure captions:
<h2>Our Planet's Animals</h2>
<p>Contrary to popular belief...</p>
<figure>
<a>
<figcaption>Rhinos</figcaption>
<img />
</a>
</figure>
Using headers (or something else) instead:
<h2>Our Planet's Animals</h2>
<p>Contrary to popular belief...</p>
<figure>
<a>
<h3>Rhinos</h3>
<img />
</a>
</figure>
Or, what lese would be correct semantically, and allow ease of styling?
I think the use of the figure element would not be correct here, as this content is probably the main content of the page, but for figure it says:
[…] but that could, without affecting the flow of the document, be moved away from that primary content […]
You'd use figure if you have a diagram in a paper or a photograph in a news article etc.: content that "[…] is typically referenced as a single unit from the main flow of the document".
Instead, I'd use section for each category and enclose all categories in a nav (because it is the main navigation for that sectioning content, which is opened by the heading "Our Planet's Animals").
<h2>Our Planet's Animals</h2>
<p>Contrary to popular belief...</p>
<nav> <!-- nav could be omitted -->
<section>
<a>
<h1>Rhinos</h1> <!-- you could use h3 here instead -->
<img />
</a>
</section>
<section>
…
</section>
<section>
…
</section>
<section>
…
</section>
</nav>
If you don't want to use headings, one could also use a list for the categories (dl or ul). I think the ul fits better than dl here:
<h2>Our Planet's Animals</h2>
<p>Contrary to popular belief...</p>
<nav> <!-- nav could be omitted -->
<ul>
<li><a>Rhinos <img /></a></li>
<li>…</li>
<li>…</li>
<li>…</li>
</ul>
</nav>
It might also be possible to use section in each li element (<li><section>…</section></li>), but I'm not sure how this would affect the document outline.
I have a webpage looks something like this:
<html>
...
<div id="menu">
...
<ul id="listOfItems">
<!--- repeated block start -->
<li id="item" class="itemClass">
...
<span class="spanClass"><span class="title">title</span></span>
...
</li>
<!-- repeated block end-->
<li id="item" class="itemClass">
...
<span class="spanClass"><span class="title">title something</span></span>
...
</li>
<li id="item" class="itemClass">
...
<span class="spanClass"><span class="title">title other thing</span></span>
...
</li>
</ul>
...
</div>
...
</html>
I would like to know what is the xpath of the titles ("title", "title something", "title other thing"). The point is that the order of the <li> elements are not specified. It could be different after every page loading. Is there any method how to discover a certain structure of the page with xpath? I have an notion about how to solve this issue, but before I'm going to write iterations with C# to discover the page I ask you.
Thanks in advance!
First of all, id's should be unique, so your portrayed webpage would not work well when it comes to testing.
I did however test, and got some XPath locators to work for selecting specific titles (although I recommend you fix your webpage instead of actually using this):
//li[#id='item']/span/span
//li[#id='item'][1]/span/span
//li[#id='item'][3]/span/span
If you're after all three titles, you could try Dimitre Novatchev's suggestion:
//span[#class='title']
This should get all titles on the page.
I would like to say one thing however, if you're getting into Selenium, I recommend you download the Selenium IDE extension for Firefox. It's a great tool for beginners. It helps you both to make your Selenium tests by recording your clicks on a website, and it also helps you auto-generate and test your XPath locators and other locators.
And again: I urge you to not make a website with duplicate id elements :-)
Does Selenium support XPath expressions like:
//span[#class='title']
If yes, than use the above XPath expression. It selects every span element in the XML document, whose class attribute has string value of "title".
I recommend to use a tool like the XPath Visualizer to play with different XPath expressions and see the selected nodes highlighted in the source XML document.
I have played for a while writing XPath but am unable to come up with exactly what I want.
I'm trying to write XPath for link(click1 and click2 in code snippet below) based on known text(myidentity in code snippet below). Can someone take a look into and suggest possible solution?
HTML code snippet:
<div class="abc">
<a onclick="mycontroller.goto('xx','yy'); return false;" href="#">
<img src="images/controls/inheritance.gif"/>
</a>
myidentity
<span>
<a onclick="mycontroller.goto('xx','yy'); return false;" href="#">click1</a>
<a onclick="mycontroller.goto('xx','yy'); return false;" href="#">click2</a>
</span>
</div>
You don't need to use XPath here, you could use a CSS locator. These are often faster and more compatible across different browsers.
css=div:contains(myidentity) > span a:nth-child(1) //click1
css=div:contains(myidentity) > span a:nth-child(2) //click2
Note that the > is only required to workaround a bug in the CSS locator library used by Selenium.
Hard to say without seeing the rest of the HTML but the following should work:
//div[text()[contains(., "myidentity")]]/span/a
See Macro's answer - this form should be used.
//div[text()[contains(., "myidentity")]]/span/a[2]
The following only works with one section of text in the containing div.
You'll need to select based on the text containing your identity text.
Xpath for click1
//div[contains(text(),"myidentity")]/span/a[1]
Xpath for click2
//div[contains(text(),"myidentity")]/span/a[2]
After switching from firefox testing to internet explorer testing, some elements couldn't be found by selenium anymore.
i tracked down one locator:
xpath=(//a[#class='someclass'])[2]
While it works as it should under firefox, it could not find this element in ie.
What alternatives do i have now? JS DOM? CSS Selector? How would this locator look like?
Update:
I will provide an example to make my point:
<ul>
<li>
<a class='someClass' href="http://www.google.com">BARF</a>
</li>
<li>
<a class='someClass' href="http://www.google.de">BARF2</a>
</li>
</ul>
<div>
<a class='someClass' href="http://www.google.ch">BARF3</a>
</div>
The following xpath won't work:
//a[#class='someclass'][2]
In my understanding this should be the same as:
//a[#class='someclass' and position()=2]
and i don't have any links that are the second child of any node. All i want is, to address one link from the set of links of class 'someClass'.
Without knowing the rest of your HTML source it's difficult to give you alternatives that are guaranteed to work. Hopefully the following suggestions will help point you in the right direction:
//a[#class='someClass'][2]This is like your example, but the parantheses are not needed.
//a[contains(#class, 'someClass')][2] This will work even if the link has other classes.
css=a.someClass:nth-child(2) This will only work if the link is the 2nd child element of it's parent.
Update
Based on your update, try the following: //body/descendant::a[#class='someClass'][2]