Page Object Model gem for ruby Page Objects are like react-components for integration spec code. They let you componentize pages or parts of pages so you don't use css-selectors every where.
If you have page.find('button', text: 'update section')
in a lot of tests, when the PM says it should be 'Change Section' you have a lot of changes to make.
By sticking this in the page-object it limits the needed scope of change to just that POM and possible the one test that regression checked this.
Let you define elements on your page
class Login < SitePrism::Page
element :username, '#username'
element :password, '#password'
element :sign_in_button, 'button'
end
Then use it in your tests
@login = Login.new
@login.load
expect(@login).to have_username
@login.user_name.set '[email protected]'
@login.password.set 'password'
@login.sign_in_button.click
expect(@page).to have_content 'Thanks for signing in Sam'
capybara options like text just pass straight through.
class HeaderSection < SitePrism::Section
set_default_search_arguments '#header'
element :header_logo, 'div#logo'
element :courses, 'a', text: 'COURSES'
element :departments, 'a', text: 'DEPARTMENTS'
element :affordability, 'a', text: 'AFFORDABILITY'
element :users, 'a', text: 'USERS'
element :help, 'button', text: 'GET HELP'
end
# also possible to pass in line in test code
@page.courses(text: 'ACCT').click
You can break more complicated stuff into sections
class Menu < SitePrism::Section
element :search, 'a.search'
element :images, 'a.image-search'
element :maps, 'a.map-search'
end
class Home < SitePrism::Page
section :menu, Menu, '#gbx3'
end
Don't feel like you need to over-componentize though. - it doesn't need to be as scoped down as far as a react component would be. You can partition a page into sections, that repeat on the same page or across different pages: For example: Sections repeating on same page: search results, list of courses Sections repeating on different pages: header, menu, footer, facet navigation
Pages and sections are just ruby classes
- great place to put common methods that you might use a lot
class LogInPage < SitePrism::Page
set_url '/session/new'
element :login, 'div#login'
element :email_field, 'input[id="user_email"]'
element :password_field, 'input[id="user_password"]'
element :submit_button, 'button', text: 'LOGIN'
element :flash_message, 'div.alert'
def visit_and_login_as(email, password)
load
email_field.set email
password_field.set password
submit_button.click
wait_until_page_has_flash_message, text: 'Success'
page.has_content? 'div#menu'
end
end
# now in my test code I just
let(:user) { create(:user) }
before do
LoginPage.new.visit_and_login_as(user.email, 'password')
end
- Selectively assert on specific elements of a page or a section, based on the signed in user permisssions, feature flags and application state
- Organize and DRY test code
- Reduces integration fragility - uses the waiting functionality of capybara
- Improve test readability