I am attempting to run integration tests on Rails using RSpec Capybara and selenium-chrome driver.
I am also using the capybara-angular gem.
I'm a little confused about exactly whats going on as I don't see my scripts when I sleep my rspec test inspect the the sources tab in the chrome debugger it doesn't seem like my assets are loaded, although it does appear that the ng-if statements are working as the page is hidden.
So I'm not quite sure what's going on. The page works as expected in development, but variables on the $scope are not set in test.
This my set up in "system.rb
RSpec.configure do |config|
config.before(:each, type: :system) do
driven_by :rack_test
end
config.before(:each, type: :system, js: true) do
driven_by :selenium_chrome
end
end
require "capybara-screenshot/rspec"
include Capybara::Angular::DSL
Here is the test I am running:
it "shows changes to the budget when the budget is changed", :js do
visit(root_path)
sleep 0.5
fill_in "inputEmail", with: "[email protected]"
fill_in "password", with: "test"
click_on("Log In")
sleep 0.25
click_on("Budgeting")
sleep 10
expect(page).to have_selector("#current_project_name", text: "Project A")
expect(page).to have_selector("#budgetInput1")
fill_in "#budgetInput1", with: "100"
# Fail on next line with 'expected to find visible css "#budgetInput1" but there were no matches'
page.should have_selector("#budgetInput1", text: "100") # <--test fails with
end
From what I can tell, the reason it is not found is because the element appears in a div with ng-if="showBudget". $scope.showBudget=true is set in the controller, but the controller doesn't appear to be loading and {{showBudget==unknown}} returns true, which suggests that AngularJS is loading but the scripts loaded by the manifest for the page are not.
How to fix this?
It looks like you're not using the correct expectation. Since you're able to call
fill_inon the element with idbudgetInput1then expecting (not sure why you're mixingexpectandshouldsyntax) with thetextoption isn't going to work. What you probably want isIf instead you're expecting the
fill_into trigger an update on the page that replaces the input element with id 'budgetInput1' with a different element, then you probably need to be sending an enter, a tab, or clicking outside the initial element to trigger the change.On another note, I'm not sure why you have the sleeps in your test -
fill_inwill wait for the matching element to exist, so there really should be no need to sleep half a second after calling visit -- For the 10 second sleep (does your app really take 10 seconds to respond???) you could just use the wait option onexpect(page).to have_selector("#current_project_name", text: "Project A", wait: 10)instead so that the test continues as soon as the element exists, rather than waiting all 10 seconds if it's not necessary.