couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From benk...@apache.org
Subject fauxton commit: updated refs/heads/master to e1e5353
Date Fri, 28 Nov 2014 19:50:10 GMT
Repository: couchdb-fauxton
Updated Branches:
  refs/heads/master 7544348bb -> e1e5353ef


Refactor Nightwatch

This ticket makes a few changes to the way Nightwatch is set up:
1. the main Nightwatch settings (username, password, login URL, key
nightwatch setup file locations) are moved to the settings.json
file to allow them to be defined a single global place and overridden
if need be.
2. it now dynamically determines the list of tests to run based on
content of settings.json.
3. hardcoded username, password & URL moved from helpers.js and
loginToGUI.js and now loaded from settings.json file

Closes COUCHDB-2481


Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/e1e5353e
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/e1e5353e
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/e1e5353e

Branch: refs/heads/master
Commit: e1e5353ef8759a8eb45f48d6de9f4cad8a1c335f
Parents: 7544348
Author: Benjamin Keen <ben.keen@gmail.com>
Authored: Wed Nov 26 12:54:03 2014 -0800
Committer: Benjamin Keen <ben.keen@gmail.com>
Committed: Fri Nov 28 11:49:58 2014 -0800

----------------------------------------------------------------------
 .gitignore                                      |   2 +
 Gruntfile.js                                    |  45 ++------
 .../tests/nightwatch/createsDatabase.js         |   2 +-
 .../databases/tests/nightwatch/createsView.js   |   2 +-
 .../tests/nightwatch/deletesDatabase.js         |   2 +-
 .../documents/tests/nightwatch/bulkDelete.js    |   4 +-
 .../tests/nightwatch/createsDocument.js         |   2 +-
 .../tests/nightwatch/deletesDocument.js         |   2 +-
 .../tests/nightwatch/navigateToNewView.js       |   2 +-
 .../switchDatabaseViaLookaheadTray.js           |   2 +-
 settings.json.default                           |   9 +-
 tasks/fauxton.js                                |  94 +++++++++++++++++
 .../custom-commands/loginToGUI.js               |  10 +-
 test/nightwatch_tests/helpers/helpers.js        |  12 ++-
 test/nightwatch_tests/nightwatch.json           |  15 ++-
 .../nightwatch_tests/nightwatch.json.underscore | 102 +++++++++++++++++++
 16 files changed, 245 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 7c98c92..680e5b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,7 +24,9 @@ settings.json*
 !assets/js/plugins/zeroclipboard/ZeroClipboard.swf
 test/test.config.js
 app/initialize.js
+test/nightwatch_tests/nightwatch.json
 test/nightwatch_tests/reports/*
 test/nightwatch_tests/selenium/*
 !test/nightwatch_tests/selenium/.gitkeep
 .DS_Store
+

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/Gruntfile.js
----------------------------------------------------------------------
diff --git a/Gruntfile.js b/Gruntfile.js
index 86ef8df..2dd1db2 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -410,6 +410,15 @@ module.exports = function(grunt) {
     
     selenium_start: {
       options: { port: 4444 }
+    },
+
+    // generates the nightwatch.json file with appropriate content for this env
+    initNightwatch: {
+      default: {
+        settings: helper.readSettingsFile(),
+        template: 'test/nightwatch_tests/nightwatch.json.underscore',
+        dest: 'test/nightwatch_tests/nightwatch.json'
+      }
     }
   });
 
@@ -425,39 +434,6 @@ module.exports = function(grunt) {
   });
 
 
-  // enable running of a single test with nightwatch
-  var fileArg = grunt.option('file');
-  if (fileArg) {
-    fileArg = fileArg + '.js';
-    var nightwatchConf = require('./test/nightwatch_tests/nightwatch.json'),
-        paths;
-
-    paths = nightwatchConf.src_folders.reduce(function (acc, dir) {
-      if (fs.existsSync(dir + '/' + fileArg)) {
-        acc.push(dir + '/' + fileArg);
-      }
-      return acc;
-    }, []);
-
-    if (paths.length > 1) {
-      throw new Error('Found multiple tests');
-    }
-
-    if (!paths.length) {
-      throw new Error('Found no testfile named ' + fileArg);
-    }
-
-    grunt.config.merge({
-      exec: {
-        start_nightWatch: {
-           command: __dirname + '/node_modules/nightwatch/bin/nightwatch' +
-            ' -t ' + paths[0] +
-            ' -e chrome -c ' + __dirname + '/test/nightwatch_tests/nightwatch.json'
-        }
-      }
-    });
-  }
-
   /*
    * Load Grunt plugins
    */
