Skip to end of metadata
Go to start of metadata

With our support for the latest Selenium version, Sauce Labs also now supports the W3C-compliant Selenium capabilities and protocol that will be released with upcoming Selenium versions. Some of the features being implemented are only available when using the W3C protocol, and the upcoming Selenium versions will include extended capabilities that are not backwards-compatible with previous Selenium versions. Sauce Labs is offering a support program to test these new features, and to help prepare for the transition to the upcoming Selenium versions.

In addition to feedback about updating your scripts as described in this topic, we'd like to hear your feedback about the overall changes to Selenium in our dedicated Slack channel. If you would like to apply to be part of the Beta Slack channel, please contact our Product Team

Updating WebDriver Capabilities

You'll need to make a few changes to the WebDriver capabilities of your existing Selenium test scripts to use the new W3C protocol in Selenium 3.11.0+.

A new capability in which you must include all the capabilities that are specific to Sauce Labs.

For example, if you wanted to specify your Sauce Labs username, and the accessKey in your test, you would set the sauce:options like this:

"sauce:options": {
	"username": "myuser", 
	"accesskey": "XXXXXXXX"
}
 Click here to see all capabilities specific to Sauce Labs that belong in sauce:options
  • 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

Sauce VM Error

A poorly configured sauce:options capability can cause the Sauce VMs to fail with the below error message when spinning up a WebDriver session.

Sauce VMs failed to start the browser or device Details Browser = IE11, Windows 7 - metadata shows “sauce:options”: “oversized non-string {…}.
Change the capability name platform to platformName
Change the capability name browser to browserName

Change the capability name version to browserVersion

Below are the browser versions that are compatible with the W3C protocol:

  • Firefox - v.53+
  • Chrome - v.61+
  • Internet Explorer 11


For tests on Google Chrome version 74 or lower, the W3C capability must be set as an experimental option. As of ChromeDriver version 75 it "now runs in W3C standard compliant mode by default", therefore setting this capability won't be necessary in the future.

Java Example
ChromeOptions chOpts = new ChromeOptions(); 
chOpts.setExperimentalOption("w3c", true);

Additionally, the "w3c" value needs to be set as a boolean value and not a string. For example, it would be set to true in Java and True in Python, not "true".

Checking for Use of New Capabilities

You can check to see whether your tests are running under the new W3C protocol.

  1. Go to the Test Details page for your test in the Sauce Labs web interface.
  2. Click the Commands tab.
  3. Select the first Post command, which will be Post /session.
  4. Under the screenshot of the command, in the Parameters section, you will see the capabilities that were used in the test. If that line begins with desiredCapabilities, you are running the non-W3C version (see screenshot below). If it begins with capabilities, you are running the new W3C-compliant version.


Language-Specific Changes

There are some changes to specific Selenium language bindings that you should be aware of when migrating to the W3C protocol.

The new DriverOptions() class is for managing options specific to each browser web driver.

Before:

DesiredCapabilities caps = new DesiredCapabilities.firefox();

After:

FireFoxOptions mozOpts = new FirefoxOptions();

If you fail to update these options when using Selenium 3.11+, you'll see this message:

"INFO: Using `new FirefoxOptions()` is preferred to `DesiredCapabilities.firefox()"

You can now set capabilities using the MutableCapabilities() class instead of using DesiredCapabilities() This is the preferred method and implements all interfaces including DriverOptions() and DesiredCapabilities().

See the Before and After Example on this page and consult the Selenium documentation for more information.

These two Java snippets show a comparison between an original script, and the version after it has been edited to use the new W3C capabilities.

Before

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);

After

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 Code Snippets

All available sample code snippets for a variety of language/framework combinations are in our training repository on GitHub. Please select the desired example below and follow the instructions:

 Click here to see the full example

Not found

Could not find the given branch refs/remotes/origin/java_js_edits

TestNG Example Walkthrough

  1. Download or clone the script from the following repository: https://github.com/saucelabs-training/w3c-examples/tree/master/java/testng

  2. Ensure you have the prerequisite software: https://github.com/saucelabs-training/demo-java/blob/master/prerequisites.md

  3. Run the following command to resolve dependencies

    $ mvn dependency:resolve
  4. Export your Sauce Labs Username and Access Key:

    Sauce Labs Username and Access Key Example:
    export SAUCE_USERNAME=my-sauce-username
    export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
  5. Run the following commands:

    $ mvn clean test -Dtest=W3CChromeTest
 Click here to see the full example

Junit5 W3C Example
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.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import java.net.MalformedURLException;
import java.net.URL;

public class W3CChromeTest {
    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();
        
