Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

Commit 7015010

Browse files
vedharishsjelin
authored andcommitted
feat(driver providers): Add BrowserStack support.
Also added BrowserStack to CI Closes #1013
1 parent 000f119 commit 7015010

10 files changed

+190
-20
lines changed

.travis.yml

+8-3
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,34 @@ env:
88
global:
99
- SAUCE_USERNAME=angular-ci
1010
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
11+
- BROWSER_STACK_USERNAME=angularteam1
12+
- BROWSER_STACK_ACCESS_KEY=BWCd4SynLzdDcv8xtzsB
1113
- LOGS_DIR=/tmp/protractor-build/logs
1214
- BROWSER_PROVIDER_READY_FILE=/tmp/sauce-connect-ready
1315
matrix:
1416
- JOB=full
1517
- JOB=smoke
18+
- JOB=bstack
1619

1720
matrix:
1821
allow_failures:
1922
- env: "JOB=smoke"
23+
- env: "JOB=bstack"
2024
exclude:
2125
- env: JOB=smoke
2226
node_js: "5"
27+
- env: JOB=bstack
28+
node_js: "5"
2329

2430

2531
before_script:
2632
- npm run pretest
2733
- mkdir -p $LOGS_DIR
28-
- ./scripts/sauce_connect_setup.sh
29-
- ./scripts/wait_for_browser_provider.sh
34+
- ./scripts/travis_setup.sh
3035

3136
script:
3237
- ./scripts/testserver.sh
33-
- ./scripts/testonsauce.sh
38+
- ./scripts/test_on_travis.sh
3439

3540
after_script:
3641
- ./scripts/print_logs.sh

docs/referenceConf.js

+16-4
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ exports.config = {
1414
//
1515
// Protractor needs to know how to connect to Drivers for the browsers
1616
// it is testing on. This is usually done through a Selenium Server.
17-
// There are four options - specify one of the following:
17+
// There are five options - specify one of the following:
1818
//
1919
// 1. seleniumServerJar - to start a standalone Selenium Server locally.
2020
// 2. seleniumAddress - to connect to a Selenium Server which is already
2121
// running.
2222
// 3. sauceUser/sauceKey - to use remote Selenium Servers via Sauce Labs.
23-
// 4. directConnect - to connect directly to the browser Drivers.
23+
// 4. browserstackUser/browserstackKey - to use remote Selenium Servers via BrowserStack.
24+
// 5. directConnect - to connect directly to the browser Drivers.
2425
// This option is only available for Firefox and Chrome.
2526

2627
// ---- 1. To start a standalone Selenium Server locally ---------------------
@@ -63,7 +64,13 @@ exports.config = {
6364
// ondemand.saucelabs.com:80/wd/hub
6465
sauceSeleniumAddress: null,
6566

66-
// ---- 4. To connect directly to Drivers ------------------------------------
67+
// ---- 4. To use remote browsers via BrowserStack ---------------------------
68+
// If browserstackUser and browserstackKey are specified, seleniumServerJar will be ignored.
69+
// The tests will be run remotely using BrowserStack.
70+
browserstackUser: null,
71+
browserstackKey: null,
72+
73+
// ---- 5. To connect directly to Drivers ------------------------------------
6774
// Boolean. If true, Protractor will connect directly to the browser Drivers
6875
// at the locations specified by chromeDriver and firefoxPath. Only Chrome
6976
// and Firefox are supported for direct connect.
@@ -110,7 +117,7 @@ exports.config = {
110117

111118
// Name of the process executing this capability. Not used directly by
112119
// protractor or the browser, but instead pass directly to third parties
113-
// like SauceLabs as the name of the job running this test
120+
// like BrowserStack and SauceLabs as the name of the job running this test
114121
name: 'Unnamed Job',
115122

116123
// User defined name for the capability that will display in the results log
@@ -139,6 +146,11 @@ exports.config = {
139146

140147
// Optional: override global seleniumAddress on this capability only.
141148
seleniumAddress: null
149+
150+
// Optional: Additional third-party specific capabilities can be
151+
// specified here.
152+
// For a list of BrowserStack specific capabilities, visit
153+
// https://www.browserstack.com/automate/capabilities
142154
},
143155

144156
// If you would like to run more than one instance of WebDriver on the same

docs/server-setup.md

+16-4
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,33 @@ To connect to a running instance of a standalone Selenium Server, set this optio
5555

5656
- `seleniumAddress` - Connect to a running instance of a standalone Selenium Server. The address will be a URL.
5757

58-
Please note that if you set seleniumAddress, the settings for `seleniumServerJar`, `seleniumPort`, `seleniumArgs`, `sauceUser` and `sauceKey` will be ignored.
58+
Please note that if you set seleniumAddress, the settings for `seleniumServerJar`, `seleniumPort`, `seleniumArgs`, `browserstackUser`, `browserstackKey`, `sauceUser` and `sauceKey` will be ignored.
5959

6060

6161
Remote Selenium Server
6262
----------------------
6363

64-
To run your tests against a remote Selenium Server, you will need an account with a service that hosts the server (and the browser drivers). Protractor has built in support for [Sauce Labs](http://www.saucelabs.com).
64+
To run your tests against a remote Selenium Server, you will need an account with a service that hosts the server (and the browser drivers). Protractor has built in support for [BrowserStack](https://www.browserstack.com) and [Sauce Labs](http://www.saucelabs.com).
65+
66+
**Using BrowserStack as remote Selenium Server**
67+
68+
In your config file, set these options:
69+
- `browserstackUser` - The username for your BrowserStack account.
70+
- `browserstackKey` - The key for your BrowserStack account.
71+
72+
Please note that if you set `browserstackUser` and `browserstackKey`, the settings for `seleniumServerJar`, `seleniumPort`, `seleniumArgs`, `sauceUser` and `sauceKey` will be ignored.
73+
74+
You can optionally set the [`name` property](referenceConf.js#L121) in a capability in order to give the jobs a name on the server. Otherwise they will just be allotted a random hash.
75+
76+
**Using Sauce Labs as remote Selenium Server**
6577

6678
In your config file, set these options:
6779
- `sauceUser` - The username for your Sauce Labs account.
6880
- `sauceKey` - The key for your Sauce Labs account.
6981

70-
Please note that if you set `sauceUser` and `sauceKey`, the settings for `seleniumServerJar`, `seleniumPort` and `seleniumArgs` will be ignored.
82+
Please note that if you set `sauceUser` and `sauceKey`, the settings for `seleniumServerJar`, `seleniumPort`, `seleniumArgs`, `browserstackUser` and `browserstackKey` will be ignored.
7183

72-
You can optionally set the [`name` property](referenceConf.js#L113) in a capability in order to give the jobs a name on the server. Otherwise they will just be called `Unnamed Job`.
84+
You can optionally set the [`name` property](referenceConf.js#L121) in a capability in order to give the jobs a name on the server. Otherwise they will just be called `Unnamed Job`.
7385

7486

7587
Connecting Directly to Browser Drivers

lib/driverProviders/browserstack.js

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* This is an implementation of the Browserstack Driver Provider.
3+
* It is responsible for setting up the account object, tearing
4+
* it down, and setting up the driver correctly.
5+
*/
6+
7+
var util = require('util'),
8+
log = require('../logger.js'),
9+
request = require('request'),
10+
q = require('q'),
11+
DriverProvider = require('./driverProvider');
12+
13+
14+
var BrowserStackDriverProvider = function(config) {
15+
DriverProvider.call(this, config);
16+
};
17+
util.inherits(BrowserStackDriverProvider, DriverProvider);
18+
19+
20+
/**
21+
* Hook to update the BrowserStack job status.
22+
* @public
23+
* @param {Object} update
24+
* @return {q.promise} A promise that will resolve when the update is complete.
25+
*/
26+
BrowserStackDriverProvider.prototype.updateJob = function(update) {
27+
28+
var self = this;
29+
var deferredArray = this.drivers_.map(function(driver) {
30+
var deferred = q.defer();
31+
driver.getSession().then(function(session) {
32+
var jobStatus = update.passed ? 'completed' : 'error';
33+
log.puts('BrowserStack results available at ' +
34+
'https://www.browserstack.com/automate');
35+
request({
36+
url: 'https://www.browserstack.com/automate/sessions/' +
37+
session.getId() + '.json',
38+
headers: {
39+
'Content-Type': 'application/json',
40+
'Authorization': 'Basic ' + new Buffer(self.config_.browserstackUser
41+
+ ':' + self.config_.browserstackKey).toString('base64')
42+
},
43+
method: 'PUT',
44+
form: {
45+
'status': jobStatus
46+
}
47+
}, function(error){
48+
if (error) {
49+
throw new Error(
50+
'Error updating BrowserStack pass/fail status: ' +
51+
util.inspect(error)
52+
);
53+
}
54+
});
55+
deferred.resolve();
56+
});
57+
return deferred.promise;
58+
});
59+
return q.all(deferredArray);
60+
};
61+
62+
/**
63+
* Configure and launch (if applicable) the object's environment.
64+
* @public
65+
* @return {q.promise} A promise which will resolve when the environment is
66+
* ready to test.
67+
*/
68+
BrowserStackDriverProvider.prototype.setupEnv = function() {
69+
var deferred = q.defer();
70+
this.config_.capabilities['browserstack.user'] =
71+
this.config_.browserstackUser;
72+
this.config_.capabilities['browserstack.key'] = this.config_.browserstackKey;
73+
this.config_.seleniumAddress = 'http://hub.browserstack.com/wd/hub';
74+
75+
// Append filename to capabilities.name so that it's easier to identify tests.
76+
if (this.config_.capabilities.name &&
77+
this.config_.capabilities.shardTestFiles) {
78+
this.config_.capabilities.name += (
79+
':' + this.config_.specs.toString().replace(/^.*[\\\/]/, ''));
80+
}
81+
82+
log.puts('Using BrowserStack selenium server at ' +
83+
this.config_.seleniumAddress);
84+
deferred.resolve();
85+
return deferred.promise;
86+
};
87+
88+
// new instance w/ each include
89+
module.exports = function(config) {
90+
return new BrowserStackDriverProvider(config);
91+
};

lib/runner.js

+2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ Runner.prototype.loadDriverProvider_ = function() {
9494
runnerPath = './driverProviders/direct';
9595
} else if (this.config_.seleniumAddress) {
9696
runnerPath = './driverProviders/hosted';
97+
} else if (this.config_.browserstackUser && this.config_.browserstackKey) {
98+
runnerPath = './driverProviders/browserstack';
9799
} else if (this.config_.sauceUser && this.config_.sauceKey) {
98100
runnerPath = './driverProviders/sauce';
99101
} else if (this.config_.seleniumServerJar) {

scripts/browserstack_local_setup.sh

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
curl -sO https://www.browserstack.com/browserstack-local/BrowserStackLocal-linux-x64.zip
2+
unzip BrowserStackLocal-linux-x64.zip -d local
3+
./local/BrowserStackLocal ` echo $BROWSER_STACK_ACCESS_KEY | rev ` &

scripts/test_on_travis.sh

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
SAUCE_ACCESS_KEY=`echo $SAUCE_ACCESS_KEY | rev`
2+
BROWSER_STACK_ACCESS_KEY=`echo $BROWSER_STACK_ACCESS_KEY | rev`
3+
4+
if [ $JOB = "smoke" ]; then
5+
node bin/protractor spec/ciSmokeConf.js
6+
elif [ $JOB = "full" ]; then
7+
node bin/protractor spec/ciFullConf.js
8+
elif [ $JOB = "bstack" ]; then
9+
node bin/protractor spec/ciBStackConf.js
10+
else
11+
echo "Unknown job type. Please set JOB=smoke, JOB=full, or JOB=bstack"
12+
fi

scripts/testonsauce.sh

-9
This file was deleted.

scripts/travis_setup.sh

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
if [ $JOB == "bstack" ]; then
2+
./scripts/browserstack_local_setup.sh
3+
else
4+
./scripts/sauce_connect_setup.sh
5+
./scripts/wait_for_browser_provider.sh
6+
fi

spec/ciBStackConf.js

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
var env = require('./environment.js');
2+
3+
// The main suite of Protractor tests.
4+
exports.config = {
5+
browserstackUser: process.env.BROWSER_STACK_USERNAME,
6+
browserstackKey: process.env.BROWSER_STACK_ACCESS_KEY,
7+
8+
framework: 'jasmine',
9+
10+
// Spec patterns are relative to this directory.
11+
specs: [
12+
'basic/*_spec.js'
13+
],
14+
15+
// Exclude patterns are relative to this directory.
16+
exclude: [
17+
'basic/exclude*.js'
18+
],
19+
20+
capabilities: env.capabilities,
21+
22+
baseUrl: env.baseUrl,
23+
24+
jasmineNodeOpts: {
25+
isVerbose: true,
26+
realtimeFailure: true
27+
},
28+
29+
params: {
30+
login: {
31+
user: 'Jane',
32+
password: '1234'
33+
}
34+
}
35+
};
36+
exports.config.capabilities['browserstack.local'] = true;

0 commit comments

Comments
 (0)