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

feat(driverProvider) Adding browserstackProxy param in BrowserStack driverProvider #4852

Merged
merged 5 commits into from
Jul 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ let allowedNames = [
'sauceSeleniumAddress',
'browserstackUser',
'browserstackKey',
'browserstackProxy',
'kobitonUser',
'kobitonKey',
'testobjectUser',
Expand Down
7 changes: 7 additions & 0 deletions lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,13 @@ export interface Config {
*/
browserstackKey?: string;

/**
* Proxy server to be used for connecting to BrowserStack APIs
* e.g. "http://proxy.example.com:1234".
* This should be used when you are behind a proxy server.
*/
browserstackProxy?: string;

// ---- 7. To connect directly to Drivers ------------------------------------

/**
Expand Down
91 changes: 42 additions & 49 deletions lib/driverProviders/browserStack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ import {Logger} from '../logger';

import {DriverProvider} from './driverProvider';

const BrowserstackClient = require('browserstack');

let logger = new Logger('browserstack');

export class BrowserStack extends DriverProvider {
browserstackClient: any;

constructor(config: Config) {
super(config);
}
Expand All @@ -30,58 +34,41 @@ export class BrowserStack extends DriverProvider {
updateJob(update: any): q.Promise<any> {
let deferredArray = this.drivers_.map((driver: WebDriver) => {
let deferred = q.defer();

driver.getSession().then((session: Session) => {
let headers = {
'Content-Type': 'application/json',
'Authorization': 'Basic ' +
new Buffer(this.config_.browserstackUser + ':' + this.config_.browserstackKey)
.toString('base64')
};
let options = {
hostname: 'www.browserstack.com',
port: 443,
path: '/automate/sessions/' + session.getId() + '.json',
method: 'GET',
headers: headers
};

let req = https.request(options, (res) => {
res.on('data', (data: Buffer) => {
let info = JSON.parse(data.toString());
if (info && info.automation_session && info.automation_session.browser_url) {
logger.info(
'BrowserStack results available at ' + info.automation_session.browser_url);
} else {
logger.info(
'BrowserStack results available at ' +
'https://www.browserstack.com/automate');
}
});
});
req.end();
req.on('error', (e: Error) => {
logger.info(
'BrowserStack results available at ' +
'https://www.browserstack.com/automate');
});
// Fetching BrowserStack session details.
this.browserstackClient.getSession(
session.getId(), function(error: Error, automate_session: any) {
if (error) {
logger.info(
'BrowserStack results available at ' +
'https://www.browserstack.com/automate');
} else {
if (automate_session && automate_session.browser_url) {
logger.info('BrowserStack results available at ' + automate_session.browser_url);
} else {
logger.info(
'BrowserStack results available at ' +
'https://www.browserstack.com/automate');
}
}
});

let jobStatus = update.passed ? 'completed' : 'error';
options.method = 'PUT';
let update_req = https.request(options, (res) => {
let responseStr = '';
res.on('data', (data: Buffer) => {
responseStr += data.toString();
});
res.on('end', () => {
logger.info(responseStr);
deferred.resolve();
});
res.on('error', (e: Error) => {
throw new BrowserError(
logger, 'Error updating BrowserStack pass/fail status: ' + util.inspect(e));
});
});
update_req.write('{"status":"' + jobStatus + '"}');
update_req.end();
let statusObj = {status: jobStatus};

// Updating status of BrowserStack session.
this.browserstackClient.updateSession(
session.getId(), statusObj, function(error: Error, automate_session: any) {
if (error) {
throw new BrowserError(
logger, 'Error updating BrowserStack pass/fail status: ' + util.inspect(error));
} else {
logger.info(automate_session);
deferred.resolve();
}
});
});
return deferred.promise;
});
Expand All @@ -99,6 +86,12 @@ export class BrowserStack extends DriverProvider {
this.config_.capabilities['browserstack.key'] = this.config_.browserstackKey;
this.config_.seleniumAddress = 'http://hub.browserstack.com/wd/hub';

this.browserstackClient = BrowserstackClient.createAutomateClient({
username: this.config_.browserstackUser,
password: this.config_.browserstackKey,
proxy: this.config_.browserstackProxy
Copy link
Contributor

@qiyigg qiyigg Jun 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this.config_.browserstackProxy is not set, will it break this code? It would be better to have a test for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added test for browserStack driverProvider's basic functionality check.
It will not break by this.
And tests are now failing in circleci with error "Error: does not exist in logs: WebDriverError: Sauce Labs Authentication Error." and in travis due to some reason. I think there is some issue with Sauce labs credentials, can you please check and review this PR.

});

// Append filename to capabilities.name so that it's easier to identify
// tests.
if (this.config_.capabilities.name && this.config_.capabilities.shardTestFiles) {
Expand Down
8 changes: 8 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@types/q": "^0.0.32",
"@types/selenium-webdriver": "~2.53.39",
"blocking-proxy": "^1.0.0",
"browserstack": "^1.5.1",
"chalk": "^1.1.3",
"glob": "^7.0.3",
"jasmine": "2.8.0",
Expand Down
2 changes: 1 addition & 1 deletion scripts/errorTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var checkLogs = function(output, messages) {
runProtractor = spawn('node',
['bin/protractor', 'spec/errorTest/sauceLabsAuthentication.js']);
output = runProtractor.stdout.toString();
messages = ['WebDriverError: Sauce Labs Authentication Error.',
messages = ['WebDriverError: Misconfigured -- Sauce Labs Authentication Error.',
'Process exited with error code ' + exitCodes.BrowserError.CODE];
checkLogs(output, messages);

Expand Down
22 changes: 21 additions & 1 deletion spec/driverprovider_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* - selenium jar and chromedriver in protractor/selenium, where
* webdriver-manager stores them.
* - if you want to test saucelabs, test with --sauceUser and --sauceKey
*
* - if you want to test browserstack driverProvider, test with
--browserstackUser and --browserstackKey
* You should verify that there are no lingering processes when these tests
* complete.
*/
Expand All @@ -19,6 +20,7 @@ var Direct = require('../built/driverProviders/direct').Direct;
var Hosted = require('../built/driverProviders/hosted').Hosted;
var Local = require('../built/driverProviders/local').Local;
var Sauce = require('../built/driverProviders/sauce').Sauce;
var BrowserStack = require('../built/driverProviders/browserStack').BrowserStack;

var testDriverProvider = function(driverProvider) {
return driverProvider.setupEnv().then(function() {
Expand Down Expand Up @@ -124,3 +126,21 @@ if (argv.sauceUser && argv.sauceKey) {
console.log('sauce.dp failed with ' + err);
});
}

if (argv.browserstackUser && argv.browserstackKey) {
var browserStackConfig = {
browserstackUser: argv.browserstackUser,
browserstackKey: argv.browserstackKey,
capabilities: {
'build': 'protractor-browserstack-spec',
'name': 'protractor-browserstack-spec',
'browserName': 'chrome',
}
};
testDriverProvider(new BrowserStack(browserStackConfig)).
then(function() {
console.log('browserstack.dp working!');
}, function(err) {
console.log('browserstack.dp failed with ' + err);
});
}