in my Rails4/rspec app, I need to male Capybara click on a zone that has no formal "link" , using data-target attribute.
html
<div class="info-zone">
<span data-target="#myInfoZone1" class="City" data-toggle="modal">
</span>
</div>
My current attempt at using capyabar fails
describe "modal loads with the right content" do
it "has right text" do
visit actual_page_path(:id => #deal.id)
find("span[data-target='#myInfoZone1']").click
end
I currently get this error
Capybara::ElementNotFound:
Unable to find css "span[data-target='#myInfoZone1']"
How can I make capybara "find" and click on the zone ?
Thanks for your help
EDIT
I found out why capybara is not finding it!
for a reason I can't understand, that is the html output code capybara finds
<!-- city zone -->
<div id="city-zone">
<!--
We gather here the various types of <spans> and load it via javascript
we append it to the the div id=city-zone
-->
</div>
I am using javascript to load inside this div. so when I load the 'page source' i see what's above
but when I go on chrome dev tools, then I see:
<!-- city zone -->
<div id="city-zone">
<div class="info-zone">
<!--
We gather here the various types of <spans> and load it via javascript
we append it to the the div id=city-zone
-->
<span data-target="#myInfoZone1" class="City" data-toggle="modal">
</span>
</div>
</div>
So i guess capybara sees the same thing as I see when I load the page source: no .
how come my javascript which I append does not appear in the html code source?
what to do about it to make capybara work
Capybara's default driver only tests html rendered by your back-end application server. If you want to test pages with front-end javascript as well, you should use a javascript-enabled driver with Capybara.
Luckily, the folks at thoughtbot made a Capybara extension just for that Capybara-webkit You can easily install it in your Gemfile. Follow the instructions here on how to install the gem.
Finally, once you install it, you can enable javascript tests in your feature specs by adding js: true in your features/scenarios as following:
RSpec.feature "test my new feature", js: true do
# my test
end
Related
I use Trix Editor to have WISIWIG in my form. I want to test with RSpec and Capybara but trix-editor put the field hidden.
<div class="form-group">
<trix-editor class="formatted_content form-control" placeholder="Description" input="annonce_ad_body_trix_input_annonce_ad"></trix-editor><input type="hidden" name="annonce_ad[body]" id="annonce_ad_body_trix_input_annonce_ad" />
</div>
I need to know how i can fill this hidden field with Capybara to make my test pass. I have try these attemp:
fill_in "annonce_ad[body]", with: "my value"
find(:css, 'trix-editor').set("New text")
find("trix-editor", visible: false).set("my value")
find(:xpath, "//input[#id='annonce_ad_body_trix_input_annonce_ad']", visible: false).set "my value"
find(:xpath, "//*[#id='annonce_ad_body_trix_input_annonce_ad']", visible: false).set("value")
first('input#annonce_ad_body_trix_input_annonce_ad.class', visible: false).set("your value")
None of these have work for me. Someone have any idea how i can fill my body(with trix) in this case?
When using Capybara the rule when dealing with non-standard controls is to mimic what the user would do. In this case that would be click on the visible field (trix-editor element) and then type the contents wanted. You should never be trying to fill in non-visible elements and in fact the visible option should rarely (if ever) be used when testing an app (makes some sense if using Capybara for scraping). So in your case that should be
find('trix-editor').click.set('New text')
It would probably work without the click, but it doesn't hurt to more fully replicate the user. Since you've stated that something very similar to that doesn't work for you (but not provided the actual error) I have to assume you're not actually using a JS capable driver. Since trix is a JS driven editor you need to use a JS capable driver when testing it - https://github.com/teamcapybara/capybara#drivers .
The following basic ruby snippet shows Capybara filling in the demo trix editor at trix-editor.org
require 'capybara/dsl'
require 'selenium-webdriver'
sess = Capybara::Session.new(:selenium_chrome, nil)
sess.visit('https://trix-editor.org/')
editor = sess.find('trix-editor')
editor.click.set('My test text')
editor.assert_text('My test text')
I make a mistake, this work for me.
find(:xpath, "//*[#id='annonce_ad_body_trix_input_annonce_ad']", visible: false).set("some value here")
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
I'm using Capybara to perform some functional tests on a Ruby On Rails app.
(Everything seems properly configured, as other Capybara tests run as expected.)
In my home page I have a link to the sign up one, in this format:
<a href="http://www.example.com/signup" class="sign_up_1">
<div class="signUpStyle">Sign Up</div>
</a>
In my test:
page.has_link?("Sign Up", :href => '/signup')
always returns false. It shouldn't, should it?
Yes it will return false.
Since the final xpath generated would have "//a[#href='/signup']" which is not a valid xpath for your dom.
You can do
page.has_xpath?("//a[#href='#{sign_up_path}']")
capybara-docs
You can also verify
page.has_link?('Sign Up', href: "http://www.example.com/signup/company")
I have been using Jekyll for a month or two now, I am also new to Ruby so learning every day.
In my site I want to add the reading time of blog posts, I have found this ruby gem which will let me do it
https://github.com/garethrees/readingtime
I install it in the normal way into my sites root and add the code needed and nothing happens. This isn't a shock because I have no actually link to it in my sites root?
So it my site looks like this html wise
---
layout: default
---
<div class="twelve columns">
<h3>{{ page.title }}</h3>
<span class="date">Wrote by Josh Hornby</span>
<span class="date">Estimated reading time – <%= #article.body.reading_time %> </span>
<br /> <br />
<%= #article.body %>
{{ content }}
</article>
<div class="twitter_button"> <img src="/images/twitter.png" alt="twitter-logo" width="50" height="50" /> </div>
</div>
<div class="four columns">
<h3>Recent Posts</h3>
<p>Find out what else I've been talking about:</p>
{% for post in site.related_posts limit: 10 %}
<ul class="square">
<li><a class="title" style="text-decoration:none;" href="{{post.url}}"><strong>{{ post.title }}</strong></a>
{% endfor %}
</ul>
</div>
Now I'm not shocked that its not working but my question is how to a install the gem so I can access it in my Jekyll file? Do I need to create a _plugin directory and call it from there? Or won't it work as its not a jekyll plugin? In that case I may have a little project writing my own Ruby Jekyll plugin.
As you have surmised, you cannot call arbitrary ruby commands in your html using <%. Instead, you want to write a plugin which defines a Liquid filter. In your html above, you would use the liquid tag to grab the content of the page. You might want to brush up on liquid-for-designers and liquid-for-programmers as well as the Jekyll notes on writing liquid extensions before we dive in, but I'll try to explain.
First, we need to use a Jekyll filter to grab the content of the page, which we will pass to our plugin for analysis. Above you have an #article.body which probably means something to a ruby on rails site, but doesn't mean anything to Jekyll. As you see in the center of your layout file, the content for the page is simply called content. It is pulled in through a Liquid output, indicated by the {{ }}.
In place of the line
<span class="date">Estimated reading time – <%= #article.body.reading_time %> </span>
We want a line that grabs the content and passes it to our plugin:
<span class="date">Estimated reading time – {{ content | readingtime }} </span>
The vertical bar is a filter, meaning pipe content to the function readingtime and include the output. Now we need to write the plugin itself. In the _plugins directory, we create a ruby script following the standard template for a Liquid filter:
require 'readingtime'
module TextFilter
def readingtime(input)
input.reading_time
end
end
Liquid::Template.register_filter(TextFilter)
And save the above as something like readingtime.rb in _plugins. It's kinda self explanatory, but you see this tells ruby to load the gem, and define a filter that takes its input and applies the reading_time function to that string.
A little note: content will pull in the HTML version of the content, not a plain text string. I don't know if the readingtime gem needs a plain text string, but you can of course convert between them using a little extra ruby code. If necessary, that's left as an exercise to the reader (though this might help).
This is my first project using Ruby on Rails and I'm working on the front-end code; the back-end developer is new to rails too. One template includes the code render 'flashes', which is triggered when there is an error on a form submission; but the markup it generates is messed up, and I'd like to fix it. Here's an example. The <!-- comments --> are mine:
<div id="flash">
<div class="wrapper">
<div title="Error" class="error"></div> <!-- Empty div -->
<p>Please enter a valid email</p> <!-- p element sibling of div.error -->
</div> <!-- Closes div.wrapper -->
</div> <!-- Closes div#flash -->
</div> <!-- Extra /div closes parent div -->
I would prefer to use one div for the message, but the biggest problem is the extra closing div tag at the end, which closes a parent division, messing up the layout.
I see that the error message is defined in the controller as flash[:error] = "Please enter a valid email", but I don't know where rails is getting this bogus markup. Is there a _flashes partial I can edit to fix this problem? I've pored over the project's filesystem, and it's not clear to me where this markup lives.
There is no _flashes.html.erb file in the Rails source. If you're seeing
render 'flashes'
in your application, you or some generator you ran put it there. Look through the files in app/views/ for one called _flashes.html.erb that contains the markup you provided in your Question. Once you find that file you should be able to modify it however you need to fix your broken HTML issue.
If you can't find it there, look at your list of gems in your Gemfile, specifically for one that relates to theming/templating. It's possilbe you've included a gem that contains this template file (though much less likely than the file existing in app/views/).