Sauce Labs now supports the featured in Selenium versions 3.11 and higher. This article will help ensure that your tests are W3C WebDriver-compliant and can successfully execute on Sauce Labs.
achieved the W3C standard level as the automation protocol for web browsers.
See the following sections for more information:
Sauce Labs Web Protocol Support
Browser | W3C Support | JWP Support |
---|
Chrome | 75 and above | Still supported |
Firefox | 55 and above | Still supported |
Safari | 12 and above | Removed in 12.1 |
Edge | All | Still supported |
Internet Explorer | All | Still supported |
What You'll Need
- se Selenium version 3.11 or higher.
Switch completely from using legacy JWP desired capabilities to the new W3C WebDriver capabilities. Note that their naming conventions are slightly different – for example:
JWP (legacy) | W3C (new) |
---|
platform | platformName |
version | browserVersion |
For more information on W3C WebDriver-compliant capabilities, head to the official W3C recommendation website.
Include our custom sauce:options
capabilities (e.g., name
, build
) in your Sauce Labs test scripts, bundled together, as seen in this example:
browserName: 'firefox',
platformName: 'macOS 10.15',
browserVersion: 'latest'
sauce:options: {
name: 'My test name',
build: 'My build',
username: "SAUCE_USERNAME",
accessKey: "SAUCE_ACCESS_KEY"
seleniumVersion: "3.141.59"
}
Click here to see a full list of sauce:options capabilities
accessKey appiumVersion avoidProxy build captureHtml chromedriverVersion commandTimeout crmuxdriverVersion
customData disablePopupHandler extendedDebugging
firefoxAdapterVersion
firefoxProfileUrl idleTimeout iedriverVersion maxDuration name parentTunnel
| passed prerun preventRequeue priority proxyHost public recordLogs recordScreenshots recordVideo restrictedPublicInfo screenResolution seleniumVersion source tags timeZone tunnelIdentifier username videoUploadOnPass
|
More information: Test Configuration Options.
Getting Started
Below are a couple of mobile and web test script examples you can use to get up and running quickly:
wdio.saucelabs.conf.js (source from Sauce Labs Training JavaScript)
config.capabilities = [
{
// For the W3C capabilities, please check
// https://www.w3.org/TR/webdriver1/#capabilities
browserName: 'chrome',
platformName: 'Windows 10',
browserVersion: 'latest',
// All vendor specific, in this case Sauce specific capabilities, should be
// put in vendor prefixed options, see
// https://www.w3.org/TR/webdriver1/#dfn-extension-capability
'sauce:options': {
build: `Sauce Labs W3C Desktop build-${new Date().getTime()}`,
screenResolution: '1440x900'
},
},
];
config.services = config.services.concat('sauce');
exports.config = config;
wdio.saucelabs.conf.js (source from Sauce Labs Training JavaScript)
config.capabilities = [
/**
* Android
*/
{
// All vendor specific, in this case Appium capabilities, should be
// put in vendor prefixed options, see
// https://www.w3.org/TR/webdriver1/#dfn-extension-capability
// All Appium capabilities, see
// http://appium.io/docs/en/writing-running-appium/caps/
// should be prefixed with `appium:{capability-name}`
'appium:deviceName': 'Google Pixel 3 GoogleAPI Emulator',
'appium:platformVersion': '10.0',
// For the W3C capabilities, please check
// https://www.w3.org/TR/webdriver1/#capabilities
browserName: 'chrome',
platformName: 'Android',
// All vendor specific, in this case Sauce specific capabilities, should be
// put in vendor prefixed options, see
// https://www.w3.org/TR/webdriver1/#dfn-extension-capability
'sauce:options': {
build: `Sauce Labs W3C Mobile Web build-${new Date().getTime()}`,
appiumVersion: '1.18.1'
},
},
/**
* iOS
*/
{
// All vendor specific, in this case Appium capabilities, should be
// put in vendor prefixed options, see
// https://www.w3.org/TR/webdriver1/#dfn-extension-capability
// All Appium capabilities, see
// http://appium.io/docs/en/writing-running-appium/caps/
// should be prefixed with `appium:{capability-name}`
'appium:deviceName': 'iPhone 11 Simulator',
'appium:platformVersion': '14.0',
// For the W3C capabilities, please check
// https://www.w3.org/TR/webdriver1/#capabilities
browserName: 'safari',
platformName: 'iOS',
// All vendor specific, in this case Sauce specific capabilities, should be
// put in vendor prefixed options, see
// https://www.w3.org/TR/webdriver1/#dfn-extension-capability
'sauce:options': {
build: `Sauce Labs W3C Mobile Web build-${new Date().getTime()}`,
appiumVersion: '1.19.1'
},
},
];
config.services = config.services.concat('sauce');
exports.config = config;
W3C WebDriver Browser Compatibility
The following browser versions are compatible with the W3C WebDriver protocol:
- Firefox version 53 and higher
- Google Chrome version 61 and higher
- Internet Explorer 11
By default, Sauce Labs uses older versions of Firefox, IE, and Safari. This is important to know since newer commands and configurations may not be supported in those versions.
For tests on Google Chrome versions 74 and lower, the W3C WebDriver capability must be set as an experimental option. ChromeDriver version 75 runs in W3C WebDriver standard compliant mode by default, so setting this capability won't be necessary in the future. Here's an example:
ChromeOptions chOpts = new ChromeOptions();
chOpts.setExperimentalOption("w3c", true);
NOTE: w3c
must be set as a boolean value (e.g., true
in Java and True
in Python) – not a string (e.g., "true").
Verifying Capabilities for W3C WebDriver Compliance
Here's how to verify if your tests are running under the new W3C WebDriver protocol:
- Go to the Test Details page for your test in Sauce Labs.
- Click the Commands tab.
- Select the first
Post
command, which will be Post /session
. - Under the
Parameters
section, check the capabilities that are used in the test.
- If your
Parameters
section begins with capabilities
, you're running the new W3C WebDriver-compliant version

