Capybara::UI gives you page objects to help make your acceptance tests readable and resilient.
Page objects are Ruby objects that encapsulate any given page in your application.
A Capybara::UI page defines methods to describe a user's interactions with that page.
module UI class LoginPage < Capybara::UI path "/session/new" def log_in(email, password) self.email = email self.password = password submit end def email=(email) fill_in("Email", with: email) end def email find_field("Email").value end def password=(password) fill_in("Password", with: password) end def password find_field("Password").value end def submit click_button("Log In") end end end
Why Page Objects?
It's helpful to define these interactions in one place so that when the underlying page changes (and it will), you can update this one class rather than finding and updating tests scattered throughout your suite. Well-written page objects make your acceptance tests more resilient to change.
A Capybara::UI page has a
path directive to define when that particular page should be used. When the path of the Capybara session matches, the Capybara::UI will be applied.
Capybara::UI can be used anywhere you use Capybara. Using the login page described above, we can refactor the following test:
feature "Login" do scenario "A user can log in with the correct email and password." do user = create(:user, email: "firstname.lastname@example.org", password: "secret") visit(login_path) fill_in("Email", with: "email@example.com") fill_in("Password", with: "secret") click_button("Log In") expect(current_path).to eq(account_path) end end
feature "Login" do scenario "A user can log in with the correct email and password." do user = create(:user, email: "firstname.lastname@example.org", password: "secret") visit(login_path) ui.log_in("email@example.com", "secret") expect(current_path).to eq(account_path) end end
The current Capybara::UI page is available at
ui in your tests and is automatically reloaded to reflect the appropriate page whenever a new page loads.
Capybara::UI is able to automatically reload when appropriate for the following Capybara drivers:
For other Capybara drivers, you can manually reload the UI:
visit(login_path) ui.reload ui.log_in("firstname.lastname@example.org", "secret")
Even better, please submit a pull request to include automatic reload for your favorite Capybara driver.