learnboost / tobi Goto Github PK
View Code? Open in Web Editor NEWTobi: Expressive server-side functional testing with jQuery
Tobi: Expressive server-side functional testing with jQuery
Hi I have 1 issue and 1 enhancement here :)
If I using
data = {
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({bla: ''blubb'})
}
and browser.post(data, cb)
there is an error in connect bodyParser at the point where body will be JSON parsed.
I have debugged - the string is broken, it is shotter then the original string should be.
I investigated further:
headers['Content-Length'] = options.body.length;
It seems that content-length is wrong calculated here ... (I have a large json string hopefully you can reproduce it with any one)
Removing content-length from tobi solves the problem.
I don't want to setup header every time I want post a json object. It can be detected automatically.
I am trying to use tobi for integration tests of the api.
Can we fix this fast? I can provide you a patch.
Best,
Oleg
Hey, upgraded to node 0.4 and the latest tobi via npm, but now code like:
browser.client.on('connect'
Results in:
node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Cannot call method 'on' of undefined
at Object.<anonymous> (/truecode/admin/current/cakephp/app/tests/live-test/care.true.nl.js:117:16)
at Module._compile (module.js:402:26)
at Object..js (module.js:408:10)
at Module.load (module.js:334:31)
at Function._load (module.js:293:12)
at Array.<anonymous> (module.js:421:10)
at EventEmitter._tickCallback (node.js:126:26)
What would be the right syntax now? Thanks in advance!
lots of docs / examples
If no nodes exist that match .foo then
browser.jQuery(".foo").click(func);
will result in an exception, because https://github.com/LearnBoost/tobi/blob/master/lib/jquery/index.js#L89 is expecting a node to exist.
The nodeName should default to an empty String and only set the nodeName if a node exists in the jQuery object. That way the switch statement will break and continue to line 116 where a more useful error message will be thrown.
Not a huge issue, but one I ran into a little bit while writing tests.
I'll try to get to this sometime this week.
In some cases the execution hangs. All the tests are executed with a OK result, but it will not end until i press CTRL-C.
My Script is a simple express.js application (Joose, Jade, Expresso, Vows).
This error occures only when no test errors are found.
tobi only returns the body contents for a "successful" response (where the status is between 200 and 300) which precludes testing the representation returned in a 404 page, 400/422 errors returned for invalid forms input and a 500 error (admittedly hard to recreate normal processing).
When I try to run some examples code with nodejs 0.5.0pre with tobi 0.3.0 and found the below error stack trace.
Could you help me about it ?
:/opt/node/lib/node_modules/tobi/examples# node google.js
/opt/node/lib/node_modules/tobi/lib/browser.js:425
var elems = this.context.find(selector).filter(function(){
^
TypeError: Object function (selector, fn){
var prev = this.context;
this.context = this.context.find(selector);
fn();
this.context = prev;
return this;
} has no method 'find'
at Browser.locate (/opt/node/lib/node_modules/tobi/lib/browser.js:425:28)
at Browser.click (/opt/node/lib/node_modules/tobi/lib/browser.js:458:27)
at /opt/node/lib/node_modules/tobi/examples/google.js:12:11
at IncomingMessage. (/opt/node/lib/node_modules/tobi/lib/browser.js:264:9)
at IncomingMessage.emit (events.js:81:20)
at HTTPParser.onMessageComplete (http.js:133:23)
at Socket.onend (http.js:1264:12)
at Socket._onReadable (net_legacy.js:659:26)
at IOWatcher.onReadable as callback
Apparently some servers write cookies with Path= instead of path= and since Browser doesn't pass the request it'll throw an exception when it can't find Path=.
version and push to npm
Hello,
I am trying to set the Cookies header on .get and .post methods but I do not seem to do it properly.
Can you please post me an example how to request a page and be able to append my own Cookie headers as well?
Thank you for your time
I've just installed Tobi, and I am trying to run the following snippet with node v0.3.2-pre
var tobi = require('tobi')
, browser = tobi.createBrowser(80, 'site.local');
browser.get('/index.php/example',function(res,$){
console.info(res);
});
Output:
node.js:59
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: Cannot find module '../support/jquery'
at resolveModuleFilename (node.js:255:13)
at loadModule (node.js:217:20)
at require (node.js:281:14)
at Object.<anonymous> (/usr/local/lib/node/.npm/tobi/0.1.0/package/lib/browser.js:16:14)
at Module._compile (node.js:336:30)
at Object..js (node.js:344:12)
at Module.load (node.js:269:25)
at loadModule (node.js:241:12)
at require (node.js:281:14)
at Object.<anonymous> (/usr/local/lib/node/.npm/tobi/0.1.0/package/lib/tobi.js:18:19)
Thanks,
A
I don't know if this issue should be addressed to tobi or to cookie module.
When I try
var t = require('tobi');
var b = t.createBrowser(80, 'google.com');
b.get('/', function(res,$){ });
I get
TypeError: Object PREF=ID=add60603cd9cf9c4:FF=0:TM=1295994258:LM=1295994258:S=PW70e0OVmPVSguan; expires=Thu, 24-Jan-2013 22:24:18 GMT; path=/; domain=.google.com,NID=43=romTGe4lscquMFz4Bwyn6E6sVVqJJE4XJ7sefecPmXqyB6R9zAt-Rre84mq7zhUJ0WxW3BsN9q5gOMrRiLyrNtj3w53KPtGgtnWf8bc4zpZCmHF7cCPjAo7WqYvjI2O7; expires=Wed, 27-Jul-2011 22:24:18 GMT; path=/; domain=.google.com; HttpOnly has no method 'substr'
this other lib is crapping out, libxml should be much better
for example if you have more than one form on the page, possibly even identical forms, you might want to focus actions to a specific fragment, something like:
// global context
browser.within('form:nth-child(2)', function(){
// in context of form:nth-child(2)
// all actions scoped to this context
// otherwise click("Save") could be the wrong form
// so this would provide a nice api for ignore the rest
browser.fill({
username: 'tobi'
, password: 'is supes cool'
});
browser.click('Save', function(){
})
});
// global context again
I get the following stacktrace. Only one forum digest option comes back as selected, when it should be both. This happens when I run make test
on a newly-checked-out clone of the repo.
This is the test that is failing: https://github.com/LearnBoost/tobi/blob/master/test/browser.navigation.test.js#L700
uncaught: AssertionError: expected { user:
{ name: '',
subscribe: 'yes',
forum_digest: 'weekly',
signature: '' } } to equal { user:
{ name: '',
signature: '',
subscribe: 'yes',
forum_digest: [ 'daily', 'weekly' ] } }
at Object.eql (/Users/bantic/tobi/node_modules/should/lib/should.js:291:10)
at /Users/bantic/tobi/test/browser.navigation.test.js:720:30
at IncomingMessage.<anonymous> (/Users/bantic/tobi/lib/browser.js:201:24)
at IncomingMessage.emit (events.js:81:20)
at HTTPParser.onMessageComplete (http.js:133:23)
at Client.onData [as ondata] (http.js:1484:27)
at Client._onReadable (net.js:683:27)
at IOWatcher.onReadable [as callback] (net.js:177:10)
uncaught: Error: 'test select multiple options' timed out
at Object._onTimeout (/Users/bantic/tobi/node_modules/expresso/bin/expresso:835:43)
at Timer.callback (timers.js:83:39)
I thought tobi would work with Zappa as it is express and connect powered but I'm getting an error saying that it has "no method listen". What should I do to get tobi working with a zappa app?
currently $(form).submit() is tied to the submit button. Should be the other way around
I'm keen to use tobi with vows, as outlined in this blog post
but am experiencing the same issue as one of the commenters with $ being undefined in the callback:
#!/usr/bin/env vows --spec
var vows = require('vows');
var assert = require('assert');
var tobi = require('tobi');
vows.describe('register').addBatch({
'GET /register': {
topic: function() {
var browser = tobi.createBrowser(3000, 'localhost');
browser.get("/register", this.callback);
},
'has a 200 status code': function(res, $) {
res.should.have.status(200);
},
'is the Register page': function(res, $) {
$('title').should.equal('Registration');
}
}
}).export(module);
results in:
♢ register
GET /register
✓ has a 200 status code
✗ is the Register page
TypeError: undefined is not a function
at CALL_NON_FUNCTION (native)
at Object.<anonymous> (/site/test/x.js:17:4)
at runTest (/site/node_modules/vows/lib/vows.js:95:26)
at EventEmitter.<anonymous> (/site/node_modules/vows/lib/vows.js:78:13)
at EventEmitter.emit (events.js:81:20)
at /site/node_modules/vows/lib/vows/context.js:31:52
at /site/node_modules/vows/lib/vows/context.js:46:29
at IncomingMessage.<anonymous> (/site/node_modules/tobi/lib/browser.js:264:9)
at IncomingMessage.emit (events.js:81:20)
at HTTPParser.onMessageComplete (http.js:133:23)
·
✗ Errored » 1 honored ∙ 1 errored (0.129s)
Is there any reason why jQuery is at version 1.4.2? The only reason I noticed is I was using a 1.5.x API that wasn't present.
I am getting an error which is as follow.
/home/Api/tests/scripts/vows/node_modules/tobi/lib/browser.js:192
if (~contentType.indexOf('json')) {
^
TypeError: Cannot call method 'indexOf' of undefined
at ClientRequest.<anonymous> (/home/Api/tests/scripts/vows/node_modules/tobi/lib/browser.js:192:24)
at ClientRequest.emit (events.js:64:17)
at HTTPParser.onIncoming (http.js:1593:9)
at HTTPParser.onHeadersComplete (http.js:108:31)
at Client.onData [as ondata] (http.js:1471:27)
at Client._onReadable (net.js:681:27)
at IOWatcher.onReadable [as callback] (net.js:177:10)
This is the case when I am trying to test a POST method ( browser.post('/v0.5/posttest', data, this.callback);
with vows.js as framework.) and the post does nothing but res.end()
using express.js.
and unit test them
Tobi's performance really goes down as the page size increases. Some of my tests run on very large forms, and 30+ seconds can pass between requests triggered by Tobi.
The issue probably lies somewhere in JSDOM, or JQuery in tandem with JSDOM. As I get time I'll try to find out the exact bottleneck and ways to reduce it.
Tried following the example on the docs and get "connection refused". The app works fine when I fire it up in node and navigate through curl or a browser.
something funky is going on, the more HTTP related tests added, start to cause expresso timeouts
Correct me if I'm wrong, but shouldn't the following work:
var browser = tobi.createBrowser(80, 'http://www.google.com);
browser.click("input[name=btnG"])
or
browser.get('/', function(res, $){
browser.click("input[name=btnG"])
});
Both are giving me an uncaught exception.
This code:
var doc = {foo: 'test', bar:'foo', a:1, b:2};
browser.post('/foo/', {body: JSON.stringify(doc)}, function(res, $) {
...
}
produces a req.body of undefined
in my express view.
better coverage needed
Seems to be generating a new connect.sid
per request
When creating a browser via an app,
var browser = tobi.createBrowser(app);
is there a way to specify the test environment to be used to configure the app? Or is the environment to run the application inherited from whatever environment was used when tobi was executed to run the tests?
Keep getting this error when running the following code against my expressjs app:
var app = require('../app'),
assert = require('assert'),
tobi = require('tobi'),
vows = require('vows'),
browser = tobi.createBrowser(app);
browser.get('/login', function(res, $){
});
Not sure what's causing this behavior.
diff --git a/Readme.md b/Readme.md
index d18ed1f..be8038e 100644
--- a/Readme.md
+++ b/Readme.md
@@ -12,7 +12,7 @@ In the example below, we have an http server or express app `require()`ed, and w
We can then use regular css selectors to grab the form, we use tobi's `.fill()` method to fill some inputs (supports textareas, checkboxes, radios, etc), then we proceed to submitting the form, ag$
var tobi = require('tobi')
- , app = require('./my/app)
+ , app = require('./my/app')
, browser = tobi.createBrowser(app);
browser.get('/login', function(res, $){
Hi,
I'm trying to use tobi with a webpage that has latin characters. Can you please add a new encoding option so I can set it to 'binary'?
From what I gathered this is a small change when creating the request:
browser.js:
// Request
var req = (this.https ? https : http).request({
method: method
, path: path
, encoding: 'binary'
, port: this.host ? this.port : (server && server.__port)
, host: this.host
, headers: headers
});
Thanks.
Best regards,
Migrate
I have a form using jquery mobile. There's no input with type submit, only Login
I've tried browser.click('button[type=submit]'
and
browser.click('Login'
and form.submit , etc, etc.. Every variant I could think of. Every one gives me:
.../node_modules/.npm/tobi/0.1.1/package/lib/jquery/index.js:114
if (!url) throw new Error('failed to click ' + locator + ', ' + prop + ' n
^
Error: failed to click * form :submit, element not present
at Object.click (.../node_modules/.npm/tobi/0.1.1/package/lib/jquery/index.js:114:21)
at Object.submit (.../node_modules/.npm/tobi/0.1.1/package/lib/jquery/index.js:149:14)
Hey, loving Tobi so far, writing a big testsuite for my app now which among things, does pdf generation. If I could just check that the right headers are set, that would already be a big help.
I'm trying to do so with this snippet:
// Get owned Invoice as pdf
browser.get('/invoices/view/201003978.pdf', function(res, $) {
res.should.have.header('Content-Type', 'application/pdf');
res.should.have.header('Content-Transfer-Encoding', 'binary');
res.should.have.header('Expires', '0');
res.should.have.header('Pragma', 'no-cache');
});
But it looks like tobi will try to parse the result as html, no matter what the content-type is:
node.js:63
throw e;
^
Error: Parse Error
at Client.onData [as ondata] (http:854:27)
at IOWatcher.callback (net:494:29)
at node.js:773:9
Would you be open to excluding some content-types in Tobi parsing? Or do you know of another way I can force Tobi to skip parsing for a single request?
Thanks!
$('form').fill({ foo: 'bar' }).submit()
Hi,
I've create a clone browser function so I can create new browser with the same cookieJar.
browser.js:
/**
* Clone a new `Browser` with the same cookieJar, external options and userAgent as the sourceBrowser.
*
* @param {Object} source browser.
* @api public
*/
Browser.prototype.cloneBrowser = function(sourceBrowser) {
this.external = sourceBrowser.external;
this.cookieJar = sourceBrowser.cookieJar;
this.userAgent = sourceBrowser.userAgent;
};
tobi.js:
/**
* Initialize a new `Browser` with the same cookieJar and userAgent
*/
exports.cloneBrowser = function(a,b,c,d){
new_browser = new exports.Browser(a,b,c);
new_browser.cloneBrowser(d)
return new_browser;
};
I need this function because I have several hosts that share the same cookies.
default_browser = tobi.createBrowser(80, default_host, { external: true });
new_brower = tobi.cloneBrowser(80, new_host, {}, browser);
Can you please add this function (or something similar) to the next release?
Thanks.
Best regards,
Migrate
When I reduce the standard example to a bare minimum, the Error message is: ERR ADDR already in use. Can you maybe deliver a bare minimum tobi test as expresso does for the unit tests? This would be a really easy entrance to tobi.
currently (
https://github.com/LearnBoost/tobi/blob/master/lib/browser.js#L130
Currently there is no way the header's are defaulted. Guess it would be nice that there is a way to set some headers that are anyway expected by many of the server side code (e.g. express.js) like already done at https://github.com/LearnBoost/tobi/blob/master/lib/browser.js#L158. The other day tobi simulated POST request couldn't find req.body in the express.js middleware as headers['Content-type'] = 'application/json';
was missing.
Also, neither README nor the blogpost like this http://vilimpoc.org/blog/2011/01/19/testing-rest-api-with-learnboosts-tobi-vows-js/ specifies such necessity of setting the headers.
/**
var tobi = require('tobi')
, should = require('should')
, browser = tobi.createBrowser(80, 'www.google.com');
browser.get('/', function(res){
res.should.have.status(200);
browser.click("input[name=btnG]", function(res, $){
$('title').should.have.text('Google');
});
});
results in
/home/main/projects/node_modules/tobi/lib/browser.js:421
var elems = this.context.find(selector).filter(function(){
^
TypeError: Object function (selector, fn){
var prev = this.context;
this.context = this.context.find(selector);
fn();
this.context = prev;
return this;
} has no method 'find'
at Browser.locate (/home/main/projects/node_modules/tobi/lib/browser.js:421:28)
at Browser.click (/home/main/projects/node_modules/tobi/lib/browser.js:454:27)
at /home/main/projects/tobitest.js:13:11
at IncomingMessage. (/home/main/projects/node_modules/tobi/lib/browser.js:281:9)
at IncomingMessage.emit (events.js:81:20)
at HTTPParser.onMessageComplete (http.js:133:23)
at Socket.onend (http.js:1266:12)
at Socket._onReadable (net.js:659:26)
at IOWatcher.onReadable as callback
I tried installing all dependancies and still no luck.. Any suggestions? (node version: v.0.4.10)
Just played with this for about 5 minutes, and it appears not suited for testing JSON responses, but I am willing to stand corrected.
currently only POST
I am using node version v.0.5.11-pre with tobi 0.1.1 and the following simple sample
tobi = require('tobi');
browser = tobi.createBrowser(80, 'google.com', {external:true});
browser.get('/', function(res, $){
});
results in exception
node_modules/tobi/lib/cookie/index.js:26
this.name = str.substr(0, str.indexOf('='));
TypeError: Object PREF=ID=f886a9c19ecc3d44:FF=0:TM=1320856926:LM=1320856926:S=Yw911ELXKPXLIKxO;
expires=Fri, 08-Nov-2013 16:42:06 GMT; path=/; domain=.google.com has no method 'substr'
Any ideas?
These would be useful when testing some RESTful things.
This code doesn't do anything but bind a function with a click event.
browser.click('a', function(res, $){
console.log('a#test was clicked')
})
According Tobi document, this is not an expected behavior.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.