@@ -545,6 +521,5 @@ module.exports = function(grunt) {
    * Nightwatch functional testing
    */
   //Start Nightwatch test from terminal, using: $ grunt nightwatch
-  grunt.registerTask('nightwatch', [ 'exec:check_selenium', 'selenium_start', 'exec:check_chrome_driver',
'exec:start_nightWatch']);
-
+  grunt.registerTask('nightwatch', [ 'exec:check_selenium', 'selenium_start', 'exec:check_chrome_driver',
'initNightwatch', 'exec:start_nightWatch']);
 };

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/app/addons/databases/tests/nightwatch/createsDatabase.js
----------------------------------------------------------------------
diff --git a/app/addons/databases/tests/nightwatch/createsDatabase.js b/app/addons/databases/tests/nightwatch/createsDatabase.js
index b729da1..5ec01ed 100644
--- a/app/addons/databases/tests/nightwatch/createsDatabase.js
+++ b/app/addons/databases/tests/nightwatch/createsDatabase.js
@@ -14,7 +14,7 @@ module.exports = {
   'Creates a Database' : function (client) {
     var waitTime = 10000,
         newDatabaseName = client.globals.testDatabaseName,
-        baseUrl = client.globals.baseUrl;
+        baseUrl = client.globals.test_settings.launch_url;
 
     client
       .loginToGUI()

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/app/addons/databases/tests/nightwatch/createsView.js
----------------------------------------------------------------------
diff --git a/app/addons/databases/tests/nightwatch/createsView.js b/app/addons/databases/tests/nightwatch/createsView.js
index f852c6f..b439f9e 100644
--- a/app/addons/databases/tests/nightwatch/createsView.js
+++ b/app/addons/databases/tests/nightwatch/createsView.js
@@ -16,7 +16,7 @@ module.exports = {
     var waitTime = 10000,
         newDatabaseName = client.globals.testDatabaseName,
         newDocumentName = 'create_view_doc',
-        baseUrl = client.globals.baseUrl;
+        baseUrl = client.globals.test_settings.launch_url;
 
     var indexFunctionString = function (parity) {
       return 'function (doc) {'               +  

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/app/addons/databases/tests/nightwatch/deletesDatabase.js
----------------------------------------------------------------------
diff --git a/app/addons/databases/tests/nightwatch/deletesDatabase.js b/app/addons/databases/tests/nightwatch/deletesDatabase.js
index 345cdf5..c698be8 100644
--- a/app/addons/databases/tests/nightwatch/deletesDatabase.js
+++ b/app/addons/databases/tests/nightwatch/deletesDatabase.js
@@ -14,7 +14,7 @@ module.exports = {
   'Deletes a database': function (client) {
     var waitTime = 8000,
         newDatabaseName = client.globals.testDatabaseName,
-        baseUrl = client.globals.baseUrl;
+        baseUrl = client.globals.test_settings.launch_url;
 
     client
       .loginToGUI()

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/app/addons/documents/tests/nightwatch/bulkDelete.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/bulkDelete.js b/app/addons/documents/tests/nightwatch/bulkDelete.js
index cf8adcf..e5c0bf0 100644
--- a/app/addons/documents/tests/nightwatch/bulkDelete.js
+++ b/app/addons/documents/tests/nightwatch/bulkDelete.js
@@ -16,7 +16,7 @@ module.exports = {
         newDatabaseName = client.globals.testDatabaseName,
         newDocumentName1 = 'bulktest1',
         newDocumentName2 = 'bulktest2',
-        baseUrl = client.globals.baseUrl;
+        baseUrl = client.globals.test_settings.launch_url;
 
     client
       .loginToGUI()
@@ -44,7 +44,7 @@ module.exports = {
   'Select all works after changing the page': function (client) {
     var waitTime = 10000,
         newDatabaseName = client.globals.testDatabaseName,
-        baseUrl = client.globals.baseUrl;
+        baseUrl = client.globals.test_settings.launch_url;
 
     client
       .loginToGUI()

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/app/addons/documents/tests/nightwatch/createsDocument.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/createsDocument.js b/app/addons/documents/tests/nightwatch/createsDocument.js
index dfceec8..88fee7f 100644
--- a/app/addons/documents/tests/nightwatch/createsDocument.js
+++ b/app/addons/documents/tests/nightwatch/createsDocument.js
@@ -16,7 +16,7 @@ module.exports = {
     var waitTime = 10000,
         newDatabaseName = client.globals.testDatabaseName,
         newDocumentName = 'create_doc_document',
-        baseUrl = client.globals.baseUrl;
+        baseUrl = client.globals.test_settings.launch_url;
     
     client
       .loginToGUI()

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/app/addons/documents/tests/nightwatch/deletesDocument.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/deletesDocument.js b/app/addons/documents/tests/nightwatch/deletesDocument.js
index cd8f5ed..47b6b94 100644
--- a/app/addons/documents/tests/nightwatch/deletesDocument.js
+++ b/app/addons/documents/tests/nightwatch/deletesDocument.js
@@ -15,7 +15,7 @@ module.exports = {
     var waitTime = 10000,
         newDatabaseName = client.globals.testDatabaseName,
         newDocumentName = 'delete_doc_doc',
-        baseUrl = client.globals.baseUrl;
+        baseUrl = client.globals.test_settings.launch_url;
 
     client
       .loginToGUI()

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/app/addons/documents/tests/nightwatch/navigateToNewView.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/navigateToNewView.js b/app/addons/documents/tests/nightwatch/navigateToNewView.js
index b59c5d2..0afb622 100644
--- a/app/addons/documents/tests/nightwatch/navigateToNewView.js
+++ b/app/addons/documents/tests/nightwatch/navigateToNewView.js
@@ -17,7 +17,7 @@ module.exports = {
   'Navigate to and from New View Page' : function (client) {
     var waitTime = 10000,
       newDatabaseName = client.globals.testDatabaseName,
-      baseUrl = client.globals.baseUrl;
+      baseUrl = client.globals.test_settings.launch_url;
 
     client
       .loginToGUI()

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/app/addons/documents/tests/nightwatch/switchDatabaseViaLookaheadTray.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/switchDatabaseViaLookaheadTray.js b/app/addons/documents/tests/nightwatch/switchDatabaseViaLookaheadTray.js
index cc2b0dc..13a4e87 100644
--- a/app/addons/documents/tests/nightwatch/switchDatabaseViaLookaheadTray.js
+++ b/app/addons/documents/tests/nightwatch/switchDatabaseViaLookaheadTray.js
@@ -15,7 +15,7 @@ module.exports = {
     var waitTime = 8000,
       newDatabaseName = client.globals.testDatabaseName,
       secondDatabaseName = newDatabaseName + "2",
-      baseUrl = client.globals.baseUrl;
+      baseUrl = client.globals.test_settings.launch_url;
 
     client
       .loginToGUI()

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/settings.json.default
----------------------------------------------------------------------
diff --git a/settings.json.default b/settings.json.default
index 3120631..1788433 100644
--- a/settings.json.default
+++ b/settings.json.default
@@ -60,7 +60,6 @@
           "version": "1.0"
         }
       }
-
     },
 
     "couch_config": {
@@ -71,5 +70,13 @@
           "okay_if_missing": true
         }
       }
+    },
+
+    "nightwatch": {
+      "username": "tester",
+      "password": "testerpass",
+      "launch_url": "localhost:8000",
+      "custom_commands_path": "test/nightwatch_tests/custom-commands",
+      "globals_path": "test/nightwatch_tests/helpers/helpers.js"
     }
 }

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/tasks/fauxton.js
----------------------------------------------------------------------
diff --git a/tasks/fauxton.js b/tasks/fauxton.js
index e06e7dc..b93aecc 100644
--- a/tasks/fauxton.js
+++ b/tasks/fauxton.js
@@ -133,4 +133,98 @@ module.exports = function(grunt) {
 
     grunt.file.write('./test/test.config.js', configTemplate({configInfo: configInfo, testFiles:
testFiles}));
   });
+
+
+  // run every time nightwatch is executed from the command line
+  grunt.registerMultiTask('initNightwatch', 'Sets up Nightwatch', function () {
+
+    // perform a little validation on the settings
+    _validateNightwatchSettings(this.data.settings);
+
+    // figure out what tests we need to run by examining the settings.json file content
+    var addonsWithTests = _getNightwatchTests(this.data.settings);
+
+    // if the user passed a --file="X" on the command line, filter out
+    var singleTestToRun = grunt.option('file');
+    if (singleTestToRun) {
+      addonsWithTests = _findSpecificNightwatchTest(addonsWithTests, singleTestToRun);
+    }
+
+    // now generate the new nightwatch.json file
+    var nightwatchTemplate = _.template(grunt.file.read(this.data.template));
+    grunt.file.write(this.data.dest, nightwatchTemplate({
+      src_folders: JSON.stringify(addonsWithTests),
+      custom_commands_path: JSON.stringify(this.data.settings.nightwatch.custom_commands_path),
+      globals_path: this.data.settings.nightwatch.globals_path,
+      username: this.data.settings.nightwatch.username,
+      password: this.data.settings.nightwatch.password,
+      launch_url: this.data.settings.nightwatch.launch_url
+    }));
+  });
+
+
+  // HELPERS
+
+  function _validateNightwatchSettings (data) {
+    var error = '';
+
+    // if the settings file didn't contain any addons, it points to bigger problems!
+    if (!data.deps.length) {
+      error = 'No addons listed in settings.json - no tests to run!';
+
+    // check the requires nightwatch settings. These should always exist in the settings.json
file
+    } else if (!_.has(data, 'nightwatch') ||
+      !_.has(data.nightwatch, 'username') ||
+      !_.has(data.nightwatch, 'password') ||
+      !_.has(data.nightwatch, 'launch_url')) {
+      error = 'Your settings.json file doesn\'t contain valid nightwatch settings. Please
check the user doc.';
+    }
+
+    if (error) {
+      grunt.fail.fatal(error);
+    }
+  };
+
+  function _findSpecificNightwatchTest (addonsWithTests, file) {
+    var filename = file + '.js';
+
+    var paths = addonsWithTests.reduce(function (acc, dir) {
+      if (fs.existsSync(dir + '/' + filename)) {
+        acc.push(dir + '/' + filename);
+      }
+      return acc;
+    }, []);
+
+    if (paths.length > 1) {
+      grunt.fail.fatal('Found multiple nightwatch tests with that filename.');
+    } else if (!paths.length) {
+      grunt.fail.fatal('Found no testfile named ' + filename);
+    }
+
+    return paths[0];
+  };
+
+  function _getNightwatchTests (settings) {
+    var addonBlacklist = (_.has(settings.nightwatch, 'addonBlacklist')) ? settings.nightwatch.addonBlacklist
: [];
+
+    return _.filter(settings.deps, function(addon) {
+
+      // if we've explicitly been told to ignore this addon's test, ignore 'em!
+      if (_.contains(addonBlacklist, addon.name)) {
+        return false;
+      }
+
+      var fileLocation = 'app/addons/' + addon.name + '/tests/nightwatch';
+      if (_.has(addon, 'path')) {
+        fileLocation = addon.path + '/tests/nightwatch';
+      }
+
+      // see if the addon has any tests
+      return fs.existsSync(fileLocation);
+
+    }).map(function(addon) {
+      return 'app/addons/' + addon.name + '/tests/nightwatch';
+    });
+  }
+
 };

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/test/nightwatch_tests/custom-commands/loginToGUI.js
----------------------------------------------------------------------
diff --git a/test/nightwatch_tests/custom-commands/loginToGUI.js b/test/nightwatch_tests/custom-commands/loginToGUI.js
index ee2917c..7b0dc18 100644
--- a/test/nightwatch_tests/custom-commands/loginToGUI.js
+++ b/test/nightwatch_tests/custom-commands/loginToGUI.js
@@ -1,17 +1,19 @@
 exports.command = function () {
 
   var client = this,
-      baseUrl = client.globals.baseUrl;
+      baseUrl = client.globals.test_settings.launch_url,
+      username = client.globals.test_settings.username,
+      password = client.globals.test_settings.password;
 
   client
     .url(baseUrl+'/#login')
     .waitForElementPresent('a[href="#login"]', 8000, false)
     .click('a[href="#login"]')
     .waitForElementPresent('#username', 8000, false)
-    .setValue('#username', ['tester'])
-    .setValue('#password', ['testerpass', client.Keys.ENTER])
+    .setValue('#username', [username])
+    .setValue('#password', [password, client.Keys.ENTER])
     .closeNotification()
     .waitForElementPresent('#jump-to-db', 8000, false);
-      
+
   return this;
 };

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/test/nightwatch_tests/helpers/helpers.js
----------------------------------------------------------------------
diff --git a/test/nightwatch_tests/helpers/helpers.js b/test/nightwatch_tests/helpers/helpers.js
index 388d5f4..645c9a6 100644
--- a/test/nightwatch_tests/helpers/helpers.js
+++ b/test/nightwatch_tests/helpers/helpers.js
@@ -1,12 +1,14 @@
 module.exports = {
-  username : 'tester',
-  password : 'testerpass',
-  baseUrl: 'http://localhost:8000',
+
   testDatabaseName : 'fauxton-selenium-tests',
+
   getNanoInstance : function () {
-    var nano = require('nano')('http://'+this.username+':'+this.password+'@localhost:5984');
-    return nano;
+    var user = this.test_settings.username,
+        pass = this.test_settings.password,
+        launch_url = this.test_settings.launch_url;
+    return require('nano')('http://' + user + ':' + pass + '@' + launch_url);
   },
+
   beforeEach: function (done) {
     var nano = module.exports.getNanoInstance(),
         database = module.exports.testDatabaseName;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/test/nightwatch_tests/nightwatch.json
----------------------------------------------------------------------
diff --git a/test/nightwatch_tests/nightwatch.json b/test/nightwatch_tests/nightwatch.json
index 1f74596..6481ab1 100644
--- a/test/nightwatch_tests/nightwatch.json
+++ b/test/nightwatch_tests/nightwatch.json
@@ -1,12 +1,10 @@
 {
-  "src_folders" : [
-    "./app/addons/databases/tests/nightwatch",
-    "./app/addons/documents/tests/nightwatch"
-    ],
+  "src_folders": ["app/addons/databases/tests/nightwatch","app/addons/documents/tests/nightwatch"],
+  "custom_commands_path": "test/nightwatch_tests/custom-commands",
+  "globals_path": "test/nightwatch_tests/helpers/helpers.js",
+
   "output_folder" : "./test/nightwatch_tests/reports",
-  "custom_commands_path" : "./test/nightwatch_tests/custom-commands",
   "custom_assertions_path" : "",
-  "globals_path" : "./test/nightwatch_tests/helpers/helpers.js",
   "live_output" : false,
 
   "selenium" : {
@@ -24,7 +22,9 @@
 
   "test_settings" : {
     "default" : {
-      "launch_url" : "http://localhost",
+      "username": "tester",
+      "password": "testerpass",
+      "launch_url" : "localhost:8000",
       "selenium_host" : "127.0.0.1",
       "selenium_port" : 4444,
       "silent" : true,
@@ -51,7 +51,6 @@
       }
     },
 
-
     "saucelabs" : {
       "selenium_host" : "ondemand.saucelabs.com",
       "selenium_port" : 80,

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e1e5353e/test/nightwatch_tests/nightwatch.json.underscore
----------------------------------------------------------------------
diff --git a/test/nightwatch_tests/nightwatch.json.underscore b/test/nightwatch_tests/nightwatch.json.underscore
new file mode 100644
index 0000000..1354b85
--- /dev/null
+++ b/test/nightwatch_tests/nightwatch.json.underscore
@@ -0,0 +1,102 @@
+{
+  "src_folders": <%= src_folders %>,
+  "custom_commands_path": <%= custom_commands_path %>,
+  "globals_path": "<%- globals_path %>",
+
+  "output_folder" : "./test/nightwatch_tests/reports",
+  "custom_assertions_path" : "",
+  "live_output" : false,
+
+  "selenium" : {
+    "start_process" : false,
+    "server_path" : "",
+    "log_path" : "",
+    "host" : "127.0.0.1",
+    "port" : 4444,
+    "cli_args" : {
+      "webdriver.chrome.driver" : "",
+      "webdriver.ie.driver" : "",
+      "webdriver.firefox.profile" : ""
+    }
+  },
+
+  "test_settings" : {
+    "default" : {
+      "username": "<%- username %>",
+      "password": "<%- password %>",
+      "launch_url" : "<%- launch_url %>",
+      "selenium_host" : "127.0.0.1",
+      "selenium_port" : 4444,
+      "silent" : true,
+      "disable_colors": false,
+      "screenshots" : {
+        "enabled" : false,
+        "path" : ""
+      },
+      "desiredCapabilities" : {
+        "browserName" : "firefox",
+        "javascriptEnabled" : true,
+        "acceptSslCerts" : true
+      }
+    },
+
+    "chrome" : {
+      "desiredCapabilities" : {
+        "browserName" : "chrome",
+        "javascriptEnabled" : true,
+        "acceptSslCerts" : true,
+        "chromeOptions" : {
+          "args" : ["window-size=1400,900"]
+        }
+      }
+    },
+
+    "saucelabs" : {
+      "selenium_host" : "ondemand.saucelabs.com",
+      "selenium_port" : 80,
+      "username" : "${SAUCE_USERNAME}",
+      "access_key" : "${SAUCE_ACCESS_KEY}",
+      "use_ssl" : false,
+      "silent" : true,
+      "output" : true,
+      "screenshots" : {
+        "enabled" : false,
+        "path" : ""
+      },
+      "desiredCapabilities": {
+        "name" : "test-example",
+        "browserName": "firefox"
+      },
+      "globals" : {
+        "myGlobal" : "some_sauce_global"
+      },
+      "selenium" : {
+        "start_process" : false
+      }
+    },
+
+    "phantomjs" : {
+      "desiredCapabilities" : {
+        "browserName" : "phantomjs",
+        "javascriptEnabled" : true,
+        "acceptSslCerts" : true,
+        "phantomjs.binary.path" : "/path/to/phantomjs"
+      }
+    },
+
+    "browserstack" : {
+      "selenium" : {
+        "start_process" : false
+      },
+      "selenium_host" : "hub.browserstack.com",
+      "selenium_port" : 80,
+      "silent" : true,
+      "desiredCapabilities": {
+        "name" : "test-example",
+        "browserName": "firefox",
+        "browserstack.user" : "...",
+        "browserstack.key" : "..."
+      }
+    }
+  }
+}


Mime
View raw message