- If it begins with
desiredCapabilities
, you're running the legacy, non-W3C WebDriver version
W3C WebDriver-Compliant Language Changes in Selenium 3.11+
There are some changes to specific Selenium language bindings you should be aware of when migrating to the W3C WebDriver protocol. Here is an:
In Selenium version 3.11 and higher, be sure to input the new DriverOptions()
class, which is used to manage options specific to each browser web driver.
Example: Selenium 3.11+, with DriverOptions()

FireFoxOptions mozOpts = new FirefoxOptions();
Example: Legacy, with DesiredCapabilities()

DesiredCapabilities caps = new DesiredCapabilities.firefox();
Using legacy formatting in Selenium 3.11+ script will yield the following message:
"INFO: Using `new FirefoxOptions()` is preferred to `DesiredCapabilities.firefox()"
You can now set capabilities using the MutableCapabilities()
class instead of using DesiredCapabilities()
.
MutableCapabilities()
is the preferred method; it implements all interfaces, including DriverOptions()
and DesiredCapabilities()
. For more information, see the DriverOptions class Selenium documentation.
These two Java snippets show a comparison between a legacy script and a version edited to use the new W3C WebDriver capabilities:
Example: Selenium 3.11+, with MutableCapabilities()
MutableCapabilities sauceCaps = new MutableCapabilities();
sauceCaps.setCapability("username", "someuser");
sauceCaps.setCapability("accessKey", "00000000-0000-0000-0000-000000000000");
sauceCaps.setCapability("name", "my test case");
MutableCapabilities caps = new MutableCapabilities();
caps.setCapability("sauce:options", sauceCaps);
caps.setCapability("platformName", "Windows 10");
caps.setCapability("browserName", "firefox");
caps.setCapability("browserVersion", "latest");
WebDriver driver = new RemoteWebDriver(new URL("https://ondemand.saucelabs.com/wd/hub"), caps);
Example: Legacy, with DesiredCapabilities()

DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("username", "someuser");
caps.setCapability("accessKey", "00000000-0000-0000-0000-000000000000");
caps.setCapability("name", "my test case");
caps.setCapability("browser", "firefox");
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "latest");
WebDriver driver = new RemoteWebDriver(new URL("https://ondemand.saucelabs.com/wd/hub"), caps);
with W3C WebDriver-Compliant Capabilities
Select a in the programming language of your choice, then follow the instructions. You can find more sample code in the Sauce Labs training repository on GitHub.
Click here to see the full example
TestNGW3CChromeTest.java (source from Sauce Labs Training Java)
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
public class TestNGW3CChromeTest {
protected WebDriver driver;
/**
* @BeforeMethod is a TestNG annotation that defines specific prerequisite test method behaviors.
In the example below we:
- Define Environment Variables for Sauce Credentials ("SAUCE_USERNAME" and "SAUCE_ACCESS_KEY")
- Define Chrome Options such as W3C protocol
- Define the "sauce:options" capabilities, indicated by the "sauceOpts" MutableCapability object
- Define the WebDriver capabilities, indicated by the "caps" DesiredCapabilities object
- Define the service URL for communicating with SauceLabs.com indicated by "sauceURL" string
- Set the URL to sauceURl
- Set the driver instance to a RemoteWebDriver
- Pass "url" and "caps" as parameters of the RemoteWebDriver
For more information visit the docs: http://static.javadoc.io/org.testng/testng/6.9.4/org/testng/annotations/BeforeMethod.html
*/
@BeforeMethod
public void setup(Method method) throws MalformedURLException {
String username = System.getenv("SAUCE_USERNAME");
String accessKey = System.getenv("SAUCE_ACCESS_KEY");
String methodName = method.getName();
/** The MutableCapabilities class is now the superclass for handling all option & capabilities implementations,
* including Selenium Browser Options classes (like ChromeOptions),
* and is required for Sauce Labs specific configurations
* For available options, see: https://wiki.saucelabs.com/display/DOCS/Test+Configuration+Options
*/
MutableCapabilities sauceOpts = new MutableCapabilities();
sauceOpts.setCapability("name", methodName);
sauceOpts.setCapability("username", username);
sauceOpts.setCapability("accessKey", accessKey);
sauceOpts.setCapability("tags", "w3c-chrome-tests");
/** DesiredCapabilities is being deprecated in favor of using Browser Options classes for everything.
* Browser Options support both standard w3c values (https://w3c.github.io/webdriver/#capabilities)
* as well as browser-specific values (https://chromedriver.chromium.org/capabilities)
* including behavior such as profile settings, mobile emulation, headless capabilities, insecure tls certs, etc.
*
* Sauce Configuration values can be addded directly to the browser options class
*/
ChromeOptions chromeOpts = new ChromeOptions();
chromeOpts.addArguments("user-data-dir=/path/to/your/custom/profile");
chromeOpts.setCapability("browserName", "googlechrome");
chromeOpts.setCapability("browserVersion", "latest");
chromeOpts.setCapability("platformName", "windows 10");
chromeOpts.setCapability("sauce:options", sauceOpts);
/**
* Finally, we pass our Browser Options instance as a parameter of our RemoteWebDriver constructor
*/
String sauceUrl = "https://ondemand.us-west-1.saucelabs.com/wd/hub";
URL url = new URL(sauceUrl);
driver = new RemoteWebDriver(url, chromeOpts);
}
/**
* @Test is a TestNG annotation that defines the actual test case, along with the test execution commands.
In the example below we:
- Navigate to our SUT (site under test), 'https://www.saucedemo.com'
- Store the current page title in a String called 'getTitle'
- Assert that the page title equals "Swag Labs"
For more information visit the docs: http://static.javadoc.io/org.testng/testng/6.9.4/org/testng/annotations/Test.html
*/
@Test
public void TestNGw3cChromeTest() throws AssertionError {
driver.navigate().to("https://www.saucedemo.com");
String getTitle = driver.getTitle();
Assert.assertEquals(getTitle, "Swag Labs");
}
/**
* @AfterMethod is a TestNG annotation that defines any postrequisite test method tasks .
In the example below we:
- Pass the ITestResult class results to a parameter called 'result'
- Use the JavascriptExecutor class to send our test 'result' to Sauce Labs with a "passed" flag
if the test was successful, or a "failed" flag if the test was unsuccessful.
- Teardown the RemoteWebDriver session with a 'driver.quit()' command so that the test VM doesn't hang.
For more information visit the docs: http://static.javadoc.io/org.testng/testng/6.9.4/org/testng/annotations/AfterMethod.html
*/
@AfterMethod
public void teardown(ITestResult result) {
((JavascriptExecutor)driver).executeScript("sauce:job-result=" + (result.isSuccess() ? "passed" : "failed"));
driver.quit();
}
}
TestNG Example Walkthrough
Download or clone the script from GitHub.
Ensure you have the prerequisite software.
Resolve any dependencies:
Export your Sauce Labs Username and Access Key:
export SAUCE_USERNAME=my-sauce-username
export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx
Run the following command:
$ mvn clean test -Dtest=TestNGW3CChromeTest
Click here to see the full example
JUnit5W3CChromeTest.java (source from Sauce Labs Training Java)
import org.junit.jupiter.api.*;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.MalformedURLException;
import java.net.URL;
public class JUnit5W3CChromeTest {
protected WebDriver driver;
public Boolean result;
/**
* @BeforeEach is a JUnit 5 annotation that defines specific prerequisite test method behaviors.
In the example below we:
- Define Environment Variables for Sauce Credentials ("SAUCE_USERNAME" and "SAUCE_ACCESS_KEY")
- Define Chrome Options such as W3C protocol
- Define the "sauce:options" capabilities, indicated by the "sauceOpts" MutableCapability object
- Define the WebDriver capabilities, indicated by the "caps" DesiredCapabilities object
- Define the service URL for communicating with SauceLabs.com indicated by "sauceURL" string
- Set the URL to sauceURl
- Set the driver instance to a RemoteWebDriver
- Pass "url" and "caps" as parameters of the RemoteWebDriver
For more information visit the docs: https://junit.org/junit5/docs/5.0.2/api/org/junit/jupiter/api/BeforeEach.html
*/
@BeforeEach
public void setup(TestInfo testInfo) throws MalformedURLException {
String username = System.getenv("SAUCE_USERNAME");
String accessKey = System.getenv("SAUCE_ACCESS_KEY");
String methodName = testInfo.getDisplayName();
/** The MutableCapabilities class is now the superclass for handling all option & capabilities implementations,
* including Selenium Browser Options classes (like ChromeOptions),
* and is required for Sauce Labs specific configurations
* For available options, see: https://wiki.saucelabs.com/display/DOCS/Test+Configuration+Options
*/
MutableCapabilities sauceOpts = new MutableCapabilities();
sauceOpts.setCapability("name", methodName);
sauceOpts.setCapability("username", username);
sauceOpts.setCapability("accessKey", accessKey);
sauceOpts.setCapability("tags", testInfo.getTags());
/** DesiredCapabilities is being deprecated in favor of using Browser Options classes for everything.
* Browser Options support both standard w3c values (https://w3c.github.io/webdriver/#capabilities)
* as well as browser-specific values (https://chromedriver.chromium.org/capabilities)
* including behavior such as profile settings, mobile emulation, headless capabilities, insecure tls certs, etc.
*
* Sauce Configuration values can be addded directly to the browser options class
*/
ChromeOptions chromeOpts = new ChromeOptions();
chromeOpts.addArguments("user-data-dir=/path/to/your/custom/profile");
chromeOpts.setCapability("browserName", "chrome");
chromeOpts.setCapability("browserVersion", "latest");
chromeOpts.setCapability("platformName", "windows 10");
chromeOpts.setCapability("sauce:options", sauceOpts);
/**
* Finally, we pass our Browser Options instance as a parameter of our RemoteWebDriver constructor
*/
String sauceUrl = "https://ondemand.us-west-1.saucelabs.com/wd/hub";
URL url = new URL(sauceUrl);
driver = new RemoteWebDriver(url, chromeOpts);
}
/**
* @Tag is a JUnit 5 annotation that defines test method tags that aid in reporting and filtering tests.
For more information visit the docs: https://junit.org/junit5/docs/5.0.2/api/org/junit/jupiter/api/Tag.html
*/
@Tag("w3c-chrome-tests")
/**
* @DisplayName is a JUnit 5 annotation that defines test case name.
For more information visit the docs: https://junit.org/junit5/docs/5.0.2/api/org/junit/jupiter/api/DisplayName.html
*/
@DisplayName("Junit5W3CChromeTest()")
/**
* @Test is a JUnit 5 annotation that defines the actual test case, along with the test execution commands.
In the example below we:
- Navigate to our SUT (site under test), 'https://www.saucedemo.com'
- Store the current page title in a String called 'getTitle'
- Assert that the page title equals "Swag Labs"
- Use and If/Else block to determine String match
For more information visit the docs: https://junit.org/junit5/docs/5.0.2/api/org/junit/jupiter/api/Test.html
*/
@Test
public void JUnit5w3cChromeTest() throws AssertionError {
driver.navigate().to("https://www.saucedemo.com");
String getTitle = driver.getTitle();
Assertions.assertEquals(getTitle, "Swag Labs");
if (getTitle.equals("Swag Labs")) {
result = true;
}else result = false;
}
/**
* @AfterEach is a JUnit 5 annotation that defines any postrequisite test method tasks .
In the example below we:
- Use the JavascriptExecutor class to send our test results to Sauce Labs with a "passed" flag
if the test was successful, or a"failed" flag if the test was unsuccessful.
- Teardown the RemoteWebDriver session with a 'driver.quit()' command so that the test VM doesn't hang.
For more information visit the docs: https://junit.org/junit5/docs/5.0.2/api/org/junit/jupiter/api/AfterEach.html
*/
@AfterEach
public void teardown() {
((JavascriptExecutor) driver).executeScript("sauce:job-result=" + (result ? "passed" : "failed"));
driver.quit();
}
}
JUnit Jupiter Example Walkthrough
Download or clone the script from this GitHub repository.
Ensure you have the prerequisite software.
Resolve any dependencies:
Export your Sauce Labs Username and Access Key:
export SAUCE_USERNAME=my-sauce-username
export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxx
Run the following command:
$ mvn clean test -Dtest=JUnit5W3CChromeTest
Click here to see the full example
test_pytest_chrome.py (source from Sauce Labs Training Python)
import pytest
import os
from selenium import webdriver
from _pytest.runner import runtestprotocol
@pytest.fixture
def driver(request):
sauce_username = os.environ["SAUCE_USERNAME"]
sauce_access_key = os.environ["SAUCE_ACCESS_KEY"]
remote_url = "http://{}:{}@ondemand.saucelabs.com/wd/hub".format(sauce_username, sauce_access_key)
sauceOptions = {
"screenResolution": "1280x768",
"platformName": "Windows 10",
"browserVersion": "61.0",
"seleniumVersion": "3.11.0",
'name': 'Pytest Chrome W3C Sample'
}
chromeOpts = {
'platformName':"Windows 10",
'browserName': "chrome",
'browserVersion': '61.0',
'goog:chromeOptions': {'w3c': True},
'sauce:options': sauceOptions
}
browser = webdriver.Remote(remote_url, desired_capabilities=chromeOpts)
yield browser
browser.quit()
def pytest_runtest_protocol(item, nextitem, driver):
reports = runtestprotocol(item, nextitem=nextitem)
for report in reports:
if report.when == 'call':
driver.execute_script('sauce:job-result={}'.format(report.outcome))
return True
def test_should_open_safari(driver):
driver.get("http://www.saucedemo.com")
actual_title = driver.title
expected_title = "Swag Labs"
assert expected_title == actual_title
PyTest Example Walkthrough
- Download or clone the script from the Sauce Labs GitHub repository.
- Ensure you have the prerequisite software.
Resolve any dependencies:
$ pip install -r w3c-examples/requirements.txt
Export your Sauce Labs Username and Access Key:
export SAUCE_USERNAME=my-sauce-username
export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
Run the following command:
$ pytest w3c-examples/pytest/*.py
Click here to see the full example
test_unittest_chrome.py (source from Sauce Labs Training Python)
import unittest
import os
from selenium import webdriver
class TestW3COptions(unittest.TestCase):
def setUp(self):
sauce_username = os.environ["SAUCE_USERNAME"]
sauce_access_key = os.environ["SAUCE_ACCESS_KEY"]
remote_url = "http://{}:{}@ondemand.saucelabs.com/wd/hub".format(sauce_username, sauce_access_key)
sauceOptions = {
"screenResolution": "1280x768",
"platformName": "Windows 10",
"browserVersion": "61.0",
"seleniumVersion": "3.11.0",
'name': 'Unittest Chrome W3C Sample'
}
chromeOpts = {
'platformName':"Windows 10",
'browserName': "chrome",
'browserVersion': '61.0',
'goog:chromeOptions': {'w3c': True},
'sauce:options': sauceOptions
}
self.driver = webdriver.Remote(remote_url, desired_capabilities=chromeOpts)
def tearDown(self):
#driver.execute_script('sauce:job-result={}'.format(report.outcome))
self.driver.quit()
def test_should_open_safari(self):
self.driver.get("http://www.saucedemo.com")
actual_title = self.driver.title
expected_title = "Swag Labs"
assert expected_title == actual_title
unittest Example Walkthrough
- Download or clone the script from the Sauce Labs GitHub repository.
- Ensure you have the prerequisite software.
Install any dependencies:
$ pip install -r w3c-examples/requirements.txt
Export your Sauce Labs Username and Access Key:
export SAUCE_USERNAME=my-sauce-username
export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
Run the following commands:
$ python -m unittest w3c-examples/unittest/*.py
Click here to see the full example.
wdio.saucelabs.conf.js (source from Sauce Labs Training JavaScript)
const {config} = require('./wdio.shared.conf');
const build = `Sauce Labs Headless Desktop build-${ new Date().getTime() }`;
// =====================
// Sauce specific config
// =====================
// See https://webdriver.io/docs/sauce-service.html for more information
config.user = process.env.SAUCE_USERNAME;
config.key = process.env.SAUCE_ACCESS_KEY;
config.headless = true;
// ===================================================================================
// Capabilities
// You can find more about constructing the capabilities for real device testing here
// https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/
// ===================================================================================
config.capabilities = [
{
browserName: 'chrome',
platformName: 'linux',
browserVersion: 'latest',
'sauce:options': {
build,
},
},
{
browserName: 'chrome',
platformName: 'linux',
browserVersion: 'latest-1',
'sauce:options': {
build,
},
},
{
browserName: 'chrome',
platformName: 'linux',
browserVersion: 'latest-2',
'sauce:options': {
build,
},
},
{
browserName: 'firefox',
platformName: 'linux',
browserVersion: 'latest',
'sauce:options': {
build,
},
},
{
browserName: 'firefox',
platformName: 'linux',
browserVersion: 'latest-1',
'sauce:options': {
build,
},
},
{
browserName: 'firefox',
platformName: 'linux',
browserVersion: 'latest-2',
'sauce:options': {
build,
},
},
];
config.services = config.services.concat('sauce');
exports.config = config;
WebdriverIO Example Walkthrough
Download or clone the script from this GitHub repository.
Ensure you have the prerequisite software.
Ins$tall node package dependencies:
$ npm --prefix ./w3c-example install ./w3c-example
Export your Sauce Labs Username and Access Key:
export SAUCE_USERNAME=my-sauce-username
export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
Run the following command:
$ npm --prefix ./w3c-example test
You should see the following output (or something similar) in the console:
mocha "test/async-await-test.js"
headless chrome test
Page Title is: Swag Labs
✓ get-title-test (2594ms)
1 passing (13s)
Click here to see the full example.
chrome_example_spec.rb (source from Selenium 4 Samples)
# The 'require' definitions define which gems dependencies our script needs. In this example we have
# - The selenium-webdriver gem
# - The rspec framework gem
# - The sauce_whisk gem (a wrapper for the SauceLabs REST API)
require "selenium-webdriver"
require "rspec"
require "sauce_whisk"
# The basic structure of RSpec uses 'describe' and 'it' to format our script in a conversational tone.
# 'describe' represents the highest context, for example if we were testing authentication features it would say something like: '.authentication', and the 'it' would say something like 'should login'
describe "W3C RSpec Test" do
# before is an RSpec method that allows us to define prerequisite test execution steps such as:
# - defining the browser name
# - defining the browser version
# - defining the OS version and platform
# - defining the sauce:options capabilities, in this case the test name, the SauceLabs credentials, and the selenium version
before(:each) do |test|
caps = {
browser_name: 'chrome',
# platform_version now becomes platform_name with the W3C bridge.
# For more details see: https://www.rubydoc.info/gems/selenium-webdriver/Selenium/WebDriver/Remote/W3C/Capabilities
platform_name: 'windows 10',
browser_version: '61.0',
# w3c is note enabled by default in Chrome (in Chrome < 75), set the w3c setting to true
"goog:chromeOptions" => {w3c: true},
# use sauce:options to handle all saucelabs.com-specific capabilities such as:
# username, accesskey, build number, test name, timeouts etc.
"sauce:options" => {
name: test.full_description,
selenium_version: '3.141.59',
build: 'w3c-ruby-tests-1.0.0',
username: ENV['SAUCE_USERNAME'],
access_key: ENV['SAUCE_ACCESS_KEY']
}
}
@driver = Selenium::WebDriver.for(:remote,
url: 'https://ondemand.saucelabs.com:443/wd/hub',
desired_capabilities: caps)
end
# Again, 'it' represents the business-level logic that we're testing,
# in this case we're checking to see if our test in SauceLabs session can open Chrome using W3C, then check the title page.
it "should_open_chrome" do
@driver.get('https://www.saucedemo.com')
puts "title of webpage is: #{@driver.title}"
end
# Here we use 'after' which is another RSpec method that handles all postrequisite test execution steps such as:
# - sending the results to SauceLabs.com
# - Tearing down the current RemoteWebDriver session so that the test VM doesn't hang
after(:each) do |example|
# SauceWhisk::Jobs is a Ruby wrapper for the SauceLabs REST API. Here we're updating the job method
# For more info please visit the Sauce Labs REST API Documentation: https://wiki.saucelabs.com/display/DOCS/Job+Methods
SauceWhisk::Jobs.change_status(@driver.session_id, !example.exception)
@driver.quit
end
end
Rspec Example Walkthrough
Download or clone the script from the Sauce Labs GitHub repository.
Ensure you have the prerequisite software.
Install gemfile/package dependencies:
$ gem install bundler
$ bundle init
$ bundle install --path .bundle
Export your Sauce Labs Username and Access Key:
export SAUCE_USERNAME=my-sauce-username
export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
Run the following command:
Click here to expand...
NUnitExamples.cs (source from Selenium 4 Samples)
using System;
using System.Collections.Generic;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
namespace SeleniumNunit.SimpleExamples
{
[TestFixture]
[Category("Selenium 4 tests")]
public class NUnitExamples
{
private IWebDriver _driver;
private string _sauceUsername;
private string _sauceAccessKey;
/// <summary>
/// This attribute is to identify methods that are called once prior to executing any of the tests in a fixture.
/// For more information: https://github.com/nunit/docs/wiki/OneTimeSetUp-Attribute
/// </summary>
[OneTimeSetUp]
public void OneTimeSetup()
{
//TODO please supply your Sauce Labs user name in an environment variable
_sauceUsername = Environment.GetEnvironmentVariable("SAUCE_USERNAME", EnvironmentVariableTarget.User);
//TODO please supply your own Sauce Labs access Key in an environment variable
_sauceAccessKey = Environment.GetEnvironmentVariable("SAUCE_ACCESS_KEY", EnvironmentVariableTarget.User);
}
/// <summary>
/// This attribute is used inside a TestFixture to provide a common set of functions that are performed just before each test method is called.
/// For more information: https://github.com/nunit/docs/wiki/SetUp-Attribute
/// </summary>
[SetUp]
public void SetUp()
{
//TODO Add common functionality for each test setup
}
/// <summary>
/// The Test attribute is one way of marking a method inside a TestFixture class as a test.
/// For more information: https://github.com/nunit/docs/wiki/Test-Attribute
/// </summary>
[Test]
public void W3CChromeTest()
{
var chromeOptions = new ChromeOptions()
{
BrowserVersion = "latest",
PlatformName = "Windows 10",
UseSpecCompliantProtocol = true
};
var sauceOptions = new Dictionary<string, object>
{
["username"] = _sauceUsername,
["accessKey"] = _sauceAccessKey,
["name"] = TestContext.CurrentContext.Test.Name
};
chromeOptions.AddAdditionalCapability("sauce:options", sauceOptions, true);
_driver = new RemoteWebDriver(new Uri("https://ondemand.saucelabs.com/wd/hub"),
chromeOptions.ToCapabilities(), TimeSpan.FromSeconds(600));
_driver.Navigate().GoToUrl("https://www.google.com");
Assert.Pass();
}
/// <summary>
/// The Test attribute is one way of marking a method inside a TestFixture class as a test.
/// For more information: https://github.com/nunit/docs/wiki/Test-Attribute
/// </summary>
[Test]
public void W3CFirefoxTest()
{
// Set up the browser options
var ffOptions = new FirefoxOptions();
ffOptions.PlatformName = "Windows 10";
ffOptions.BrowserVersion = "latest";
// Set up the new Sauce Options for C#
// For more information: https://wiki.saucelabs.com/display/DOCS/Selenium+W3C+Capabilities+Support+-+Beta
var sauceOptions = new Dictionary<string, object>();
sauceOptions.Add("username", _sauceUsername);
sauceOptions.Add("accessKey", _sauceAccessKey);
sauceOptions.Add("name", TestContext.CurrentContext.Test.Name);
// seleniumVersion is REQUIRED for any browser other than Chrome
sauceOptions.Add("seleniumVersion", "3.141.59");
ffOptions.AddAdditionalCapability("sauce:options", sauceOptions, true);
// Sauce Lab's endpoint
var uri = new Uri("http://ondemand.saucelabs.com/wd/hub");
// Instantiate the driver with the Uri and browser options
_driver = new RemoteWebDriver(uri, ffOptions);
_driver.Navigate().GoToUrl("https://www.saucelabs.com");
StringAssert.Contains("Sauce Labs", _driver.Title);
}
/// <summary>
/// This attribute is used inside a TestFixture to provide a common set of functions that are performed after each test method.
/// For more infomration: https://github.com/nunit/docs/wiki/TearDown-Attribute
/// </summary>
[TearDown]
public void CleanUpAfterEveryTestMethod()
{
//Checks the status of the test and passes the result to the Sauce Labs job
var passed = TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Passed;
((IJavaScriptExecutor)_driver).ExecuteScript("sauce:job-result=" + (passed ? "passed" : "failed"));
_driver?.Quit();
}
}
}
NUnit Example Walkthrough
- Download or clone the script from the Sauce Labs GitHub repository.
- Ensure you have the prerequisite software.
- In Visual Studio, open the solution.
Export your Sauce Labs Username and Access Key:
export SAUCE_USERNAME=my-sauce-username
export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
- In Visual Studio Test Explorer, run tests in Selenium3.Nunit.Scripts.SimpleExamples.W3CExamplesOnSelenium3.cs.
Common Test Script Configuration Errors to Avoid
Here are some things to keep in mind when configuring your test script capabilities.
It's important not to mix W3C WebDriver-compliant capabilities with legacy JWP capabilities. This will result in a system error when you're spinning up a WebDriver session:
selenium.common.exceptions.WebDriverException: Message: Misconfigured -- Mixed Capabilities Error.
W3C keys (platformName/browserVersion) were detected alongside JWP keys (platform/version). To fix this, replace all JWP keys with W3C keys.
The following desired capabilities were received:
{'browserName': 'chrome',
'browserVersion': '80',
'platform': 'Windows'}
See https://wiki.saucelabs.com/display/docs/w3c+capabilities+support for more details.
To fix this particular error, you'd need to change platform
to platformName
and then change version
to browserVersion
browserName: 'chrome',
platformName: 'Windows',
browserVersion: '80'
sauce:options: {
name: 'My test name',
build: 'My build',
username: "SAUCE_USERNAME",
accessKey: "SAUCE_ACCESS_KEY"
seleniumVersion: "3.141.59"
}
Additional Resources