Finding elements within a class in capybara - ruby-on-rails-3

I have a very simple DIV in my code:
<div class='articles'>
<h2>More articles...</h2>
<ul>
<li>Where to Take Your ...</li>
<li><a href="/articles/crucial-topics-that-are-covered-in-the-dmv-handbook" >Crucial Topics that ...</a></li>
</ul>
</div>
And I am trying to use capybara to test for the two LI elements but nothing works, I believe because I am searching within a class and capybara is having issues with this.
I've tried all variations of this:
page.should have_css('.articles li', :count => "2")
or
page.first(:css, '.articles').should have_css('li', :count => 2)
I have many instances where I need to be able to searching within a css class instead of ID so I am curious about how to get this to work

Related

How to find xpath of an element which depends upon sibling class

I have below html code
<a class = sidetoolsdivider>
<div class = sideone > Test 1 </div>
<div class = sidetwo> </div>
</a>
<a class = sidetoolsdivider>
<div class = sideone > Test 2 </div>
<div class = sidetwo> </div>
</a>
...............
Here I need to find xpath locator of class sidetwo which has text Test1. There are many such similar classes hence you can differentiate between different only based on element text
The xpath would be something like below:
Since the element depends on the text, can make use of text attribute for the same.
//div[text()='Text1']/following-sibling::div
Or
//div[contains(text(),'Text1')]/following-sibling::div
Or
//div[contains(text(),'Text1')]/following-sibling::div[#class='sidetwo']
Link to refer - Link
This gets you the correct 'a'. Find an 'a' which contains the right div of sideone (note the .//, find a Child which is)
"//a[.//div[ #class='sideone" and text()='Test 1']"
Then just get the side two, complete xPath
"//a[.//div[ #class='sideone" and text()='Test 1']//div[#class='sidetwo']"
Works even if there is more text inside the entire 'a' and stuff gets complex with more elements inside.

Is it possible to not omit some opts on the outermost element in a custom Riot tag?

I'm using RiotJS v3.9
I've written a custom tag that accepts a few opts. The problem is that the markup it generates includes all of those opts on the outermost element, in addition to the interior tags where I explicitly deposit them. I do not want any opts to appear on the top element unless I make that happen.
In this case, my custom tag display a list of items. One of the opts it accepts is the value for a specific data- attribute on each list item. So, I want data-something={opts.itemSomething} to appear on each list item, but I do not want that to appear on the wrapper.
// my-list.tag
<my-list>
<ul data-something={ opts.something }>
<li
each={ item in opts.items }
data-something={ parent.opts.itemSomething }
>
{ item }
</li>
</ul>
</my-list>
Using it:
<my-app>
<my-list
something="parent-value"
item-something="child-value"
items={['one', 'two', 'three']}
/>
</my-app>
What it emits into the page:
<my-list something="parent-value" item-something="child-value">
<ul data-something="parent-value">
<li data-something="child-value"> one </li>
<li data-something="child-value"> two </li>
<li data-something="child-value"> three </li>
</ul>
</my-list>
I don't want the emitted <my-list> tag to have either the parent-value or the child-value on it. I only want those attributes to appear on the <ul> and <li>, like I coded it.
// bad output
<my-list something="parent-value" item-something="child-value">
// good output
<my-list>
Is this possible?
Also, I know from working with React that I'm likely to encounter future cases where I want some of the opts to appear on the wrapper while hiding others. So, ideally I'd like to know how to control this behavior on a per-opt basis.
you can remove the unwanted attributes in both the "updated" and "mount" event.
check this demo
However I strongly suggest you to switch to riot#5!!

How to get all “li” elements of “ul” class in Selenium WebDriver - PageFactory specific

