Selenium and Ruby

Applies to CrossBrowserTesting SaaS, last modified on October 07, 2021

Selenium and Ruby

Whether you are new to writing automated tests with Selenium, or you are trying to make appropriate changes to your current tests so you can use our service, CrossBrowserTesting tries to make things as easy as possible.

To get started, we need to ensure some necessary dependencies are installed. Doing so is easy with Gem. We will be using Selenium for sure, so let us get that installed:

gem install selenium-webdriver

We also recommend using the gem, "Rest-Client" for making Restful API calls:

gem install rest-client

Lastly, we recommend installing test-unit for creating unit tests:

gem install test-unit

Now, we can get started! Copy the following script into your favorite text-editor:

require "selenium-webdriver"
require "rest-client"
require "test-unit"

class BasicTest < Test::Unit::TestCase
    def test_basic_test
        begin

            #Note that your email address in the username uses an encoded "@" (%40)

            username = 'you%40yourdomain.com'
            authkey = 'yourauthkey'

            # Defining capabilities of the test session, such as browser, OS, and resolution
            caps = Selenium::WebDriver::Remote::Capabilities.new
            caps["name"] = "Basic Example" # A name for your test
            caps["build"] = "1.0" #Versioning data for your site or application as you test
            caps["browser_api_name"] = "Safari10" #You can get a full list of browser, OS, and resolution combinations from our API
            caps["os_api_name"] = "Mac10.12"
            caps["screen_resolution"] = "1024x768"
            caps["record_video"] = "false"
            caps["record_network"] = "false"

            driver = Selenium::WebDriver.for(:remote, :url => "http://#{username}:#{authkey}@hub.crossbrowsertesting.com:80/wd/hub", :desired_capabilities => caps)

            session_id = driver.session_id

            score = "pass"
            cbt_api = CBT_API.new
            # maximize the window - DESKTOPS ONLY
            # driver.manage.window.maximize

            puts "Loading URL"
            driver.navigate.to("http://crossbrowsertesting.github.io/selenium_example_page.html")

            expected_title = "Selenium Test Example Page"

            puts "Grabbing title"
            actual_title = driver.title

            # we'll assert that the title is what we want
            assert_equal(expected_title, actual_title)

            puts "Taking Snapshot"
            cbt_api.getSnapshot(session_id)
            cbt_api.setScore(session_id, "pass")

        rescue Exception => ex
            puts ("#{ex.class}: #{ex.message}")
            cbt_api.setScore(session_id, "fail")
        ensure # this is a good practice to get into so that the driver will always exit, even if there is an error
            driver.quit
        end
    end
end