        /** ChomeOptions allows us to set browser-specific behavior such as profile settings, headless capabilities, insecure tls certs, 
        and in this example--the W3C protocol 
        For more information see: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/chrome/ChromeOptions.html */
        
        ChromeOptions chromeOpts = new ChromeOptions();
        chromeOpts.setExperimentalOption("w3c", true);
        
        /** The MutableCapabilities class  came into existence with Selenium 3.6.0 and acts as the parent class for 
        all browser implementations--including the ChromeOptions class extension.
        Fore more information see: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/MutableCapabilities.html */
        
        MutableCapabilities sauceOpts = new MutableCapabilities();
        sauceOpts.setCapability("name", methodName);
        sauceOpts.setCapability("seleniumVersion", "3.141.59");
        sauceOpts.setCapability("username", username);
        sauceOpts.setCapability("accessKey", accessKey);
        sauceOpts.setCapability("tags", testInfo.getTags());

        
        /** Below we see the use of our other capability objects, 'chromeOpts' and 'sauceOpts', 
        defined in ChromeOptions.CAPABILITY and sauce:options respectively.
        */
        DesiredCapabilities caps = new DesiredCapabilities();
        caps.setCapability(ChromeOptions.CAPABILITY,  chromeOpts);
        caps.setCapability("sauce:options", sauceOpts);
        caps.setCapability("browserName", "googlechrome");
        caps.setCapability("browserVersion", "71.0");
        caps.setCapability("platformName", "windows 10");
        
        /** Finally, we pass our DesiredCapabilities object 'caps' as a parameter of our RemoteWebDriver instance */
        String sauceUrl = "https://ondemand.saucelabs.com:443/wd/hub";
        URL url = new URL(sauceUrl);
        driver = new RemoteWebDriver(url, caps);
    }
    /**
         * @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("w3cChromeTest()")
    /**
         * @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 w3cChromeTest() 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

  1. Download or clone the script from the following repository: https://github.com/saucelabs-training/w3c-examples/tree/master/java/junit5

  2. Ensure you have the prerequisite software: https://github.com/saucelabs-training/demo-java/blob/master/prerequisites.md

  3. Run the following command to resolve dependencies

    $ mvn dependency:resolve
  4. Export your Sauce Labs Username and Access Key:

    Sauce Labs Username and Access Key Example:
    export SAUCE_USERNAME=my-sauce-username
    export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
  5. Run the following commands:

    $ mvn clean test -Dtest=W3CChromeTest
 Click here to see the full example

Pytest W3C Example
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

  1. Download or clone the script from the following repository: https://github.com/saucelabs-training/w3c-examples/tree/master/python
  2. Ensure you have the prerequisite software: https://github.com/saucelabs-training/demo-python/blob/master/prerequisites.md
  3. Run the following command to resolve dependencies:

    $ pip install -r requirements.txt
  4. Export your Sauce Labs Username and Access Key:

    Sauce Labs Username and Access Key Example:
    export SAUCE_USERNAME=my-sauce-username
    export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
  5. Run the following commands:

    $ python pytest test_pytest_chrome.py
 Click here to see the full example

Unittest W3C Example
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

  1. Download or clone the script from the following repository: https://github.com/saucelabs-training/w3c-examples/tree/master/python
  2. Ensure you have the prerequisite software: https://github.com/saucelabs-training/demo-python/blob/master/prerequisites.md
  3. Run the following command to resolve dependencies:

    $ pip install -r requirements.txt



  4. Export your Sauce Labs Username and Access Key:

    Sauce Labs Username and Access Key Example:
    export SAUCE_USERNAME=my-sauce-username
    export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
  5. Run the following commands:

    $ python unittest test_pytest_chrome.py
 Click here to see the full example.

chrome-w3c-example-test.js
const promise = require('selenium-webdriver');
let expect = require('chai').expect;
let webdriver = require('selenium-webdriver');
/**
    Here we set our script dependencies (e.g. selenium-webdriver and 'assert'), and we also set some key variables such as:
        - our SauceLabs account credentials
        - the SUT (site under test) url
        - any necessary tags we may use to run test reports or filters
        - the WebDriver session (indicated by 'driver')
*/
let username = process.env.SAUCE_USERNAME,
    accessKey = process.env.SAUCE_ACCESS_KEY,
    /* Change the baseURL to your application URL */
    baseUrl = "https://www.saucedemo.com",
    tags = ["w3c", "demoTest", "w3c-chrome-tests", "nodeTest"],
    driver;

