Is it possible to find out if an element comes before the second element in Capybara? - webdriver

I was doing tests with Caplybara, Cucumber and WebDriver, so I looked at two elements on top of each other, so I thought.
In a simpler way, is it possible to know if an element comes before the second?
In a more complex way, is it possible to know if one element has a position on top of the other?
The structure is simple
<div id="father-parent">
<p id="children-0">Firt element</p>
<p id="children-1">Second element</p>
</div>

If what you're trying to verify is that children-0 comes right before children-1 you can use the CSS adjacent sibling selector
expect(page).to have_css('#children-0 + #children-1')
If you just want to verify that children-0 is a prior sibling of children-1 (not necessarily adjacent) you can use the general sibling selector
expect(page).to have_css('#children-0 ~ #children-1')

Depending on how the test is written, you could also use the have_sibling matcher:
first_child = find('#children-0')
expect(first_child).to have_sibling('#children-1')
To test for element positions, some drivers support the :below filter:
expect(first_child).to have_sibling('#children-1', below: first_child)
below is one of Capybara's global filters, you could also use above, left_of, and right_of.

If you can do with simple content matching, I have just added a new matcher as spec/support/matchers/appear_before_matcher.rb:
RSpec::Matchers.define :appear_before do |later_content|
match do |earlier_content|
page.body.index(earlier_content) < page.body.index(later_content)
end
end
and then used it like this:
expect('First element').to appear_before('Second element')

Related

How can I select an element by an attribute set on its parent using CSS 2.0 selectors?

I have a HTML like this in my QWebView
<div class='a' id='root'>
<div id='x'>...</div>
<p> ...
<p>
...
<div id='x2'>...</div>
<div>
<a href='go/xxxx'>go</a>
</div>
</div>
How do I select the a? I tried this selectores:
div[id='root'].a
div[id='root'] + a
but it didn't worked. Code:
QWebFrame* frame = webView->page()->mainFrame();
QWebElement button = frame->documentElement().findFirst("div[id='root'].a");
assert(!button.isNull()); // gets executed
Your selector is selecting the div with id='root' and class='a'. If you want to select the a tag inside of that div, you need to make your selector:
div[id='root'].a a
The additional 'a' at the end of the selector tells jquery to select the a inside of the div.
You can switch to using XPath 2.0 in Qt to have more expressive freedom, but then you need to process your HTML as XML.
To resolve, add a descendant selector1 for a. I.e., change this div[id='root'].a into this:
div[id=root].a a
As an alternative, if there's a bug in Qt, try:
div[id=root][class=a] a
Or (which is potentially a bit wider):
div[id~=root][class~=a] a
These last two are just alternatives in case for some reason the original fix to your code (adding the a descendant selector) didn't work.
The code snippets above doesn't use quoted strings, this is optional.
1 adding a was seen in stevenc4's answer), after my original (wrong) solution. Kudos to him :)

Chrome - nth-child rule is too slow

I've been testing DOM selecting performance using jQuery.
I get some questions after comparing $("ul li:nth-child(999)") to $("ul li").eq(999)
$("ul li:nth-child(999)");
$("ul li").eq(999);
Please click on the following link to see my detailed test results :
JSPerf Test Result
Especially Chrome shows poor performance for operating nth-child pseudo classes.
I want to know why such a result is caused.
Can I get any algorithm, mechanism or references about that?
I would be very grateful if someone helps me.
Thanks.
Your testing result is interesting. I also hope to know the correct answer to differences in the algorithm at the base.
Not talking about the algorithms of the two functions, I do not know if that helps.
But I think just functionally...
First, the two functions are slightly different.
$().eq is the jQuery method. It's own jQuery method.
A little differently, ':nth-child' is CSS selector. It's passed to jQuery Engine optimized for nearly the performance as the CSS engine.
And these two things are functionally different.
According to CSS3 :nth-child() Selector,
The :nth-child(n) selector matches every element that is the nth child, regardless of type, of its parent.
and
jQuery eq() Method,
The eq() method returns an element with a specific index number of the selected elements.
For example,
<body>
<div> div 1 </div>
<div> div 2 </div>
<div> div 3 </div>
<div>
div 4
<div> div 5</div>
<div> div 6</div>
</div>
</body>
If you use $('body div').eq(2), it return the jQuery object for <div> div 2 </div> depending on the index 2.
Else if you use $('body div:nth-child(2)'), it return the set of jQuery objects for <div> div 2 </div> 'and <div> div 6 </div>'.
Because it the 'nth-child(n)' css selector return the nth child of 'its parent'.
But I also don't what the underlying cause that makes eq() method is slower than another.
I'm sorry if it did not help.
I couldn't find any answer about this question anywhere, think that it can be an unknown bug.
So I sent an email to Chromium Team, this issue has been ticketed on Chromium forum officially.
You can see the ticket for nth-child issue on the following link :
https://code.google.com/p/chromium/issues/detail?id=364081&q=nth&colspec=ID%20Pri%20M%20Iteration%20ReleaseBlock%20Cr%20Status%20Owner%20Summary%20OS%20Modified
Thanks.

Hiding previous element by checked selector

I would like to use css3 features to hiding previous element.
Basically,
I want to use a checkbox to hide previous sibling element without using javascript.
I have prepared a sample for entry point.
http://cssdesk.com/5zccy
Thanks
Edit:
I have changed sample.
My usecase: I want to have collapsible sections at my site. Two area separated by a simple checkbox and checking it will beautifully hide previous sibling.
I believe that using pure css will let me to reduce using javascript for this task.
You can not hide the previous elements - just the following ones with the general sibling selector
DEMO
Then you might be able to position the elements, so on the actual page the checkbox will appear after the .parent div.
There's no css selector to select the previous tag of a matched element. The closest you can get using only css it's doing that for the next element:
<input class="hider" type="checkbox" /> child
<div class="parent">
Parent
</div>​
.hider:checked + * {
display:none;
}​

Why does this selector return two elements on this page in Chrome?

Pretty straightforward. I think I have what should be a unique selector, but in Chrome it returns two <p> elements. The page I'm looking at is:
http://docs.webfaction.com/user-guide/control_panel.html
and the selector is:
document.querySelectorAll('body:nth-child(2) div#container:nth-child(1) div#content.clear.hasCorners:nth-child(2) div.document:nth-child(3) div.documentwrapper:nth-child(1) div.bodywrapper:nth-child(1) div.body:nth-child(1) div#the-control-panel.section:nth-child(1) p:nth-child(3)')
I must be misunderstanding something about the nth-child selector because I would think this is guaranteed to be unique.
EDIT: Ah, I should definitely be using some child selectors (>) here to avoid going further down the DOM tree. Someone can feel free to answer it with that and I'll accept.
As noted above, the issue is that without the child selector (>) there's no guarantee of uniqueness because there may be additional matches further down the DOM tree. For instance consider this markup:
<body>
<div class="foo" id="bar">
<div class="foo" id="baz"></div>
</div>
</body>
if you tried:
$('body:nth-child(1) .foo:nth-child(1)')
that would return two elements.

Adding :last-child or :last-of-type to nav menu

Normally CSS is my thing, but I'm somehow dumbfounded why this isn't working for me. I'm building a site through Cargo for CMS purposes and you can see it here: http://cargocollective.com/mikeballard
In my menu, I have five main categories, and clicking on them (images, for example) reveals the list of work under that category.
<div id="menu_2444167" class="link_link">
<a id="p2444167" name="mikeballard" target="" href="http://cargocollective.com/mikeballard/filter/images">Images</a>
</div>
<div id="menu_2444188" class="project_link">
<a name="mikeballard" rel="history" href="mikeballard/#2444188/Ultra-Nomadic-Def-Smith-Cycle-2011">Ultra Nomadic Def Smith Cycle, 2011</a>
</div>
<!-- more divs here -->
<div id="menu_2444201" class="project_link">
<a name="mikeballard" rel="history" href="mikeballard/#2444201/Archive">Archive</a>
</div>
Basically, I'm trying to select the last div in this set, and add a margin-bottom:15px to that div. I've tried using:
.project_link:last-child or .project_link:last-of-type but it doesn't seem to be working.
The HTML, which can't be altered too much to rely on Cargo, isn't great as if they had used list items, instead of divs with anchor tags I'm assuming this would be a lot easier.
The :last-of-type and :last-child selectors are not supported before IE9.
Class names, etc are not looked at when it comes to the :last-child and :last-of-type selectors. The .project_link:last-child selector will only trigger if the specific element is the last child in the parent element and has the class "project_link", and the .project_link:last-of-type selector will only trigger if the specific element is the last element of that type and has the class "project_link".
Both should trigger in a supporting browser, since it is implied as *.project_link:last-of-type and will check for every type of element inside that parent (which appears to only be divisions anyways). The last division shown here has the class "project_link" which would match this rule. The only reason these wouldn't trigger is if you had extra elements (or divisions) below what you're showing us, or you're using a browser which doesn't support it.

Resources