How to select from multiple CSS selectors with Capybara - ruby-on-rails

Using RSpec and Capybara to test for the existence of an element within a div with class 'foo'.
<div class="foo">
<p>Text zzz</p>
Looking for element here
</div>
<div class="foo">
<p>Text aaa</p>
Element should not exist within this div.
</div>
There are many divs with class 'foo' on the page, and I can give them different ID's based on foo's ID in the database.
But I don't know foo's ID from within the test. And, I don't want to test the parent of the divs because an element should be present in one div and absent in another.
What is the best way to test for an element in this case?

If I understand the question correctly (and I'm not 100% confident I do), I think this should work:
el1 = find(:xpath, '//div[#class="foo"][./p[contains(.,"Text zzz")]]')
el2 = find(:xpath, '//div[#class="foo"][./p[contains(.,"Text aaa")]]')
There's probably a slightly simpler way to do this using css instead of xpath, but I've found that this works for this type of situation. (Note: I haven't actually tested this code.)

parent = find("p[text()='zzz']").find(:xpath,"..")
within parent do
...
https://github.com/jnicklas/capybara/pull/505

Related

How to define within scope for (hidden) div with id-tag (capybara testing)?

Does somebody know how i use the visible option in a within to define a scope within a tagged div like <div id="contact-persons" class="row"> so that my testing scope for within will look like within("#contact-persons", visible: false) do ... end?
I just tried it exactly that way, but still cannot find the div.

I have two divs with the same class and ID.how do I use within, so that I can simulate clicks?

I work on a Rails project that uses Capybara for front end testing. I ended up in a situation where I have duplicate div tags with the same ID. How can I use capybara scoping so that I select only one of them and perform my tests within that div?
Given the html
<div id="wrapper1">
<div id="conflict">...</div>
</div>
<div id="wrapper2">
<div id="conflict">...</div>
</div>
then you should be able to do
within("#wrapper1") do
find("#conflict") # will find the matching element inside the wrapper1 div
end
However you really should just fix the HTML and any JS that uses those divs, since it is technically illegal HTML which can cause any number of unpredictable behaviors

Capybara Selecting CSS classes via regexp Ruby

Is there a way to find all div's on a page via their css class using a regexp if the classes match the regex? Below is an example snippet:
<div class="runtime">...</div>
<div class="runtime2">...</div>
<div class="runtime3">...</div>
I was hoping there is a way to get all divs via a regex because there could be more div's I want to find following that class format on the page but they change on a page by page basis.
For that format you can use a starts-with, and contains attribute selector
all('div[class^="runtime"], div[class*=" runtime"]', minimum:1)
The second selector is for the case where there's another class preceeding runtime... in the element. For a more general case there is no built in way to use a regex for class matching, although you could get an array of all the divs and then filter that based on the class attribute yourself (not going to be very performant)

Referring to current HTML-Element in Razor?

In Razor (MVC 4) can I do something like the following (pseudo)code?
<div id="One" #if(THIS_ID_IS("One")) {WRITE_SOMETHING_HERE} ></div>
<div id="Two" #if(THIS_ID_IS("One")) {WRITE_SOMETHING_HERE} ></div>
My intention is, that in DIV "One" an additional attribute will be written, but not in DIV "Two"
So, the THIS_ID_IS(string id) should determine, if the Razor-Parse is INSIDE the given DIV with id="xyz"
Is this possible?
You can use single line if statement to overcome this situation
<div id="One" #(THIS_ID_IS("One") ? "write something" : "") ></div>
Since ids are unique values. All divs will have diffrent ids.
So I dont think there is any need for Conditional Check in razor.
You can Directly add the extra attributes to your Div as follows
<div id="One" attribute-name="Value"></div>
In situations like this I tend to write a helper method to output the markup. This way you a not constrained by the 'rules' of razor. I did a similar thing to output jQuery slider html inside a div.
It also depends on your target audience, I rarely produce the actual views as our designer does most of that. I don't like handing over stuff to the 'creatives' that requires them to write/understand the logic.
It may not be the ideal solution or maybe even overkill in your situation but may be worth a look.
http://www.asp.net/mvc/tutorials/older-versions/views/creating-custom-html-helpers-cs
As much as I would like it to be possible. It looks like it's not the case.
Based on these two articles :
Simple
In depth
It would seem that the Razor engine combines a code and a markup parser.
The main parser decides to use one or the other.
So the parsers are not aware of one another.
Simply put, in your example, <div id="One"></div> and #if(THIS_ID_IS("One")) would be parsed in different scopes and then just concatenated together.

How to get id of an element when using Capybara for test (Rails)

I am using Capybara to write test in my application, but now i have a situation in which i need to read id of an element within capybara like
myid = page.find("#parentNode").first(".childClass").id
Consider i have the below HTML structure
<div id="parentNode">
<div id="childNode1" class="childClass">1</div>
<div id="childNode2" class="childClass">2</div>
</div>
Please Note : I am not trying to read the content of the child node, but the id. The above shown is for example.
Expected Output : childNode1 (id of first element with class childClass
You are almost near the answer. The only change is instead of calling id as method, you have to call it as attribute as follows
page.find("#parentNode").first(".childClass")[:id]
I would use some xpath instead of css in this case.
Note I am not that skilled in xpathing so I use css first to find parentNode.
find(#parentNode).find(:xpath, div[1]).id
Try that and see if it works.
optionally you can use css in the second find as well and use the class as criteria since it finds the first element anyway.
Got the answer..!!
We can use page.evaluate_script to achieve this. I used the below code
page.evaluate_script('$("#parentNode .childNode").first().attr("id")')
Hope this will help some one :)

Resources