/** the selenium-webdriver will eventually deprecate the promise manager, therefore you must resolve your callback methods by either:
 * - chaining your own promises: https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs#option-1-use-classic-promise-chaining
 * - migrating to generators: https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs#option-2-migrate-to-generators
 * - or migrating to async/await (as shown in this example): https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs#option-3-migrate-to-asyncawait
 */

promise.USE_PROMISE_MANAGER = false;
/** 
    We use 'describe' in order to group test methods together. Even though we only have one test case in this example,
    structuring your project this way makes it scalable when you add tests. We can also set global-level test execution parameters such as timeouts
*/
describe('W3C Test', function() {
    this.timeout(40000);
    /**
        'beforeEach' is a Mocha test suite hook that allows us to set any prerequisite test method tasks. In this example we set:
        - SauceLabs.com credentials via username and accessKey
        - Browser to chrome
        - OS platform to Windows 10
        - The name of the test
        - and our "sauce:options" object, here we set other test parameters such as the:
            - sauce labs credentials (username and accessKey)
            - selenium version,
            - the build name/number,
            - test name
            - test-level timeouts,
            - test case tags
        For more information on 'beforeEach' consult the docs: https://mochajs.org/api/mocha.suite#beforeEach
    */
    beforeEach(async function () {
        driver = await new webdriver.Builder().withCapabilities({
            "browserName": 'chrome',
            "platformName": 'Windows 10',
            "browserVersion": 'latest',
            /** Google requires "w3c" to be set in "goog:chromeOptions" as true if you're using ChromeDriver version 74 or lower.
             * Based on this commit: https://chromium.googlesource.com/chromium/src/+/2b49880e2481658e0702fd6fe494859bca52b39c
             * ChromeDriver now uses w3c by default from version 75+ so setting this option will no longer be a requirement **/
            "goog:chromeOptions" : { "w3c" : true },
            "sauce:options": {
                "username": username,
                "accessKey": accessKey,
                "maxDuration": 3600,
                "idleTimeout": 1000,
                "seleniumVersion:": '3.141.59',
                "tags": tags,
                "name": "chrome-w3c-" + this.currentTest.title,
                "build": 'w3c-sauce-mocha-tests'
            }
        }).usingServer("https://ondemand.saucelabs.com/wd/hub").build();

        await driver.getSession().then(function (sessionid) {
            driver.sessionID = sessionid.id_;
        });
    });
    
    /**
        'afterEach' is a Mocha test suite hook that allows us to set any postrequisite test method tasks. In the example below we:
            - 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 on 'afterEach' consult the docs: https://mochajs.org/api/mocha.suite#afterEach
    */

    afterEach(async function() {
        await driver.executeScript("sauce:job-result=" + (this.currentTest.state));
        await driver.quit();
    });
    
    /**
         * 'it' is the Mocha test case 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' indicated by the 'baseUrl' variable.
            - Store the current page title in a String called 'title'
            - Assert that the page title equals "Swag Labs"
            For more information visit the docs: https://mochajs.org/api/test
    */

    it('get-title-test', async function() {
        await driver.get(baseUrl);
        const title = await driver.getTitle();
        console.log('Page Title is: ' + title);
        expect(title).equals('Swag Labs');
    });
});

Mocha-Chai Example Walkthrough

  1. Download or clone the script from the following repository: https://github.com/saucelabs-training/w3c-examples/tree/master/node/mocha/test

  2. Ensure you have the prerequisite software

  3. Install node package dependencies

    $ npm install
  4. Export your Sauce Labs Username and Access Key:

    Sauce Labs Username and Access Key Example:
    export SAUCE_USERNAME=my-sauce-username
    export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
  5. Run the following command:

    $ npm test

    You should see the following output (or something similar) in the console:

     mocha "test/chrome-w3c-example-test.js"
    
    
    
      headless chrome test
    Page Title is: Swag Labs
        ✓ get-title-test (2594ms)
    
    
      1 passing (13s)                                                              


 Click here to see the full example.

