-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeError: undefined is not a function #1
Comments
I spent a little bit of time digging around, and it looks like this issue (among others) is caused by the fact that this implementation hasn't been updated to work with Express 4, which is automatically installed when running First, config/setup.js has to go from this: function setup(app, express) {
app.configure('development', function() {
require("./development.js")(app, express);
});
app.configure('staging', function() {
require("./staging.js")(app, express);
});
app.configure('production', function() {
require("./production.js")(app, express);
});
}
module.exports = exports = setup; to this: function setup(app, express) {
if ('development' == app.get('env')) {
require("./development.js")(app, express);
}
if ('staging' == app.get('env')) {
require("./staging.js")(app, express);
}
if ('production' == app.get('env')) {
require("./production.js")(app, express);
}
}
module.exports = exports = setup; Second, grid.js (in the root folder) has to go from this: var express = require('express')
, routes = require('./routes')
, http = require('http')
, path = require('path')
, createNodeProxy = require('./routes/nodeproxy')
, setup = require('./config/setup.js')
, less = require('less-middleware')
, routes = require('./routes')
, security = require('connect-security')
;
var InMemoryUserProvider = require('connect-security/lib/service/inmemoryuserprovider')
, BasicAuthenticationFilter = require('connect-security/lib/filter/basicauthenticationfilter')
, BasicAuthenticationEntryPoint = require('connect-security/lib/entrypoint/basicauthenticationentrypoint')
;
var app = express();
setup(app, express);
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.engine('ejs', require('ejs-locals'));
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.cookieParser());
app.use(express.cookieSession({ key: 'testlabs-grid', secret: 'jdHU82*sH3!!laD' }));
app.use(security({
interceptUrls: [
{ url: /^\/(css|img|js)/, access: 'isAuthenticated()' },
{ url: /^\/admin/, access: 'hasRole("admin")' },
{ url: /^\/api/, access: 'isAuthenticated()' },
{ url: /^\//, access: 'hasRole("user")' }
],
filters: [
new BasicAuthenticationFilter({
userProvider : new InMemoryUserProvider({
users: app.get('users')
})
})
],
entryPoint: new BasicAuthenticationEntryPoint({
realmName: 'TestLabs Grid'
})
}))
// all requests to /wd/hub/* should be proxied through to a node.
app.use(createNodeProxy(app.get('host'), app.get('nodeStore'), app.get('sessionStore')));
// set correct content-type on register requests
app.use(function(req, res, next) {
if (req.method == 'POST' && /\/grid\/register/.test(req.path)) {
req.headers['content-type'] = 'application/json';
}
next();
});
app.use(express.bodyParser());
app.use(app.router);
app.use(less({ src: path.join(__dirname, 'public') }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(security.errorHandler());
});
routes(app);
http.createServer(app).listen(app.get('port'), function(){
console.log("TestLabs Grid listening on port " + app.get('port'));
}); To this: var express = require('express')
, routes = require('./routes')
, http = require('http')
, path = require('path')
, createNodeProxy = require('./routes/nodeproxy')
, setup = require('./config/setup.js')
, less = require('less-middleware')
, routes = require('./routes')
, security = require('connect-security')
;
var InMemoryUserProvider = require('connect-security/lib/service/inmemoryuserprovider')
, BasicAuthenticationFilter = require('connect-security/lib/filter/basicauthenticationfilter')
, BasicAuthenticationEntryPoint = require('connect-security/lib/entrypoint/basicauthenticationentrypoint')
;
var app = express();
setup(app, express);
app.set('port', process.env.PORT || 3000);
app.engine('ejs', require('ejs-locals'));
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.cookieParser());
app.use(express.cookieSession({ key: 'testlabs-grid', secret: 'jdHU82*sH3!!laD' }));
app.use(security({
interceptUrls: [
{ url: /^\/(css|img|js)/, access: 'isAuthenticated()' },
{ url: /^\/admin/, access: 'hasRole("admin")' },
{ url: /^\/api/, access: 'isAuthenticated()' },
{ url: /^\//, access: 'hasRole("user")' }
],
filters: [
new BasicAuthenticationFilter({
userProvider : new InMemoryUserProvider({
users: app.get('users')
})
})
],
entryPoint: new BasicAuthenticationEntryPoint({
realmName: 'TestLabs Grid'
})
}))
// all requests to /wd/hub/* should be proxied through to a node.
app.use(createNodeProxy(app.get('host'), app.get('nodeStore'), app.get('sessionStore')));
// set correct content-type on register requests
app.use(function(req, res, next) {
if (req.method == 'POST' && /\/grid\/register/.test(req.path)) {
req.headers['content-type'] = 'application/json';
}
next();
});
app.use(express.bodyParser());
app.use(app.router);
app.use(less({ src: path.join(__dirname, 'public') }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(security.errorHandler());
routes(app);
http.createServer(app).listen(app.get('port'), function(){
console.log("TestLabs Grid listening on port " + app.get('port'));
}); Then, there are a number of middleware that are no longer bundled with Express (which means they must be added to package.json and installed via npm) and whose name have changed:
That should take care of that. Now
and my terminal output on the server side:
Any ideas why that happens? |
Hey Laurent, Thanks for all of the information you've sent, we really appreciate it. We are no longer using Selenium Grid at all internally, so I guess that's But since you're considering using it, I think we can find some time this In the meantime, completely shameless plug, check out the tool this version Thanks for your patience, we'll speak soon. Steve Steve Walton On Thu, Feb 19, 2015 at 6:53 PM, Laurent Mazouer notifications@github.com
CONFIDENTIAL NOTICE Twenty Eight Automation Ltd is a company registered in England Wales No. |
Dear Steve, Thank you very much for getting back to me about this, and for taking time out of your busy schedule to fix it! Your help in getting this code going again will contribute a long way to what we're trying to accomplish: the only reason we're not using https://testlabs.io out-of-the-box is because our requirements are a little unusual, which is why your repo was the exact thing we needed. Rest assured that your team will get all of the credit they deserve once things get going on our side. Cheers, Laurent |
Hey Laurent, I've gone through and upgraded the dependencies etc.. Mostly like what you've given us but I've dropped a few things out that shouldn't be necessary. The latest error you're seeing is because by default we have BASIC auth enabled (as in our use case the grid was public). I've turned this off by default now so a simple update should get you going. Let me know how you go. Max |
Dear Max, Thanks for fixing this so quickly! I am now able to register both regular and PhantomJS instances as nodes to the Selenium Grid. However when I try to run a simple test scenario: from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
driver = webdriver.Remote(
command_executor='http://localhost:3000/wd/hub',
desired_capabilities=DesiredCapabilities.CHROME)
driver.get('http://www.google.com')
html = driver.page_source
print (html)
driver.close() which I got from
Do you have a sense of what could be going wrong? |
My first guess would be the node can't fine your Chrome driver - have you got the You should get an error message in the grid logs - if none of the above helps can you post your logs? |
After some fiddling around, it turns out the issue was related to Python's
There is mention of var id = req.param('id'); to: var id = req.query.id; and that should do the trick (please correct me if I'm wrong about this!) Now while this works brilliantly when using Chrome or Firefox and the official Selenium Server java code, things get hairier with PhantomJS... I can register a PhantomJS node without issues, but when I try to run a sample test scenario like this one: from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
driver = webdriver.Remote(
command_executor='http://localhost:3000/wd/hub',
desired_capabilities=DesiredCapabilities.PHANTOMJS)
driver.get("http://www.google.com")
html = driver.page_source
print (html)
driver.close() This is what I get on the server window:
(you're looking for the line with the [ERROR] header)
and this is what I get on the window where I'm running the test scenario:
Would you happen to know what's going on? |
A little more housekeeping - I found a few deprecated function calls in line 34 res.send(500, error); which should be res.status(500).send(error) line 61 res.send(503,
'Error forwarding new session request, no nodes available for desired capabilities.'); which should be res.status(503).send('Error forwarding new session request, no nodes available for desired capabilities.') line 84 res.send(302); which should be res.status(302) I haven't figured out the PhantomJS problem I exposed in my previous message however - did you have better luck @superafroman ? I can't seem to be able to run any sort of test scenario on a PhantomJS node, even thought attaching one to the Grid works... |
I believe the issue with case sensitive HTTP headers has only been fixed in PhantomJS 2.0 - which isn't supported by GhostDriver yet. Until that's updated you won't be able to use PhantomJS with this grid. |
After a bit of digging, I think you're right: from what I understand, there has been a fix upstream for this issue for over a year but nobody seems to care about PhantomJS enough to backport it and release a new version that includes the fix. In the meantime, we might experiment a headless Chromium + xvfb configuration instead. |
Not at all - absolutely happy to help! |
Quick question: I tried running
node grid.js
after having installed all the right dependencies for your NodeJS Selenium Grid implementation, and this is what I get:Any ideas?
The text was updated successfully, but these errors were encountered: