问题
Here's my complete spec:
require 'spec_helper'
describe "Idea page", js: true do
subject { page }
before(:all) do
create(:idea)
visit root_path
click_link "Log In"
end
context "Single idea" do
before do
page.find(:xpath, '//*[@id="accordion"]/div/div[1]/a').click
end
it { should have_selector('a',text:'Claim') }
it "should have a button for reporting the idea"
it "should have a button for opening all links"
describe "Claiming" do
before do
click_link "Claim"
end
it {should have_selector('a', text:'Claimed')}
end
end
end
Without (:all)
(i.e, when it's just before
in the first block), the browser opens, clicks on the Login link, goes to the right page, and clicks on the link. Nice.
But then it does it all over again before it tries clicking the second link ("Claim"), which is both time-consuming and error-prone. So I tried to fix this with before(:all)
.
But now, it just pops open Firefox, waits for a moment, and closes it again without doing anything. Test fails say:
Failures:
1) Idea page Single idea
Failure/Error: page.find(:xpath, '//*[@id="accordion"]/div/div[1]/a').click
Capybara::ElementNotFound:
Unable to find xpath "//*[@id=\"accordion\"]/div/div[1]/a"
# ./spec/features/ideas_spec.rb:15:in `block (3 levels) in <top (required)>'
2) Idea page Single idea Claiming
Failure/Error: page.find(:xpath, '//*[@id="accordion"]/div/div[1]/a').click
Capybara::ElementNotFound:
Unable to find xpath "//*[@id=\"accordion\"]/div/div[1]/a"
# ./spec/features/ideas_spec.rb:15:in `block (3 levels) in <top (required)>'
Obviously, since the browser page was blank.
What am I missing? Thank you.
Edit: Maybe there's something basic I don't understand. With before(:each)
here's what the test tries to do:
1) Log in to the webapp, make sure there's a 'Claim' button.
2) Log in to the webapp again, open the accordion again, and now click that 'Claim` button to see what's going to happen.
So the beginning of every step is exactly the same, the browser doing the same thing again and again. Is that how it's supposed to be?
If so, why do I get errors when I do this? Specifically, with before(:each)
I get this:
Failures:
1) Idea page Single idea Claiming
Failure/Error: it {should have_selector('a', text:'Claimed')}
Selenium::WebDriver::Error::UnhandledAlertError:
Modal dialog present
# [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/command_processor.js:10287:in `nsCommandProcessor.execute'
# [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/driver_component.js:7328:in `Dispatcher.executeAs/<'
# [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/driver_component.js:7488:in `Resource.handle'
# [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/driver_component.js:7435:in `Dispatcher.dispatch'
# [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/driver_component.js:10119:in `WebDriverServer/<.handle'
# [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:1935:in `unknown'
# [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:2261:in `ServerHandler.handleResponse'
# [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:1168:in `Connection.process'
# [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:1616:in `RequestReader._handleResponse'
# [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:1464:in `RequestReader._processBody'
# [remote server] file:///tmp/webdriver-profile20130116-3734-lw7267/extensions/fxdriver@googlecode.com/components/httpd.js:1333:in `RequestReader.onInputStreamReady'
# ./spec/features/ideas_spec.rb:26:in `block (4 levels) in <top (required)>'
Even though I see the browser clicking the button, turning it to "Claimed", and there is no modal dialog shown.
Edit 2: I stand corrected! There was a modal dialog there after all! I fixed the JS to stop showing it, and the test now passes. I still think it's weird that the framework has to repeat the whole sequence from scratch every step (seems like a waste of work), but whatever. Thank you!
回答1:
This is because the test data, including the capybara session data (such as logged-in state) and the model created by create(:idea)
are wiped out between specs.
You want to go with before(:each)
not :all
, even though it is more time consuming.
来源:https://stackoverflow.com/questions/14364879/capybara-and-beforeall-in-rspec