Skip to content

Instantly share code, notes, and snippets.

@Juraci
Last active August 29, 2015 13:56
Show Gist options
  • Save Juraci/8849035 to your computer and use it in GitHub Desktop.
Save Juraci/8849035 to your computer and use it in GitHub Desktop.
Page Object Standards 1# - Avoid long procedures inside the page objects
# Here is an example of procedures that should be avoided inside the page objects
it "can create the server" do
server = DataSetup::Servers::Server.new(server_name)
server_details_view = server_list_view.create_server(server)
# ^ this create_server method above is hiding the flow of the test inside the page object
server_details_view.info_section.wait_to_load
server_details_view.root_admin_password_modal_exist.should be_true
server_details_view.server_name.should == server_name
server_details_view.info_section.image_name.should include(server.image)
server_details_view.info_section.flavor_name.should == '512MB Standard Instance'
server_details_view.info_section.disk_config.should == 'Automatic'
server_details_view.info_section.region.should include(server.region)
end
# look at the method implementation bellow
# it starts in the list_view, calls a method inside CreateView
module Servers
class SshKeyListView < Base::Pages::View
def create_server(server)
create_server_view = go_create_server
create_server_view.create_server(server)
PageObjects::Servers::DetailsView.new @selenium
end
end
end
# it ends up in a procedural set of actions inside the create view, full of conditionals
def fill_information_from_server(server)
region = server.region
type_server_name(server.name)
select_region(region)
if image_table.displayed?
select_image(server.image)
else
select_image_from_cascade_widget(server.image_description)
end
if size_table.displayed?
select_size(server.size)
else
select_flavor_from_flavor_panel(server.flavor_class, server.size)
end
if not server.first_gen?
modify_network("PublicNet", server.hasPublicNet?)
end
if disk_config_selector_shown?
select_disk_config(server.disk_config)
end
if ssh_key_section_shown? && !server.ssh_key.nil?
select_ssh_key(server.ssh_key)
end
end
# Why this should be avoided?
# Here are the arguments
# 1 - this method has basically 2 code smells
# Long method code smell:
## this method is breaking the single responsibility principle
## creating a server has lots of behavior that cannot fit in one method
## it's also doing several actions in a procedural way. Long methods are hard to maintain.
# Spaghetti code smell:
## Not all servers are created in the same way
## That is why there is so many conditionals inside this method like region based conditions.
# 2 - it is bad for the test readability
## because it hides part of the flow of the test inside this method
## which makes it hard to know what this test is really doing just by reading it
## What if I need to create several servers in my tests, this would be too much code repetition right?
## That is why UiSetup is for so you can abstract repetitive procedures there
## while keeping the page objects clean and simple.
# Just to recap
# Page object should be only an interface between the tests and the web elements
# The flow of actions must belong to the test body not to the page objects
# If a given procedure must be used several times you should abstract it on UiSetup
# The page objects should be like a box of building blocks;
# you can select just the pieces you need and assemble them in unanticipated ways (the tests)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment