Permalink
Browse files

Merge pull request #47 from bnoguchi/multi-host

Several changes, enabling testing of OAuth Consumer flows
  • Loading branch information...
2 parents edcf666 + 4fd16e3 commit 6fb8c86f19acdba2c08264c549a03f469911f043 @rauchg rauchg committed Jul 1, 2011
Showing with 141 additions and 16 deletions.
  1. +56 −15 lib/browser.js
  2. +1 −1 lib/jquery/index.js
  3. +84 −0 test/browser.navigation.test.js
View
@@ -15,6 +15,7 @@ var EventEmitter = require('events').EventEmitter
, jsdom = require('jsdom')
, jQuery = require('./jquery/core')
, url = require('url')
+ , https = require('https')
, http = require('http');
/**
@@ -61,6 +62,7 @@ var Browser = module.exports = exports = function Browser(html, options, c) {
} else {
this.server = html;
}
+ this.https = (port === 443);
};
/**
@@ -114,6 +116,26 @@ Browser.prototype.context = function(selector, fn){
return this;
};
+Browser.prototype.hostBrowser = function(uri) {
+ var otherHostname = uri.hostname
+ , port = uri.port || (uri.protocol === 'https:' ? 443 : (this.port || 80))
+ , browsers = Browser.browsers
+ , otherBrowser;
+ if (!browsers) {
+ browsers = Browser.browsers = {};
+ }
+ if (!browsers[this.host]) {
+ browsers[this.host] = this;
+ }
+ otherBrowser = browsers[otherHostname];
+ if (!otherBrowser) {
+ otherBrowser =
+ browsers[otherHostname] = new Browser(port, otherHostname);
+ otherBrowser.userAgent = this.userAgent;
+ }
+ return otherBrowser;
+};
+
/**
* Request `path` with `method` and callback `fn(jQuery)`.
*
@@ -148,33 +170,45 @@ Browser.prototype.request = function(method, path, options, fn, saveHistory){
return;
}
+ var uri, otherHostname, otherBrowser;
+ if (path.substring(0, 4) === 'http') {
+ // If we have a full uri, not a uri path, then convert the full uri to a path
+ uri = url.parse(path);
+ path = uri.pathname + (uri.search || '');
+ otherHostname = uri.hostname;
+ if (otherHostname &&
+ (otherHostname !== 'undefined') &&
+ (otherHostname !== host)) {
+ otherBrowser = this.hostBrowser(uri);
+ return otherBrowser.request(method, path, options, fn, saveHistory);
+ }
+ }
+
+
// Save history
if (false !== saveHistory) this.history.push(path);
// Cookies
var cookies = this.cookieJar.cookieString({ url: path });
if (cookies) headers.Cookie = cookies;
+ // User-Agent
+ if (this.userAgent) headers['User-Agent'] = this.userAgent;
+
// Request body
if (options.body) {
headers['Content-Length'] = options.body.length;
headers['Content-Type'] = headers['Content-Type'] || 'application/x-www-form-urlencoded';
}
// Request
- headers.Host = host;
-
- // HTTP client
- if (!this.client) {
- // portno & host supplied
- if (this.port && this.host) {
- this.client = http.createClient(this.port, this.host);
- } else {
- this.client = http.createClient(server.__port);
- }
- }
-
- var req = this.client.request(method, path, headers);
+ var req = (this.https ? https : http).request({
+ method: method
+ , path: path
+ , port: this.host ? this.port : (server && server.__port)
+ , host: this.host
+ , headers: headers
+ });
req.on('response', function(res){
var status = res.statusCode
, buf = '';
@@ -225,10 +259,17 @@ Browser.prototype.request = function(method, path, options, fn, saveHistory){
// Redirect
} else if (status >= 300 && status < 400) {
var location = res.headers.location
- , path = url.parse(location).pathname;
+ , uri = url.parse(location)
+ , path = uri.pathname + (uri.search || '');
+ otherHostname = uri.hostname;
+ if (otherHostname &&
+ (otherHostname !== 'undefined') &&
+ (otherHostname !== self.host)) {
+ self = self.hostBrowser(uri);
+ }
self.emit('redirect', location);
if (self.followRedirects) {
- self.request('GET', path, options, fn);
+ self.request('GET', path, {}, fn);
} else {
return fn(res);
}
View
@@ -117,7 +117,7 @@ module.exports = function(browser, $){
if (!url) throw new Error('failed to click ' + locator + ', ' + prop + ' not present');
// Perform request
- browser[method](url, options, fn);
+ browser[method.toLowerCase()](url, options, fn);
return this;
};
@@ -218,6 +218,52 @@ module.exports = {
});
});
},
+
+ 'test .request(method, url)': function(done){
+ var browser = tobi.createBrowser(app);
+ browser.request('GET', 'http://127.0.0.1:' + app.__port, {}, function(res, $){
+ res.should.have.status(200);
+ browser.should.have.property('path', '/');
+ browser.history.should.eql(['/']);
+ browser.request('GET', 'http://127.0.0.1:' + app.__port + '/user/0', {}, function(){
+ browser.should.have.property('path', '/user/0');
+ browser.history.should.eql(['/', '/user/0']);
+ browser.should.have.property('source', '<h1>Tobi</h1><p>the ferret</p>');
+ browser.jQuery('p').text().should.equal('the ferret');
+ done();
+ });
+ });
+ },
+
+ 'test .request(method, foreignUrl)': function(done){
+ var browser = tobi.createBrowser(app);
+ browser.request('GET', 'http://www.google.com/', {}, function(res, $){
+ res.should.have.status(200);
+ browser.should.not.have.property('path');
+ browser.history.should.be.empty;
+
+ var googBrowser = Browser.browsers['www.google.com']
+ googBrowser.should.have.property('path', '/');
+ googBrowser.history.should.eql(['/']);
+ googBrowser.jQuery('img[alt="Google"]').length.should.equal(1);
+ done();
+ });
+ },
+
+ 'test .request(method, foreignHttpsUrl)': function(done){
+ var browser = tobi.createBrowser(app);
+ browser.request('GET', 'https://www.github.com/', {}, function(res, $){
+ res.should.have.status(200);
+ browser.should.not.have.property('path');
+ browser.history.should.be.empty;
+
+ var googBrowser = Browser.browsers['github.com']
+ googBrowser.should.have.property('path', '/');
+ googBrowser.history.should.eql(['/']);
+ googBrowser.jQuery('img[alt="github"]').should.not.be.empty;
+ done();
+ });
+ },
'test .request() redirect': function(done){
var browser = tobi.createBrowser(app);
@@ -240,6 +286,30 @@ module.exports = {
});
},
+ 'test .request() redirect to a full uri with different hostname': function(done){
+ var browser = tobi.createBrowser(80, 'bit.ly')
+ Browser.browsers.should.not.have.property('bit.ly');
+ Browser.browsers.should.not.have.property('node.js');
+ browser.request('GET', 'http://bit.ly/mQETJ8', {}, function (res, $) {
+ res.should.have.status(200);
+ Browser.browsers.should.have.property('bit.ly');
+ Browser.browsers.should.have.property('nodejs.org');
+ var nodeBrowser = Browser.browsers['nodejs.org'];
+ nodeBrowser.jQuery('img[alt="node.js"]').length.should.equal(1);
+ done();
+ });
+ },
+
+ 'test .request redirecting from a full non-https uri to a https uri': function(done){
+ var browser = tobi.createBrowser(80, 'bit.ly')
+ browser.request('GET', 'http://bit.ly/jrs5ME', {}, function (res, $) {
+ res.should.have.status(200);
+ var githubBrowser = Browser.browsers['github.com'];
+ githubBrowser.jQuery('#slider .breadcrumb a').should.have.text('tobi');
+ done();
+ });
+ },
+
// [!] if this test doesn't pass, an uncaught ECONNREFUSED will be shown
'test .request() on deferred listen()': function(done){
var browser = tobi.createBrowser(appDeferred)
@@ -847,6 +917,20 @@ module.exports = {
done();
});
},
+
+ 'test setting user-agent': function(done){
+ var browser = tobi.createBrowser(80,'whatsmyuseragent.com');
+ browser.get('http://whatsmyuseragent.com', function(res,$){
+ res.should.have.status(200);
+ $('h4:first').should.have.text('');
+ browser.userAgent = 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30';
+ browser.get('/', function(res,$){
+ res.should.have.status(200);
+ $('h4:first').should.have.text('Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30');
+ done();
+ });
+ });
+ },
after: function(){
app.close();

0 comments on commit 6fb8c86

Please sign in to comment.