Check content of web page in cucumber test - ruby-on-rails

I'm starting to explore BDD and Cucumber.
So I want to check if my page displays the content of 2 articles I have.
This is the step I'm using the check if the content is there:
Then /^I should see "([^"]*)"$/ do |desc|
page.should have_content desc
expected = Article.find_by_description(desc)
page.should have_content(expected.navision_code)
page.should have_content(expected.category.name)
end
Normally this should do the trick I guess but when I run the test I got this error message:
expected there to be content "---\n- tenetur\n" in "Alfa Paints Order System\n\n\n\nAlfa Paints\n\n\n\nSeth abernathy, admin\n\n\nVerander paswoord\n\nLogout\n\n\n\n\n\n\n\n\n\n\n\nAlfa Paints\nordering system\n\n\n\n\n\nOverzicht van alle artikelen\n\n\n\nBack\n\n\n\n\n\n\nProduct ID\nBeschrijving\nCategorie\n3001\nPaint\n---\n- tenetur\n\n3002\nBrush\n---\n- tenetur\n\n\n\n\n\n\n\n\n\n\n
(RSpec::Expectations::ExpectationNotMetError)
./features/step_definitions/admin_articles_steps.rb:41:in `/^I should see "([^"]*)"$/'
features/admin_articles.feature:10:in `Then I should see "Paint"'
As you can see I expect paint and the error message shows the content has paint inside.
But somehow cucumber isn't recognizing it.
I'm new to cucumber and I'm probably missing something but maybe somebody could help me on my way.

You are testing for three things at once, so it is difficult to tell which of the expectations is failing. As a first step, try commenting out everything but the first expectation just to make sure its failing where you think.
Then /^I should see "([^"]*)"$/ do |desc|
page.should have_content desc
// expected = Article.find_by_description(desc)
// page.should have_content(expected.navision_code)
// page.should have_content(expected.category.name)
end
If you still have the same problem, add debugger so that you can experiment and see what is going on from inside your test environment. This is a skill worth developing if you plan to do much cucumber testing.
Then /^I should see "([^"]*)"$/ do |desc|
debugger
page.should have_content desc
end
From debug console, see what the desc variable and page look like:
p desc
p page.content

Related

Capybara have_text Passes When It Should Fail

