Capybara: How to test a stylesheet of a page? - ruby-on-rails

I want to have the ability to test the correct swapping of a stylesheet in my test suite. With this post about testing the page title using Capybara, I thought I would be able to test any link tags in the head section of the page. But it seems I am mistaken.
With a step like this:
save_and_open_page
page.should have_xpath("//link") # just something as simple as this, first.
save_and_open_page generates a HTML like this (with some stuff removed for brevity):
<head>
...
<link href="/home/ramon/source/unstilted/public/system_test/stylesheets/fancake/css/2.css?1323572998" type="text/css" class="jquery-styler" rel="stylesheet">
...
</head>
But I get this failure:
expected xpath "//link" to return something (RSpec::Expectations::ExpectationNotMetError)
Given all that, how do I test a stylesheet?
Thanks!

If you want to check that a CSS file exists on a page, then you can do the following:
page.should have_xpath("//link[contains(#href, 'style.css')]")
That'll check whether there are any <link> elements where the href attribute contains style.css. The error about "expected xpath to return something" means that the XPath you provided didn't actually exist - why it thinks that, I'm not sure, as you have a perfectly valid <link> tag in the HTML you've provided.

When I am checking for a css what I do is something like
expect(page.body).to include('/home/ramon/source/unstilted/public/system_test/stylesheets/fancake/css/2.css')

Related

Using javascript global window variables and integration testing

