Guest Post: Designing a Ruby-based Sauce Test Automation Framework Pt. 3

In the first part of this blog series, we defined Page Object Pattern and also familiarized ourselves with the various building blocks of the Ruby-based test automation framework.

We then familiarized ourselves on implementing a Simple Test Framework on Ruby using Page Object Pattern.

Let’s now look at building a test project in Ruby using this framework and try executing it on Sauce Labs.

Building a Test Project

Now that we have finished implementing the framework base classes in Ruby, we are going to use these framework classes in a simple Test project.

When using this framework in an actual project, it would be a good idea to separate the framework base classes and make them into a gem. This allows multiple project teams to reuse the framework classes and at the same time allows centralized version control of the framework base classes.

In our test project, Project level Test Base classes will extend the Framework Base classes. This will allow project teams to override and specify project specific actions and configurations in Project Base Classes.

project_test_base.rb

  • This class also extends the Selenium Test Base class and handles project level common setup steps, teardown steps and action initialization steps for tests.
  • In addition, this class also calls and initializes the Actions and Pages required to carry out the tests. As we discussed, in the Page Object pattern, each Test class will create Pages through individual instances and the Actions that are needed to execute the test case. Accordingly, this Project Test Base will create the most commonly used Action classes in the project through individual instances. In this case, we are creating the Simple Form Actions from within the Project Test Base itself.
# project_action_base.rb
# (Note: require_relative has been used assuming that all files would be stored in the same folder)

require_relative 'selenium_test_base'
require_relative 'simple_form_actions'
require_relative 'simple_form_page'

class ProjectTestBase   < SeleniumTestBase
  def initialize(webDriver)
    super(webDriver)
  end

  def create_actions(webDriver)
    @form_actions = SimpleFormActions.new(webDriver)
  end

  def create_pages(webDriver)
    #code to create the respective page instance
  end

  def  setup_test_fixture()
  end

  def setup
    webDriver = start_browser("firefox")
    create_actions(webDriver)
    launch_url("http://saucelabs.com/test/guinea-pig")
  end
end

This class extends the Selenium Action Base class. The Project Action Base class also creates Page objects required to execute the test.

# simple_form_actions.rb
require_relative 'selenium_action_base'

class ProjectActionBase < SeleniumActionBase
  def initialize(webdriver)
    super(webdriver)
    @form_page = SimpleFormPage.new(webdriver)
  end

end

This Action class extends the Project Action Base and performs actions on the Simple Form page for executing the tests. As we will see later, this Action class will be later called by the Simple Form Test class to perform these actions on the Simple Form Page.

# simple_form_page.rb
require_relative 'project_action_base'

class SimpleFormActions < ProjectActionBase
  def initialize(webDriver)
    @driver = webDriver
    @form = SimpleFormPage.new(@driver)
  end

  def attempt_submit( email,comments,isValid = nil)
    @form.comment_field(comments)
    @form.email_field(email)
    @form.submit()
  end
end

Defines the page elements on the SimpleFormPage and manages the interactions within such specific page elements.

# simple_form_tests.rb
require_relative 'selenium_page_base'
require_relative 'selenium_page_element'

class SimpleFormPage < SeleniumPageBase
  def initialize(webdriver)
    super(webdriver)
    @page_element = SeleniumPageElement.new(webdriver)
  end

  def email_field(value)
    @page_element.load_element('fbemail',value)
  end

  def comment_field(value)
    @page_element.load_element('comments',value)
  end

  def submit
    @page_element.submit
  end

  def read_response
    #removing element ID explicitly using slice
    @page_element.get_response().text.slice "Ruby Selenium framework runs on sauce labs"
  end
end

SimpleFormTests is the first test case class that we are creating. Since we are using RSpec to perform the assertions, this test class limits itself with just executing the test actions.

# project_test_base_spec.rb
require_relative 'project_test_base'

class SimpleFormTests < ProjectTestBase
  def initialize(webDriver)
    super(webDriver)
  end

  def get_page_title
    @driver.title
  end

  def successful_form_submit
    @form_actions.attempt_submit("email@welcome.com", "Ruby Selenium framework runs on sauce labs", true)
  end
end

This is where the real test assertions happen. The RSpec creates Test objects and performs the Test Assertions.

require_relative "project_test_base"
require_relative "simple_form_tests"

describe SimpleFormTests, "#testing simple form submit on selenium saucelabs environment" do
  before(:all) do
    @simple_form = SimpleFormTests.new('webDriver')
    @simple_form.setup
  end

  it "returns page title of the website" do
    @simple_form.get_page_title.should eql("I am a page title - Sauce Labs")
  end

  it "should render comment on sucessful form submit" do
    @simple_form.successful_form_submit.should eql("Ruby Selenium framework runs on sauce labs")
  end

  after(:all) do
    @simple_form.teardown
  end
end

The framework provides the advantages of Ruby. The framework is re-usable and easily maintainable in the long run. This framework would help QA professionals save time and effort. It could also result in cost savings for organizations.

This guest post was written by Vinodh Balaji Sridharan and Ganesh Kaliannan, Neev Technologies.

Written by

Bill McGee

Topics

FrameworksAutomated testing