I have an test written with RSpec and Capybara that should not be passing, however it is:
it 'should have the given text' do
visit root_path
expect(page).to have_text("This is not here")
end
I then included this in the test to look for the issue:
puts page.text
It returns a lot more text than is on the page, and included in that is:
Extracted source (around line #12):
10 11 12 13
})
visit root_path
expect(page).to have_text("This is not here")
It looks like whatever I put in my test will come up when it calls has_text?. Why does it contain all this text that is not on the page?
This is because you have an error in your app/code and a gem rendering the error, and surrounding code, to the returned page enabled in test mode. You want to disable all those types of gems (better_errors, etc) when in test mode (so it's closer to production mode). You can do that by moving them to a development only group in your Gemfile. You can also look in test.log to see what error is being thrown.

Button doesn't get clicked using capybara (using Firefox and xvfb)

I'm trying to set up cucumber tests in docker so I found out that I need to use xvfb in order to at least run tests without GUI. After hours of struggling I've finally run tests, but now:
I'm testing sending data through the form. I'm filling necessary fields and I'm clicking the button, but it doesn't do anything. It works fine when I'm browsing through the page; it is okay when I run cucumber locally without docker (with or without headless Firefox), but it fails in that one case. When I'm debugging it sees the button, click returning 'ok', but it does nothing. Also, current_url doesn't change, and Product is not saved to DB (so I assume button does not get clicked).
Could it be a problem with not compiled scripts files, maybe JavaScript doesn't work properly in headless Firefox or something else?
I've updated capybara to latest version. Code for testing:
step 'I click on Products link'
expect(page).to have_content "You don't have any products yet!"
click_link('ADD YOUR FIRST PRODUCT')
expect(page).to have_content 'Add new product'
fill_in('Product Name', with: 'Product')
fill_in('Price', with: 19.99)
fill_in('Description', with: 'This is test product')
find(:xpath, "//input[#type='submit'][#value='SAVE PRODUCT']").click
expect(page).to have_content 'Your product is LIVE' # it fails HERE
click_link('BACK TO PRODUCTS')
expect(page).to have_content 'Product'
click_link('Edit')
expect(page).to have_content 'This is test product'
find_all(:xpath, "//a[#href='#productVariants']").first.click
expect(page).to have_content 'CREATE VARIANTS'
find_all(:xpath, "//a[#href='#customizeWidget']").first.click
expect(page).to have_content 'Button background'
find_all(:xpath, "//a[#href='#flashSales']").first.click
expect(page).to have_content 'Enable Sales Boosters'
And the error message is:
expected to find text "Your product is LIVE" (...) (RSpec::Expectations::ExpectationNotMetError) (should I post page content also?)
It works that way - after save the same page for editing product is shown but modal is revealed and there should have this text. I've saved a screenshot, a page was not reloaded and the modal was not shown (modal is shown if a product is saved properly).
Try precompiling your assets/javascripts in test environment. Problem might be with your javascript not running.
Turns out the problem was I had wrong version of Firefox installed in my container and I guess my version of selenium (2.53.0) was not working properly with FF 52.

Using rspec failed tests (to map the program out) is resulting in errors?

Note: I'm following a tutorial for Ruby on Rails, and thus I'm a complete noob
Basically, in the tutorial I am following, it shows you how to make failed tests that you meet as you go along, like a checklist for your program. My problem is that when I do the test, it sort of outputs what it should, but in errors, which isn't good (I think) because it doesn't match the output of the instructions.
Output: http://pastebin.com/0xyf3aBf (and show below)
Output
Failures:
1) Static pages Home page should have the content 'Sample App'
←[31mFailure/Error:←[0m ←[31mexpect(page).to have_content('Sample App')←[0m
←[31mexpected #has_content?("Sample App") to return true, got false←[0m
←[36m # ./spec/requests/static_pages_spec.rb:9:in `block (3 levels) in <top
(required)>'←[0m
Finished in 0.07 seconds
←[31m1 example, 1 failure←[0m
Failed examples:
←[31mrspec ./spec/requests/static_pages_spec.rb:7←[0m ←[36m# Static pages Home p
age should have the content 'Sample App'←[0m
Randomized with seed 10853
My static_pages_specs.rb file: http://pastebin.com/L0LHACR4 (and shown below)
static_pages_specs.rb
require 'spec_helper'
describe "Static pages" do
describe "Home page" do
it "should have the content 'Sample App'" do
visit '/static_pages/home'
expect(page).to have_content('Sample App')
end
end
end
Other than the extra control codes (which might just be a symptom from your console or the cut&paste), this looks like a normal test failure. Which you should expect if you have written the test first.
One important part of TDD is indeed to get a simple failing test - with this kind of failure (the have_content matcher has failed to match) - and to then "fix" the failure.
It is also possible to get problems with the test code, which would also need fixing of course. But I don't see anything wrong with your test in this case.
If there was something wrong with the test, you would have to debug it in the more traditional way of applying critical thinking and experience when you read the code. So try to keep the test code simple, and to the point. Break down long complex tests into many short small ones.
Possibly the have_content matcher could be improved to give better context, rather than make a sub-test that you were not aware of . . . that was written by someone else though, and isn't too bad, it still makes some sense (there is presumably no content at all on the target page).

Cucumber Strange Behaviour

While using cucumber for BDD, i have found a very strange scenario where my "I should see" method (default implementation is failling).
Here is my scenario definition:
When I go to signup page
And I fill in "Username" with "ben#test.com"
And I press "Sign up"
Then I should see "Anything that i type here. ABC XYZ"
Obviously, the text "Anything that i type here. ABC XYZ" is not on the page but the cucumber wouldnt fail the scenario. Here is the definition of "I should see"
Then /^(?:|I )should see "([^"]*)"$/ do |text|
if page.respond_to? :should
page.should have_content(text)
else
assert page.has_content?(text)
end
end
A bit more digging, and it seems that the problem is that 1.8.7 is not supported in capybara. Instead of complaining loudly, it simply performs badly. Things like filling in forms work etc but the has_content fails miserably. Maybe it would be better if it shouted loudly that it needed 1.9.x.
Anyway I changed my Gemfile to
gem "capybara", "1.1.4", :group => :test
and it all seems to be working again.
Should I log this as an issue against capybara? The idea would be to just scream that it wont work with 1.8.7.
More on this discussion: https://groups.google.com/forum/?fromgroups=#!topic/cukes/B3UbbyG5k6s

Easiest way to get basic integration coverage in rails?

I'm taking over an application. It has no testing.
I'm looking for the bare minimum integration testing I can start with to have at least something to yell at me if I break something.
I was thinking:
Load small sql dump
Given a list of URL
Request URL and ensure a successful response
Searching for something like this has been fruitless.
Any pointers to something like this?
Or, how would you implement something like this quick 'n dirty to get beginning coverage?
I used basic rspec integration testing:
# login factories, etc
context "Login" do
it "works" do
visit '/'
page.should have_content "Login: "
fill_in 'login', :with => #user.login
click_button 'Login'
page.should have_content #user.name
end
end
By creating the integration test, it forced me to make the necessary factories, so I could get an idea of the coupling for each page. Bonus: it made it easier to split the models up later when I added unit testing.

Resources