There's this nifty stackoverflow post on passing variables to Javascript. It echos this railscast episode. The technique works like a charm for configuring a jquery datepicker, but cause all my javascript integration tests to fail.
Here is the code in application.html.erb
<script type="text/javascript">
<%-# commented line -%>
window.sDateFormatLocal = "<%= t 'date.formats.js_date' %>"
</script>
This is a datepicker initialization that uses it
$("input.datepicker").datepicker({
dateFormat: sDateFormatLocal,
onClose: function(value, ui) {
console.log("regular old datepicker");
}
}
It appears to work very well. The only problem, all my integration tests with 'js: true' now fail. Here are the errors I get.
Capybara::Poltergeist::JavascriptError:
One or more errors were raised in the Javascript code on the page:
ReferenceError: Can't find variable: sDateFormatLocal
When I run in browser (Chrome, Firefox) there are no errors or warnings in the console.
For completeness, a typical spec looks like this:
describe "The root" do
it "should load the page and have js working.", :js => true do
visit root_path
page.should have_content "Hello world"
end
end
Is there a setting I am missing to allow variables like this in poltergeist?
If your datepicker function is not in jQuery document ready function or similar methods such as window.onload you'll have trouble.
By default the application.js will be loaded in head, and the JS code in your html.erb later. The html and assets are loaded by browser in parallel, and very likely assets will finish loading at first. If you execute the function right away instead of waiting for document ready, the variable is undefined.
If you missed that, put such code in ready block.
A better practice for exporting server variable is, instead of put it in html body, put it on head before application.js so you won't have any problem on undefined variable.
Just to follow-up on this, in case someone in is debugging a similar problem. It turned out in this case, not every view was using the same template. For instance, the signin screen has a different head. That was causing this not to load in certain circumstances, yet not others, like the ones where my tests were failing. Bottom line, make sure when you replicate your tests, you are doing it exactly as the tests do, like in my case, passing through a signin screen.

Render HTML file with CSS and local variables

I have the following content in an HTML file placed under public/company/ with a CSS file css/style.css:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<link href="css/style.css" rel="stylesheet" type="text/css" media="all"/>
</head>
<body>
<div class="title">Name {name}</div>
</body>
</html>
I want to render this HTML file with the CSS stylesheet from an action and replace {name} without changing the physical file content and place. I can render the HTML file but the CSS file would not be found. Can anyone help me render the HTML file with the CSS file and replace the {name}?
css/style.css when called from company/file.html will try to load company/css/style.css.
Click here to see an article the way you can do that. Hope it will help!
But, I'm not sure why you are looking to render that way where Rails has all the features in place.
If your CSS file is located at /public/company/css/style.css, then your static HTML file should link it with an absolute path. Use a leading / in the resource's path indicate an absolute path.:
<link href="/company/css/style.css" rel="stylesheet" type="text/css" media="all"/>
Note that the Rails router will likely catch this request and raise an exception. Depending on the web server, you may need to enable static assets or serve directly, bypassing Rails altogether.
Changing the content of a static HTML file server-side without actually modifying it (ie. adding ERb) isn't straightforward. You could:
inject some javascript into the response to perform modifications client-side. (ugly)
load the static HTML file using Nokogiri, et. al., modify the content, and send the output to the client. (expensive)
Sounds to me like these vanilla HTML/CSS files are third party (designer? client?) and you would like to drop it in /public and have it work automatically with Rails. That would be nice, but it's not that easy. You'd be better off using Rails' built-in templating system, but that means modifying files and moving them to the expected locations.

RSpec have_tag failing even when tag is present?

Currently doing the Ruby On Rails Tutorial by Michael Hartl, and am starting on test-driven development. The tutorial demands that tests be written to ensure that the right titles are present on our html.erb pages. There are three of these pages - home, contact and about. The tests look like so:
it "should have the right title" do
get 'home'
response.should have_tag("title",
"Ruby On Rails Sample Application | Home")
end
My home.html.erb file looks like so:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Ruby On Rails Sample Application | Home</title>
</head>
<body>
<h1>Sample App Home</h1>
<p>This is the home page for the
Ruby on Rails Tutorial
sample application.</p>
</body>
</html>
As you can see, the title tag is present and it's wrapping the correct text. However, when I run my test, I get this error message:
'PagesController GET 'home' should have the right title' FAILED
Expected at least 1 element matching "title", found 0.
Can anyone explain what is going wrong here? Thanks
Do you have
require 'spec_helper'
on top of your pages_controller_spec.rb?
Do you have
render_views
statement in your describe block?
To John Paul Ashenfelter, I thought save_and_open_page was Capybara method, and not Rspec?
You should start by making sure the page renders correctly using
save_and_open_page
in your Rspec. Usually there's a problem with the rendering (eg maybe invalid xHTML?)
You'll also need to add the launchy gem to your project (eg gem 'launchy' in your Gemfile)

Symfony: question about paths

in the cover page (login, register...) of my app i have this line:
<link rel="stylesheet" type="text/css" href="/css/formularios.css">
When i deploy my app, the that css rule is not loaded because, as i can
see in Firebug, it's looking for that rules in
www.tirengarfio.com/css/formularios.css instead of
www.tiregarfio.com/rs2/web/css/formularios.css.
What should i do?
Javi
You should use the view.yml config file and the include_stylesheets() helper. However, if you'd like to create the link tags by hand, use the public_path() helper to get the correct path.

grails app root context

I have a test grails app setup with a context of "/testapp". When I add a link in my gsp that references / it does not go to the root of my grails.app.context, but to the root of my grails.serverURL property.
For example given a link with href "/css/main.css"
I would expect that this link would actually look in localhost:8080/testapp/css/main.css instead of localhost:8080/css/main.css
Is there a way that I can get references to / to start at my grails.app.context vs the grails.serverURL?
use the request contextPath value on the page
${request.contextPath}
and then prepend the additional host information if necessary to construct the complete url
the question is how do you add your links into your gsps?
We do things like
<link rel="stylesheet" href="${resource(dir: 'css', file: 'stylesheet1.css')}"/>
and
<g:javascript library="prototype"/>
by using the g:javascript and resource tags and methods, you tell grails to set the path for you...
I suspect you are just putting standard tags in...
goto
http://grails.org/doc/latest/
and, under tags in the left hand nav, look for resource and/or javascript to get an idea (its difficult to link directly in to the docs...:()
I had a similar issue to OP - how to have grails form links that start at the context root and NOT server root?
You can do so using the "uri" attribute for g:link and g:createLink tags. For example:
<g:link uri="/login">login</g:link>
will prefix any context if applicable, and produce the following
login if your app is at the http://server/
login if your app is at http://server/testapp/
Not sure why it's an undocumented attribute in the reference docs, but I found it in the Javadocs - ApplicationTagLib
You should probably be using the resource tag into your grails CSS directory, like mentioned above. However, you can also use the resource method to find the root context of you web application using the same tag:
${resource(uri:'/')}
then just use that string wherever.
And when it comes to elements like stylesheets I'd recommend creating a simple tag that'll do the trick, something along those lines:
class StylesTagLib {
static namespace = "g"
def stylesheet = { args, body ->
out << """<link rel="stylesheet" href="${resource(dir: 'css', file: args.href)}"/>"""
}
}
and later on in your code use it like this:
<g:stylesheet href="main.css"/>
Obviously you can fiddle with the conventions (should I use a predefined folder? should I add the .css extension automatically? stuff like that) but the general idea is to hide the ugliness behind a nicely defined tag.

Resources