Skip to content

Commit

Permalink
Use the Safari 10 WebDriver to run tests
Browse files Browse the repository at this point in the history
For all the reasons addressed in a WebKit blog post,
https://webkit.org/blog/6901/webdriver-support-in-safari-10/,
this method should be preferred over the previous method.
  • Loading branch information
RLovelett committed Aug 16, 2018
1 parent d4dd9d0 commit 26a9695
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 22 deletions.
122 changes: 115 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,116 @@
var fs = require('fs');
var path = require('path');
var wd = require('wd');
var url = require('url');

var Safari = function(baseBrowserDecorator, args, logger) {
baseBrowserDecorator(this);

var config = Object.assign({
protocol: 'http:',
hostname: '127.0.0.1',
port: 4444,
pathname: '/'
}, args.config);

var webDriver = url.format(config);
this.name = 'Safari via WebDriver at ' + webDriver;
var log = logger.create(this.name);

log.debug(JSON.stringify(args));
log.debug(JSON.stringify(config));

this.driver = wd.remote(config);

this.driver.on('status', (info) => {
log.debug('Status: ' + info);
});

this.driver.on('command', (eventType, command, response) => {
log.debug('[command] ' + eventType + ' ' + command + ' ' + (response || ''));
});

this.driver.on('http', (meth, path, data) => {
log.debug('[http] ' + meth + ' ' + path + ' ' + (data || ''));
});

this._getOptions = function() {
return [
"-p", config.port.toString()
];
}

const superStart = this._start;
// Stop the default start from occuring
this._start = () => {};

/**
* This launcher works by checking to see if there is a `/usr/bin/safaridriver` instance running.
* It is determined to be running if the web driver API can be reached on the configured host and port.
* If it is then it it launches the Karma test runner in a new session. If it is not, it then attempts
* to start its own new instance of `/usr/bin/safaridriver` and then connect the Karma test runner in
* a new session.
*
* @param {string} url The URL that the Karma server is listening on.
*/
this.on('start', function(url) {
var self = this;

var attempts = 0;
// TODO: It would be nice if this was configurable
const MAX_ATTEMPTS = 10;
// TODO: It would be nice if this was configurable
const SLEEP_DURATION = 500;

function attachKarma(error) {
attempts += 1;
if (error && error.code === 'ECONNREFUSED' && attempts === 1) {
log.debug('attachKarma ' + attempts + ' of ' + MAX_ATTEMPTS);
log.debug(self._getCommand() + ' is not running.');
log.debug('Attempting to start ' + self._getCommand() + ' ' + self._getOptions(url).join(' '));
superStart(url);
self.driver.init({ browserName: 'safari' }, attachKarma);
} else if (error && error.code === 'ECONNREFUSED' && attempts <= MAX_ATTEMPTS) {
log.debug('attachKarma ' + attempts + ' of ' + MAX_ATTEMPTS);
log.debug('Going to give the driver time to start-up. Sleeping for ' + SLEEP_DURATION + 'ms.');
setTimeout(function() {
log.debug('Awoke to retry.');
self.driver.init({ browserName: 'safari' }, attachKarma);
}, SLEEP_DURATION);
} else if (error) {
log.error('Could not connect to Safari.');
log.error(error);
} else {
log.debug('Connected to Safari WebDriver');
log.debug('Connecting to ' + url);
self.driver.get(url);
}
}

var SafariBrowser = function(baseBrowserDecorator) {
self.driver.init({ browserName: 'safari' }, attachKarma);
});

this.on('kill', (done) => {
if (this.driver) {
this.driver.quit(function() {
done();
});
} else {
done();
}
});
};

Safari.prototype = {
name: 'Safari',

DEFAULT_CMD: {
darwin: '/usr/bin/safaridriver'
},
ENV_CMD: 'SAFARI_BIN'
};

Safari.$inject = ['baseBrowserDecorator', 'args', 'logger'];

var SafariLegacy = function(baseBrowserDecorator) {
baseBrowserDecorator(this);

this._start = function(url) {
Expand All @@ -20,7 +128,7 @@ var SafariBrowser = function(baseBrowserDecorator) {
};
};

SafariBrowser.prototype = {
SafariLegacy.prototype = {
name: 'Safari',

DEFAULT_CMD: {
Expand All @@ -30,10 +138,10 @@ SafariBrowser.prototype = {
ENV_CMD: 'SAFARI_BIN'
};

SafariBrowser.$inject = ['baseBrowserDecorator'];

SafariLegacy.$inject = ['baseBrowserDecorator'];

// PUBLISH DI MODULE
module.exports = {
'launcher:Safari': ['type', SafariBrowser]
'launcher:Safari': ['type', Safari],
'launcher:SafariLegacy': ['type', SafariLegacy]
};
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"safari"
],
"author": "Vojta Jina <[email protected]>",
"dependencies": {},
"dependencies": {
"wd": "^1.10.3"
},
"peerDependencies": {
"karma": ">=0.9"
},
Expand All @@ -29,6 +31,7 @@
},
"contributors": [
"Andreas Krummsdorf <[email protected]>",
"Friedel Ziegelmayer <[email protected]>"
"Friedel Ziegelmayer <[email protected]>",
"Ryan Lovelett <[email protected]>"
]
}
13 changes: 0 additions & 13 deletions safari.html

This file was deleted.

0 comments on commit 26a9695

Please sign in to comment.