<div class="col-md-3 col-sm-3">
<h4>Free Resources</h4>
<ul>
<li>
NCERT Solutions for Class 10 Maths
</li>
<li>
NCERT Solutions for Class 9 Maths
</li>
<li>
NCERT Solutions for Class 10 Science
</li>
<li>
NCERT Solutions for Class 9 Science
</li>
<!-- CBSE Previous Year Paper -->
<li>
CBSE Previous Year Paper
</li>
<!-- RD Sharma solutions-->
<li>
RD Sharma Class 10 Solutions
</li>
<!-- Tutors SEO Pages-->
<li>
Home Tuition
</li>
<li>
Math Teacher
</li>
<li>
Science Teacher
</li>
</ul>
</div>
I have pasted the html I am working with. Just to make things more clear there exists two more div tags in the same hierarchy with the class name = 'col-md-3 col-sm-3'.
I found this question helpful (How to get all "li" elements of "ul" class in Selenium WebDriver) but I wanted to know how to do the same using PageFactory ?.
Please help me here. I am thinking that I will find the root of the list <div> element (using #FindBy annotation) and do the looping for each <a> tag and return this list from the Element repository class for that web page. Is there a better way to do this? I specifically want PageFactory version of this.
You can use #FindBys
like,
#FindBys(xpath)
List<WebElement> elements;
For example if have list of element under UL tag. Then your xpath will be //ul/li/a and you can use it in page factory as given below.
#FindBys(xpath="//ul/li/a")
public List<WebElement> elements;
You can call it in your script or method like, I assume the element is on homepage,
Home homePage = new HomePage(driver);
PageFactory.initElements(driver, homePage);
homePage.elements.get(0).click //to click on first element
or to iterate all elements and get the values as given below.
for(WebElement element:elements)
sop(element.getText();

HAML generate nested divs in loop

Is there any way to generate many divs nested each other?
I expect print some like this:
<div>
<div>
<div>
<div>
<div>
</div>
</div>
</div>
</div>
</div>
Simple loop is not helping
- (1..5).each do |i|
%div
Goes to
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
There isn't any way of doing this in pure haml, by design.
Firstly, ask yourself: Do you really need this? There are often far better ways to achieve the result you want.
In my case, I needed an arbitrary nesting of divs with a particular class, based on a number I was given externally. I added the following to my rails helpers:
def nestify(css_class, level, &block)
if level > 0
content_tag(:div, class: css_class) { nestify(css_class, level - 1, &block) }
else
yield
""
end
end
Then, in your haml, you use it with a block:
= nestify('each-div-has-this-class', 5) do
Content for inner div.
[Edit] Quick note: I wrote this a while back, can't remember why - but this code is not production ready. Ruby doesn't work well with recursive functions. Please flatten it into a loop for better performance / scalability.

Backbone Marionette extra div wrappers: tagName solution in other threads not working for DYNAMIC tabs

Below is a snippet from a sample tab control from here: http://layout.jquery-dev.net/demos/tabs.html
Those tabs inside those splitter panes are exactly what I need. But I need the tabs to be dynamically added and removed based on user interaction. Thought I could do it with composite or collection views in backbone marionette - add/remove things from the underlying collection and tabs appear and disappear in the UI.
Conceptually this shouldn't hard. But the difficulty comes in with the the dreaded extra wrapping div problem that is so discussed in various threads over the years.
Extra divs in itemviews and layouts in Backbone.Marionette
In my case, each li in my ul comes up wrapped in a it's own div. That messes up the CSS in the code snippet below. It breaks some of it, so things look weird. If I could just produce the output below, things wouldn't look weird.
<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all ui-sortable" role="tablist">
<li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tab" tabindex="0" aria-controls="tabs-west-1" aria-labelledby="ui-id-1" aria-selected="true">
Nunc tincidunt
</li>
<li class="ui-state-default ui-corner-top" role="tab" tabindex="-1" aria-controls="tabs-west-2" aria-labelledby="ui-id-2" aria-selected="false">
Proin dolor
</li>
</ul>
The output above has complex li's rendered directly in the ul container which is also complex. Why can't I make that output happen?
This extra wrapping div seems to be the default behavior of backbone marionette when itemView's are rendered. Many answers in these threads center on setting the tagName property to li. Problem is that produces a blank, generic li. Look at the li's in the snippet above. They have lots of properties.
My li's will need to have unique id's and styling and other attributes like those above. Making your item view's tagName an li just produces a simple li in your output. How do I get my dynamic id's and styling classes and such in there?
My first attempt to fix this was to pull the li code into my handlebars template so I could encode it with the dynamic data I needed:
var TabItemView = Marionette.ItemView.extend({
template: Handlebars.compile(
'<li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tab" tabindex="0" aria-controls="tabs-{{id}}" aria-labelledby="ui-id-{{id}}" aria-selected="true">' +
'{{tabName}}' +
'</li>'
),
});
But that now wraps each li in my list in it's own container div. Every combination of using el, tagName, appendHtml override produces either a wrapping element or incorrect results - like appendHtml override causes each new tab to simply replace existing tabs - so I only ever have one tab, the latest one added.
What am I missing here? Why can't I define a template for an li containing dynamic data in it and render it DIRECTLY to my ul WITHOUT an extra wrapping div around each list element? I guess another way to phrase the question is I am working with an existing template that REQUIRES complex li's. How do I produce them in a composite or collection view WITHOUT the extra wrapping container around them?
Backbone and Marionette seem to offer the promise of being able to do things like this in a way more manageable than doing it in straight jQuery. I'm not having that experience. What am I not seeing?
I don't use Marionette, but I don't see why it would override Backbone's default behavior. This should give you an idea:
var TabView = Marionette.ItemView.extend({
tagName: 'ul',
className: 'ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all ui-sortable" role="tablist',
render: function() {
//something like this
var _this = this;
this.collection.each(function(item){
var view = new TabItemView({
model: item
});
_this.$el.append(view.render().el)
})
}
});
var TabItemView = Marionette.ItemView.extend({
tagName: 'li',
className: 'ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tablist',
template: Handlebars.compile(
'{{tabName}}'
),
});
Regarding managing views and data to produce specific HTML output, I suggest you take a look at my blog post here: http://davidsulc.com/blog/2013/02/03/tutorial-nested-views-using-backbone-marionettes-compositeview/
That should get you to structure the views so they render properly. Then, you can add http://backbonejs.org/#View-attributes to the mix to get your complex attributes (for which there aren't existing Backbone attributes such as className).