-
-
Save And93/1d99132ca46e0323b66fb1163da587dc to your computer and use it in GitHub Desktop.
Little nodejs http server for serving users to protractor parallel runs, so each thread will get unique user.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by akhotemskyi on 8/18/16. | |
*/ | |
const request = require('request'); | |
let http = require('http'); | |
let accounts; | |
let server; | |
/** | |
* Accepts array of object with users, that should be served thru HTTP server. | |
* This needs to provide reliable way to get user for parallel test run. | |
* | |
* Array example - [{username: name, password: passw}, {username:name, password: passwd} ... ] | |
* | |
* Think of this as external users provider. | |
* | |
* GET /get - replies with one of the available users, removes it from list of available users | |
* GET /return?account=accountName - puts back user to list of available users, replies with user that was returned | |
* GET /list - replies with JSON with list of available users | |
* | |
* Why do we need separate server, can we just use global object? | |
* Unfortunately no - global object is not shared between all browser instances, so each will get their own list. | |
* In order to have list of accounts as singleton, we are storing it in this server. | |
* | |
*/ | |
exports.startAccountProviderService = function (providedAccounts) { | |
accounts = providedAccounts; | |
const PORT = 12000; //TODO: Hardcoded, find way to dynamically find free port | |
const ADDRESS = `http://localhost:${PORT}` | |
function accountProviderService(request, response) { | |
if (request.url.includes('/get')) { | |
let account = accounts.pop(); | |
response.end(JSON.stringify(account)); | |
console.log(`Account Provider Service: Providing User - ${JSON.stringify(account)}`); | |
} else if (request.url.includes('/return')) { | |
var url = require('url'); | |
var query = url.parse(request.url, true).query; | |
let account = { username: query.username, password: query.password }; | |
accounts.push(account); | |
response.end(JSON.stringify(account)); | |
console.log(`Account Provider Service: User Returned - ${JSON.stringify(account)}`); | |
} else if (request.url.includes('/list')) { | |
response.end(JSON.stringify(JSON.stringify(account))); | |
} | |
} | |
server = http.createServer(accountProviderService); | |
server.listen(PORT, function () { | |
console.log("userProviderService server listening on: http://localhost:%s", PORT); | |
console.log('userProviderService has the following accounts to choose from:'); | |
console.log(accounts); | |
}); | |
server.unref(); // Making server die when node app (our tests) is dead or finished. So there won't be zombie process. | |
}; | |
/** | |
* Receive user from running service, and put it to browser.params. | |
* Do not forget to call returnUser(user) when you no longer need it, or you will run out of accounts. | |
* @returns Promise, that will be resolved once user obtained and saved to params. | |
*/ | |
exports.putUserToParams = function () { | |
var deferred = protractor.promise.defer(); | |
request.get({ url: `${ADDRESS}/get` }, (error, response, body) => { | |
if (error || response.statusCode !== 200) { | |
console.error(`Account Provider Service: Error on attempt to GET http://localhost:12000/get : ${response.statusCode} : ${error}`); | |
} | |
let account = JSON.parse(body); | |
browser.params.user.name = account.username; | |
browser.params.user.password = account.password; | |
console.log('Account Provider Service: Pushing to params:'); | |
console.log(' params.user.name = ' + browser.params.user.name); | |
console.log(' params.user.password = ' + browser.params.user.password); | |
deferred.fulfill(account) | |
}); | |
return deferred.promise; | |
}; | |
/** | |
* Returns user from browser.params by default, or your provided user back to server, so it could be used by other threads. | |
* @param userObject special formated object to return | |
*/ | |
exports.returnUser = function (userObject = { username: browser.params.user.name, password: browser.params.user.password }) { | |
request.get({ | |
url: `${ADDRESS}/return`, | |
qs: userObject | |
}, (error, response, body) => { | |
if (error || response.statusCode !== 200) { | |
console.error(`Account Provider Service: Error on attempt to GET ${ADDRESS}/return : ${response.statusCode} : ${error}`); | |
} | |
console.log('Account Provider Service: Returning:'); | |
console.log(' params.user.name = ' + userObject.username); | |
console.log(' params.user.password = ' + userObject.password); | |
} | |
); | |
}; | |
/** | |
* Get all free users from that are available to receive and use. | |
* Used for debug purposes. | |
* @returns Promise -> [userObject] array, special formatted | |
*/ | |
exports.getUsersList = function () { | |
var deferred = protractor.promise.defer(); | |
request.get({ | |
url: `${ADDRESS}/list`, | |
}, (error, response, body) => { | |
let accounts = JSON.parse(body); | |
deferred.fulfill(accounts); | |
}); | |
return deferred.promise; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const accountProviderService = require('./accountProviderService.js'); | |
const accounts = [ | |
{ username: 'test', password: '123456' }, | |
{ username: 'test2', password: '123456' }, | |
{ username: 'test3', password: '123456' } | |
] | |
exports.config = { | |
// Just example, this config should be updated with your settings. | |
beforeLaunch: function () { | |
accountProviderService.startAccountProviderService(accounts); | |
}, | |
onPrepare: function () { | |
accountProviderService.putUserToParams(); | |
}, | |
onComplete: function () { | |
accountProviderService.returnUser(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function login(user) { | |
browser.get('/') | |
console.log('Using user: ${user} to login`) | |
$('input.username').sendKeys(user.username) | |
$('input.password').sendKeys(user.password) | |
$('button.login').click() | |
} | |
describe('Login test example', function () { | |
login(browser.params.user) | |
expect(new HomePage().isLoaded()).toBeTruthy('Home page should be loaded after login') | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment