i am making my first steps in writing cucumber features in Ruby On Rails application and am struggling with getting a value of an element.
The structure is something like this:
<div class="selectize-dropdown-content">
<div data-value="test1" data-selectable="" class="option">TEST 1</div>
<div data-value="test2" data-selectable="" class="option">TEST 2</div>
</div>
I would like to get the value of the div element when the data-value is "test1" ... so, TEST 1
Currently I am doing it this way:
within(:xpath, '//div[#class="selectize-dropdown-content"]') do
find(:xpath, '//div[#data-value="' + value + '"]')
end
But it fails for not finding the "within" div.
So, I guess I am doing it wrong.
How does one go about it?
Thx
You need to call text method on the desired element
within('.selectize-dropdown-content') do
find(:xpath, "//div[#data-value='#{value}']").native.text
end
if there's a parent element for your block of code with ID you can do it like:
text = page.find('#parentID div:nth-child(1) div:first-child', visible: true).text
if you don't try it with javascript
text=page.evaluate_script('document.getElementsByClassName("selectize-dropdown-content")[0].getElementsByTagNam("div")[0].value')
Related
I'm trying to iterate over a list and pass the current iteration and another model variable to a fragment, but the "other" model variable is always null.
<div th:each="place : ${results.placeResults}" class="col-sm-6 col-xl-4 mb-5">
<div th:replace="fragments/placecard :: placecard" th:with="place=${place},res=${results}"/>
</div> <!-- end for each-->
In the fragment ${res} is always blank.
I figured it out, the th:replace basically makes the th:with have no effect. I changed the code to use th:include and things look better.
There is the structure like:
<div class="parent">
<div>
<div class="fieldRow">...</div>
</div>
<div>
<div class="fieldRow">
<div class="CheckBox">
</div>
</div>
<div>
<div class="fieldRow">...</div>
</div>
<div>
<div class="fieldRow">...</div>
</div>
</div>
In my script I am writing a loop for each of the 4 div's under div[#class='parent'] and aiming to click the checkbox if there is, i.e.
members = page.all(:xpath, '//div[#class='parent'])
members.each do |a|
if **page.has_xpath?(a).find(:xpath, "div[#class='fieldRow']/div[#class='CheckBox']")**
a.find(:xpath, "div[#class='fieldRow']/div[#class='CheckBox']").click
end
end
However I can't look for the correct usage of has_xpath? with xpath including variable.
Please advice? Thank you!
has_xpath? takes an XPath expression (not an element) and returns a boolean (true/false) based on whether there are any elements that match that expression within the current scope - http://www.rubydoc.info/gems/capybara/Capybara/Node/Matchers#has_xpath%3F-instance_method. Since it returns true/false you can't then call find on it. For the example you posted there's no need for XPath or checking for the existence of the elements, just find all the matching elements and call click on them. Something like
page.all('div.parent div.fieldRow div.Checkbox').each { |cb| cb.click }
or
page.all('div.parent div.Checkbox').each { |cb| cb.click }
if the fieldRow class isn't something you really need to check.
Note: this assumes clicking the elements doesn't invalidate any of the other matched elements/change the page.
If you REALLY need to do it with the whole members and looping on them , using XPath, and checking for presence then it would be something like
members = page.all(:xpath, './/div[#class='parent'])
members.each do |a|
if a.has_xpath?(:xpath, ".//div[#class='fieldRow']/div[#class='CheckBox']")
a.find(:xpath, ".//div[#class='fieldRow']/div[#class='CheckBox']").click
end
end
Note: the .// at the beginning of the XPath expressions is needed for scoping to work correctly - see https://github.com/teamcapybara/capybara#beware-the-xpath--trap - which is an issue using CSS selectors doesn't have, so you should really prefer CSS selectors whenever possible.
Feels like a dumb question but I do not get it. How can I do fast string concatenation in Angular 2 Dart templates?
I have a seperate html file for my component lets say my_component.html:
Works:
....
<div id="abc">
{{order.pickupPlace.email}}
</div>
...
Works:
....
<div id="abc">
{{ ((order.pickupPlace.state) ? order.pickupPlace.state+" ":'')}}
</div>
...
Does not work:
....
<div id="abc">
{{"<br/>"+order.pickupPlace.email}}
</div>
...
Does not work:
....
<div id="abc">
{{order.pickupPlace.name+" "+order.pickupPlace.email}}
</div>
...
Have tried to find an answer in the docs here (https://webdev.dartlang.org/angular/guide/template-syntax#!#expression-operators) but no luck.
Of course I could use *ngIf on every element which I output conditionally but is there a way for simple string concatenation?
The best way is to declare a getter inside your Component controller that does the concatenation for you, you will get dart syntax support and the html template will looks cleaner.
String get myConcatenation => "${order.pickupPlace.name}${order.pickupPlace.email}";
<div id="abc">
{{myConcatenation}}
</div>
The last two examples can be made to work easily:
<div id="abc">
<br/>{{order.pickupPlace.email}}
</div>
And:
<div id="abc">
{{order.pickupPlace.name}} {{order.pickupPlace.email}}
</div>
Angular handles this pretty well. If you need some more complicated logic you can move it to the Dart code (but you cannot use HTML there easily).
If you find creating lot of weird logic consider creating more smaller components that can handle this for you.
I am writing the test automaton code for a system and the dev team presented me the following html:
<div id="someId">
<div class="classA">
<button class="classB">
</div>
<div class="classA">
<button class="classB">
</div>
</div>
Now the question is: Is it possible to click exclusively on the SECOND button? If so - how?
If I understand you right, you're click on links styled as buttons. You can use this step definition
Then(/^I click the (\d+) instance of link "(.*?)"$/) do |instance, link|
page.all('a', :text => "#{link}")[instance.to_i - 1].click
end
I would not rely on the order of elements returned by all. I remember running into issues with it in the past, see e.g. this issue. Instead I'd use a selector, something like this:
find("#someId div.classA:nth-child(1) button.classB").click
(IIRC they are zero-indexed)
Trying to validate the 2nd link in the following HTML:
<div id="navigation">
<ul>
<li>
TV
</li>
<li>
Radio
</li>
with the following expression:
page.find(:xpath, "//div[#id='navigation']//a").should have_content('Radio')
and I'm getting the following error:
expected there to be content "Radio" in "TV"
Should'nt the find method research in all the A elements inside the DIV node as I'm using a double slash? Could this be a bug or am I doing something wrong?
And is there any other way to be able to validate the 2nd link?
Thanks for the help guys!
In your case find will find first a in Capybara < 2.0 and will raise an Ambiguous Match exception in Capybara 2.0 as there are more than one elements with such locator.
I suggest you to do the following:
page.should have_selector('#navigation a', text: 'Radio')