ericportis.com

WebDriving Experimental Features

Sometimes I need to automate some quick browser tests. I like to use Node, and standalone webdriver.io to do this.

Sometimes, the stuff I’m interested in testing is new and experimental. So, I want to get WebDriver to drive:

  1. Canary
  2. With the Experimental Web Platform Features flag enabled.

But! Before we tackle that, let’s level-set.

WebDriving plain old Chrome

To test in regular ol’ Chrome, I need ChromeDriver installed and running. Because I do as much as possible through Homebrew, I installed ChromeDriver via:

$ brew cask install chromedriver

Then…

$ chromedriver

…tada – that’s ChromeDriver up and running.

Next, within my project directory, I:

$ npm -i --save-dev webdriver

With those two pieces – ChromeDriver and WebDriver.io – in place, I can run a script like this:

const { remote } = require( 'webdriverio' );

( async () => {

const browser = await remote( {
	logLevel: 'error',
	path: '/',
	capabilities: {
		browserName: 'chrome'
	},
	port: 9515
} );

// do stuff with the browser
} );

And a little Chrome window pops up and my script is controlling and reading information from it programmatically and it’s great.

Canary

So, how do I get that little Chrome window to be a Canary window?

First things first, we need a new ChromeDriver. The stock version will only work with the stable version of Chrome.

Getting ChromeDriver Canary isn’t terribly easy, but it is well-documented. TL;DR you have to jump through a hoop or two to hunt for the very latest ChromeDriver build from within in a big hairy directory containing many thousands of Chromium snapshots, download it, and run it. (It might go without saying but: quit regular ChromeDriver before you do this).

Given the script above, ChromeDriver Canary (and the script) will fail, because ChromeDriver Canary will still try to start up regular-old stable Chrome. Why? I don’t know, the layers of who’s driving what using what configuration settings here (between WebDriver.io, ChromeDriver, and actual Chrome) confuse me. But I did eventually figure out how to get ChromeDriver Canary to, well, drive Canary.

One of the capabilities that you can set within WebDriver’s remote instantiation is, apparently, 'goog:chromeOptions'. With this, you can set a bunch of options, that are passed to ChromeDriver. And one of those options is binary, which you can use to point to a particular Chrome application binary. Like Canary!

const browser = await remote( {
	logLevel: 'error',
	path: '/',
	capabilities: {
		browserName: 'chrome',
		'goog:chromeOptions': {
			binary: '/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary'
		}
	},
	port: 9515
} );

Now, our script will successfully get ChromeDriver Canary to start Canary up, and run tests in it. Step one complete!

Experimental Web Platform Features

There’s another goog:chromeOptions called args. Using this, you can tell ChromeDriver to pass command line switches to the Chrome binary, when it’s starting it up. Turns out, one of those switches is --enable-experimental-web-platform-features, which does just what it says. So! With this:

const browser = await remote( {
	logLevel: 'error',
	path: '/',
	capabilities: {
		browserName: 'chrome',
		'goog:chromeOptions': {
			args: [ 'enable-experimental-web-platform-features' ],
			binary: '/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary'
		}
	},
	port: 9515
} );

We get a programmatically-controlled Canary window, with the Experimental Web Platform Features flag enabled. Yay!