# Create a CBT_API object that will allow us a standardized, DRY way to set scores, add descriptions, and get snapshots of tests.
class CBT_API
    @@username = 'you%40yourdomain.com'
    @@authkey = 'yourauthkey'
    @@BaseUrl = "https://#{@@username}:#{@@authkey}@crossbrowsertesting.com/api/v3"
    def getSnapshot(sessionId)
        # this returns the the snapshot's "hash" which is used in the
        # setDescription function
        response = RestClient.post(@@BaseUrl + "/selenium/#{sessionId}/snapshots",
            "selenium_test_id=#{sessionId}")
        snapshotHash = /(?<="hash": ")((\w|\d)*)/.match(response)[0]
        return snapshotHash
    end

    def setDescription(sessionId, snapshotHash, description)
        response = RestClient.put(@@BaseUrl + "/selenium/#{sessionId}/snapshots/#{snapshotHash}",
            "description=#{description}")
    end

    def setScore(sessionId, score)
        # valid scores are 'pass', 'fail', and 'unset'
        response = RestClient.put(@@BaseUrl + "/selenium/#{sessionId}",
            "action=set_score&score=#{score}")
    end
end

Save it as a Ruby script, and we can now run our first test. If you have the app open as well, navigate to the Selenium section of our site to watch this test run.

RemoteWebDrivers are instantiated by providing a capabilities object as the second argument in the constructor. As you can see, the capabilities match up with our OS/Device/Browser configurations, and you can provide boolean values that tell us whether we should record video, take a snapshot, or record network traffic, as well as give your test a name (such as "Login Form Test") and a build (such as "1.0").

We created a CBT_API object that allows us to set the score, take a snapshot, and set the description just by interacting with the object. This becomes increasingly useful as you begin to develop your own tests, as it allows you to maintain clean, DRY that is easy to interact with and update.

Once all of our assertions have been run, we set the pass/fail score of the test and tell the webdriver to quit. By using the "ensure" statement in the example code, we are able to guarantee that the driver has exited at the end of the test, regardless of pass or fail, or if there were any exceptions. This will prevent issues regarding parallel automated tests.

As always, if you need any help getting your tests working successfully, you can always get in touch with us by email. We are always happy to help.

Run tests in parallel

To speed your automated testing, you can run your tests in parallel, making use of several browsers or devices at one time.

require "selenium-webdriver"
require "rest-client"

#Note that your email address in the username uses an encoded "@" (%40)\
#EX: example@crossbrowsertesting.com -> example%40crossbrowsertesting.com
$username = 'your email'
$authkey = 'your authkey'

browsers = [
  {"os_api_name": "Win7x64-C2", "browser_api_name": "IE10", "name": "Ruby Parallel"},
  {"os_api_name": "Win8.1", "browser_api_name": "Chrome43x64", "name": "Ruby Parallel"},
  {"os_api_name": "Win10", "browser_api_name": "Chrome69x64", "name": "Ruby Parallel"},
  {"os_api_name": "Mac10.12", "browser_api_name": "Chrome59x64", "name": "Ruby Parallel"}
]

# Create a CBT_API object that will allow us a standardized, DRY way to set scores, add descriptions, and get snapshots of tests.
class CBT_API

    @@BaseUrl = "https://#{$username}:#{$authkey}@crossbrowsertesting.com/api/v3"
    def getSnapshot(sessionId)
        # this returns the the snapshot's "hash" which is used in the
        # setDescription function
        response = RestClient.post(@@BaseUrl + "/selenium/#{sessionId}/snapshots",
            "selenium_test_id=#{sessionId}")
        snapshotHash = /(?<="hash": ")((\w|\d)*)/.match(response)[0]
        return snapshotHash
    end

    def setDescription(sessionId, snapshotHash, description)
        response = RestClient.put(@@BaseUrl + "/selenium/#{sessionId}/snapshots/#{snapshotHash}",
            "description=#{description}")
    end

    def setScore(sessionId, score)
        # valid scores are 'pass', 'fail', and 'unset'
        response = RestClient.put(@@BaseUrl + "/selenium/#{sessionId}",
            "action=set_score&#038;score=#{score}")
    end
end


def test_basic_test(browser)
    puts browser

    caps = browser
    begin
        driver = Selenium::WebDriver.for(:remote, :url => "http://#{$username}:#{$authkey}@hub.crossbrowsertesting.com:80/wd/hub", :desired_capabilities => caps)

        session_id = driver.session_id

        score = "pass"
        cbt_api = CBT_API.new
        # maximize the window - DESKTOPS ONLY
        # driver.manage.window.maximize

        puts browser[:os_api_name] + ": Loading URL"
        driver.navigate.to("http://crossbrowsertesting.github.io/selenium_example_page.html")

        expected_title = "Selenium Test Example Page"

        puts browser[:os_api_name] + ": Grabbing title"
        actual_title = driver.title

        puts browser[:os_api_name] + ": Taking Snapshot"
        cbt_api.getSnapshot(session_id)
        cbt_api.setScore(session_id, "pass")

        driver.quit()
    end

    rescue
        cbt_api.setScore(session_id, "fail")
        driver.quit()

end


threads = []

(0..browsers.length-1).each do | thread_no |
    threads << Thread.new { test_basic_test(browsers[thread_no]) }
end

threads.each(&#038;:join)

See Also

Watir

Highlight search results