[only-proxy-mode] Enable only proxy mode for when Selenium is elsewhere

This commit is contained in:
John Bintz 2016-03-31 14:36:51 -04:00
parent 3e34842eb2
commit 576ec2b73b
4 changed files with 106 additions and 80 deletions

View File

@ -12,3 +12,10 @@ to recreate my RSpec/Cucumber + Capybara setup purely in JavaScript!
`npm install -g persistent_selenium`, then `persistent_selenium`. Point
your Selenium client to `http://localhost:4443/wd/hub`. Test away!
### Command Line Arguments
* `--only-proxy`: Do not download/start Selenium server locally
* `--selenium-host`: The host on which a Selenium server is running (default localhost)
* `--selenium-port`: The port on which a selenium server is running (default 4444)
* Additional arguments are passed directly to a locally running Selenium server on starting

101
index.js
View File

@ -1,89 +1,30 @@
var selenium = require('selenium-standalone');
var proxy = require('express-http-proxy');
var Request = require('request');
var minimist = require('minimist');
var app = require('express')();
var currentSession = null;
var currentSessionObj = null;
var seleniumPort = 4444;
var arg = minimist(
process.argv.slice(2),
{ boolean: ['only-proxy'] }
);
var initBrowser = function(cb) {
Request({
method: 'post',
url: 'http://localhost:' + seleniumPort + '/wd/hub/session/' + currentSession + '/url',
json: { url: "data:text/html;charset=utf-8;base64,PGh0bWw+PGhlYWQ+PHRpdGxlPm5vZGUtcGVyc2lzdGVudF9zZWxlbml1bTwvdGl0bGU+PGhlYWQ+PGJvZHk+PGgxPm5vZGUtcGVyc2lzdGVudF9zZWxlbml1bSBzdGFydGluZy4uLjwvaDE+PC9ib2R5PjwvaHRtbD4=" }
}, function(err, response, body) {
cb();
});
var app = require('./proxy');
app.config = arg;
function run() {
console.log("Persistent selenium listening on port 4443");
app.listen(arg['app-port'] || 4443);
};
app.use(proxy('localhost', {
filter: function(req, res) {
if (currentSession) {
if (req.path === '/wd/hub/session/' + currentSession &&
req.method.toLowerCase() === 'delete') {
req._wasDelete = true;
}
if (req.path === '/wd/hub/session' &&
req.method.toLowerCase() === 'post') {
req._wasCreate = true;
}
}
return true;
},
decorateRequest: function(req) {
req.port = seleniumPort;
if (currentSession) {
if (req.path === '/wd/hub/session/' + currentSession &&
req.method.toLowerCase() === 'delete') {
req.method = 'GET';
req.path = '/wd/hub/sessions';
}
if (req.path === '/wd/hub/session' &&
req.method.toLowerCase() === 'post') {
req.method = 'GET';
req.path = '/wd/hub/sessions';
}
}
return req;
},
intercept: function(origRes, data, req, res, callback) {
if (!currentSession && req.url === '/wd/hub/session' &&
req.method.toLowerCase() === 'post') {
currentSessionObj = JSON.parse(data.toString('utf-8'));
currentSession = currentSessionObj.sessionId;
initBrowser(function() { callback(null, data); });
} else {
if (req._wasCreate) {
data = JSON.stringify(currentSessionObj);
initBrowser(function() { callback(null, data); });
if (arg['only-proxy']) {
run();
} else {
selenium.install({ logger: function(msg) { console.log(msg); }}, function(instErr) {
selenium.start({ spawnOptions: {}, seleniumArgs: arg._ }, function(startErr) {
if (startErr) {
console.log(startErr);
} else {
if (req._wasDelete) {
callback(null, JSON.stringify('{}'));
} else {
callback(null, data);
}
run();
}
}
}
}));
var seleniumArgs = process.argv.slice(2);
selenium.install({ logger: function(msg) { console.log(msg); }}, function(err) {
selenium.start({ spawnOptions: {}, seleniumArgs: seleniumArgs }, function(err) {
if (err) {
console.log(err);
} else {
console.log("Persistent selenium listening on port 4443");
app.listen(4443);
}
});
});
});
}

View File

@ -15,6 +15,7 @@
"dependencies": {
"express": "^4.12.4",
"express-http-proxy": "^0.6.0",
"minimist": "^1.2.0",
"request": "^2.57.0",
"selenium-standalone": "^4.4.2"
},

77
proxy.js Normal file
View File

@ -0,0 +1,77 @@
var app = require('express')();
var proxy = require('express-http-proxy');
var currentSession = null;
var currentSessionObj = null;
function initBrowser(cb) {
var seleniumPort = app.config['selenium-port'] || 4444;
var seleniumHost = app.config['selenium-host'] || 'localhost';
Request({
method: 'post',
url: 'http://' + seleniumHost + ':' + seleniumPort + '/wd/hub/session/' + currentSession + '/url',
json: { url: "data:text/html;charset=utf-8;base64,PGh0bWw+PGhlYWQ+PHRpdGxlPm5vZGUtcGVyc2lzdGVudF9zZWxlbml1bTwvdGl0bGU+PGhlYWQ+PGJvZHk+PGgxPm5vZGUtcGVyc2lzdGVudF9zZWxlbml1bSBzdGFydGluZy4uLjwvaDE+PC9ib2R5PjwvaHRtbD4=" }
}, function(err, response, body) {
cb();
});
};
app.use(proxy('localhost', {
filter: function(req, res) {
if (currentSession) {
if (req.path === '/wd/hub/session/' + currentSession &&
req.method.toLowerCase() === 'delete') {
req._wasDelete = true;
}
if (req.path === '/wd/hub/session' &&
req.method.toLowerCase() === 'post') {
req._wasCreate = true;
}
}
return true;
},
decorateRequest: function(req) {
req.port = app.config['selenium-port'] || 4444;
if (currentSession) {
if (req.path === '/wd/hub/session/' + currentSession &&
req.method.toLowerCase() === 'delete') {
req.method = 'GET';
req.path = '/wd/hub/sessions';
}
if (req.path === '/wd/hub/session' &&
req.method.toLowerCase() === 'post') {
req.method = 'GET';
req.path = '/wd/hub/sessions';
}
}
return req;
},
intercept: function(origRes, data, req, res, callback) {
if (!currentSession && req.url === '/wd/hub/session' &&
req.method.toLowerCase() === 'post') {
currentSessionObj = JSON.parse(data.toString('utf-8'));
currentSession = currentSessionObj.sessionId;
initBrowser(function() { callback(null, data); });
} else {
if (req._wasCreate) {
data = JSON.stringify(currentSessionObj);
initBrowser(function() { callback(null, data); });
} else {
if (req._wasDelete) {
callback(null, JSON.stringify('{}'));
} else {
callback(null, data);
}
}
}
}
}));
module.exports = app;