Watir WebDriver as a test automation tool

    A recent article about WebDriver reminded me a little about the complex we use to automate testing Web applications.

    So, the tests are based on the RSpec + Watir WebDriver bundle (for Rails applications, it would be more appropriate to look towards Capybara). With the support of Bundler and local WebDrivers, an easy installation is performed on the tester's workplace (install Ruby 1.9, Rubygems, Bundler, and run bundle install). Gemfile source:

    source :rubygems
    gem "watir-webdriver", "~>0.6.1"
    gem "rspec-core", "~> 2.0"
    gem "rspec-expectations", "~> 2.0"
    gem "rr", "~> 1.0"
    gem "ci_reporter", "~> 1.7"
    


    Due to the ci_reporter gem, integration with Jenkins CI is carried out, and due to the parallel_tests gem and Selenium Grid, parallelization of tests is performed (today parallel tests are not used in production yet).

    Here is a test example:

    describe "FirstSite" do
      before(:all) do
        site! "first"
      end
      # returns true on success; otherwise false.
      def login_as(data)
        browser.rel_goto "/"
        browser.title.should include 'example.com'
        browser.text_field(:id => 'login').set data[:login]
        browser.text_field(:id => 'password').set data[:password]
        submit_button = browser.button(:id => 'submit')
        submit_button.click
        browser.url =~ %r{/welcome$}
      end
      def logout
        browser.rel_goto "/"
        browser.button(:id => 'logout').click
      end
      describe :login do
        auth = fixture :auth
        describe :successful do
          after(:each) do
            logout
          end
          auth.keys.select { |key| key.kind_of?(Symbol) }.each do |key|
            next  if key == :wrong
            it "Logging in as #{key} should be OK" do
              login_as(auth[key]).should be_true
            end
          end
        end
        describe :wrong do
          it "Logging in with wrong credentials should fail" do
            login_as(auth[:wrong]).should_not be_true
          end
        end
      end
    end
    


    The sites under test and the testing method are defined in the settings.
    ---
    production:
      sites:
        first: "http://staging.example.com"
      webdriver:
        hub: "http://192.168.13.6:8888/wd/hub"
    test:
      sites:
        first: "http://staging.example.com"
      webdriver:
        hub: "http://192.168.13.6:8888/wd/hub"
    development:
      sites:
        first: "localhost:5678"
      webdriver:
        local: true
    


    By setting the environment variables WATIR_ENV and WATIR_BROWSER, we define the testing environment for a particular test run.

    All customization is performed by two files. .rspec: spec_helper.rb:

    --format nested
    --color
    --require ./spec_helper.rb




    require "rubygems"
    require "bundler/setup"
    require "yaml"
    require "watir-webdriver"
    require "rspec/core"
    $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib') # для различных библиотек.
    module RegruHelpers
      include Selenium
      def site!(site)
          RSpec.configuration.site = RSpec.configuration.sites[site]
      end
      def fixture(name)
        RegruHelpers.symbolized YAML.load_file(
          File.join(File.dirname(__FILE__), 'fixtures', "#{name}.yml")
        )
      end
      def screenshot!(text = '')
        directory = File.join(File.dirname(__FILE__), 'spec', 'screenshots')
        file_name = "#{example.metadata.full_description}-#{text}.png"
        file_path =File.join(directory, file_name)
        browser.screenshot.save file_path
      end
      def save_html!(text = '')
        directory = File.join(File.dirname(__FILE__), 'spec', 'html')
        file_name = "#{example.metadata.full_description}-#{text}.html"
        file_path =File.join(directory, file_name)
        File.open(file_path, "w") do |f|
          f.print browser.html
        end
      end
      Watir::Browser.class_eval do
        def rel_goto url
          goto "#{RSpec.configuration.site}#{url}"
        end
      end
      def browser
        RSpec.configuration.browser ||= begin
          local = RSpec.configuration.watir_settings[:webdriver][:local]
          if local
            Watir::Browser.new(RSpec.configuration.browser_type)
          else
            capabilities = WebDriver::Remote::Capabilities.send(
              RSpec.configuration.browser_type,
              :javascript_enabled => true
            )
            Watir::Browser.new(
              :remote, 
              :url => RSpec.configuration.watir_settings[:webdriver][:hub], 
              :desired_capabilities => capabilities
            )
          end
        end
      end
    end  
    RSpec.configure do |config|
      config.mock_with :rr
      config.add_setting :watir_settings
      config.add_setting :browser_type
      config.add_setting :sites
      config.add_setting :site
      config.add_setting :browser
      config.include RegruHelpers
      config.extend RegruHelpers
      environment = ENV['WATIR_ENV'] || 'test'
      browser_type = (ENV['WATIR_BROWSER'] || 'chrome').to_sym
      watir_settings = RegruHelpers.symbolized YAML.load_file(File.join(File.dirname(__FILE__), 'settings.yml'))[environment]
      RSpec.configuration.watir_settings = watir_settings
      RSpec.configuration.sites = watir_settings[:sites]
      RSpec.configuration.site = watir_settings[:sites]['first']
      RSpec.configuration.browser_type = browser_type
      config.after(:suite) do
        unless RSpec.configuration.browser.nil?
          RSpec.configuration.browser.close
          RSpec.configuration.browser = nil
        end
      end
      config.after(:each) do
        if example.exception
          screenshot!('after')
          save_html!('after')
        end
      end
      def self.symbolized(hash)
        r = hash.dup
        hash.each_pair do |k, v|
          if k.kind_of?(String)
            if v.kind_of?(Hash)
              v = symbolized v
            end
            r[k.to_sym] = v
          end
        end
        r
      end
    end
    

    Also popular now: