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: [email protected] -> 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&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(&:join)