conf.js
const SpecReporter = require('jasmine-spec-reporter').SpecReporter;
exports.config = {
    sauceUser: process.env.SAUCE_USERNAME,
    sauceKey: process.env.SAUCE_ACCESS_KEY,
    sauceRegion: 'us',
    specs: [ 'specs/*spec.js' ],

    onPrepare: async () => {
        await browser.waitForAngularEnabled(false);
        const caps = await browser.getCapabilities();
        jasmine.getEnv().addReporter(new SpecReporter({
            spec: {
                displayStacktrace: true,
            }
        }));
    },
    framework: 'jasmine',
    multiCapabilities: [
        {
            browserName: 'chrome',
            browserVersion: 'latest',
            platformName: 'Windows 10',
            'goog:chromeOptions': { 'w3c': true },
            'sauce:options': {
                seleniumVersion: '3.141.59',
                name: 'chrome-w3c-protractor-test',
                build: 'Sample W3C Protractor Tests'
            },
            shardTestFiles: true,
            maxInstances: 25
        },
        {
            browserName: 'firefox',
            browserVersion: 'latest',
            platformName: 'Windows 10',
            'sauce:options': {
                seleniumVersion: '3.141.59',
                name: 'firefox-w3c-protractor-test',
                build: 'Sample W3C Protractor Tests'
            },
            shardTestFiles: true,
            maxInstances: 25
        },
    ],
    baseUrl: 'https://www.saucedemo.com',

    onComplete: async () => {
        let printSessionId = async (jobName) => {
            let session = await browser.getSession();
            console.log('SauceOnDemandSessionID=' + session.getId() + ' job-name=' + jobName);
        };
        printSessionId('Insert Job Name Here');
        //await browser.executeScript("sauce:job-result=" + (SpecReporter.valueOf().result());
    },
};

sample_test_spec.js
describe('Protractor Demo', function() {
    it('should confirm page title', async () => {
        await browser.executeScript("sauce:context=Going to 'saucedemo.com'");
        await browser.get('https://www.saucedemo.com');
        await browser.executeScript("sauce:context=Asserting 'Swag Labs' title is present");
        let title = await browser.getTitle();
        expect(title).toEqual('Swag Labs');
    });
});

Protractor-Jasmine Example Walkthrough

  1. Download or clone the script from the following repository: https://github.com/saucelabs-training/w3c-examples/tree/master/node/protractor

  2. Ensure you have the prerequisite software

  3. Install node package dependencies

    $ npm install
  4. Export your Sauce Labs Username and Access Key:

    Sauce Labs Username and Access Key Example:
    export SAUCE_USERNAME=my-sauce-username
    export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
  5. Run the following command:

    $ npm test

    You should see the following output (or something similar) in the console:

    > protractor conf.js
    [firefox #11] Jasmine started
    [firefox #11] .
    [firefox #11]   Protractor Demo
    [firefox #11]     ✓ should confirm page title                                                
 Click here to see the full example.

chrome_example_spec.rb
    # 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

  1. Download or clone the script from the following repository: https://github.com/saucelabs-training/w3c-examples/tree/master/ruby/rspec

  2. Ensure you have the prerequisite software

  3. Install gemfile/package dependencies

    $ gem install bundler
    $ bundle init
    $ bundle install --path .bundle
  4. Export your Sauce Labs Username and Access Key:

    Sauce Labs Username and Access Key Example:
    export SAUCE_USERNAME=my-sauce-username
    export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
  5. Run the following command:

    $ bundle exec rspec
 Click here to expand...

NUniteExamples.cs
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

  1. Download or clone the script from the following repository: https://github.com/saucelabs-training/w3c-examples/tree/master/csharp
  2. Ensure you have the prerequisite software
  3. In Visual Studio, add the NuGet packages you need to run your automated web tests on Sauce Labs
  4. Export your Sauce Labs Username and Access Key:

    export SAUCE_USERNAME=my-sauce-username
    export SAUCE_ACCESS_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx2cy8f4
  5. In Visual Studio, click Test, point to your desired operating system, and click Test Explorer.

W3C Protocol for Appium

Appium 1.8.0, released on April 20th, 2018 offers full support for W3C. Sauce Labs isn't aware of any existing issues with using W3C capabilities in Appium tests.

TestNG Example Walkthrough

Coming Soon!

JUnit Jupiter Example Walkthrough

Coming Soon!

Pytest Example Walkthrough

Coming Soon!

Mocha-Chai Example Walkthrough

Coming Soon!

WebdriverIO Example Walkthrough

Coming Soon!

Rspec Example Walkthrough

Coming Soon!

NUnit Example Walkthrough

Coming Soon!

CI/CD Best Practices

A good practice is to inject your buildName and test name as environment variables in your CI/CD platform. For example to pull the build and job information from Jenkins we would set our test variables as such: 

public static String username = System.getenv("SAUCE_USERNAME");
public static String accesskey = System.getenv("SAUCE_ACCESS_KEY");
public static String jobName = System.getenv("JOB_NAME+BUILD_NUMBER)";
public static String buildTag = System.getenv("BUILD_ID+BUILD_TAG");


For more information on the various methods in which each CI/CD platforms handles this operation, refer to the links below:

Webinar and Script Editing Demo Videos

In this demo you'll see how to modify a basic Selenium script written in Java to be compliant with the new W3C protocol.

An introduction to Selenium 4 from Sauce Labs

  • No labels