Giter VIP home page Giter VIP logo

tobi's Introduction

Tobi

Expressive server-side functional testing with jQuery and jsdom.

Tobi allows you to test your web application as if it were a browser. Interactions with your app are performed via jsdom, htmlparser, and jQuery, in combination with Tobi's Cookie Jar, provides a natural JavaScript API for traversing, manipulating and asserting the DOM, and session based browsing.

Example

In the example below, we have an http server or express app require()ed, and we simply create new tobi Browser for that app to test against. Then we GET /login, receiving a response to assert headers, status codes etc, and the $ jQuery context.

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, again receiving a response and the jQuery context.

var tobi = require('tobi')
  , app = require('./my/app')
  , browser = tobi.createBrowser(app);

browser.get('/login', function(res, $){
  $('form')
    .fill({ username: 'tj', password: 'tobi' })
    .submit(function(res, $){
      res.should.have.status(200);
      res.should.have.header('Content-Length');
      res.should.have.header('Content-Type', 'text/html; charset=utf-8');
      $('ul.messages').should.have.one('li', 'Successfully authenticated');
      browser.get('/login', function(res, $){
        res.should.have.status(200);
        $('ul.messages').should.have.one('li', 'Already authenticated');
        // We are finished testing, close the server
        app.close();
      });
    });
});

Browser

Tobi provides the Browser object, created via tobi.createBrowser(app), where app is a node http.Server, so for example Connect or Express apps will work just fine. There is no need to invoke listen() as this is handled by Tobi, and requests will be deferred until the server is listening.

Alternatively you may pass a port and host to createBrowser(), for example:

var browser = tobi.createBrowser(80, 'lb.dev'); 

Evaluate External Resources

To evaluate script tags simply pass the { external: true } option:

var browser = tobi.createBrowser(app, { external: true });

Browser#get()

Perform a GET request with optional options containing headers, etc:

browser.get('/login', function(res, $){
  
});

With options:

browser.get('/login', { headers: { ... }}, function(res, $){
  
});

Aliased as visit, and open.

Browser#post()

Perform a POST request with optional options containing headers, body etc:

browser.post('/login', function(res, $){
  
});

With options:

browser.post('/login', { body: 'foo=bar' }, function(res, $){
  
});

Browser#back()

GET the previous page:

browser.get('/', function(){
  // on /
  browser.get('/foo', function(){
    // on /foo
    browser.back(function(){
      // on /
    });
  });
});

Browser locators

Locators are extended extend selectors, the rules are as following:

  • element text
  • element id
  • element value
  • css selector

These rules apply to all Browser related methods such as click(), fill(), type() etc. Provided the following markup:

<form>
  <input id="form-login" type="submit" value="Login" />
</form>

The following locators will match the input:

.click('Login');
.click('form-login');
.click('input[type=submit]');
.click(':submit');

Browser#click(locator[, fn])

Tobi allows you to click() a elements, button[type=submit] elements, and input[type=submit] elements in order to submit a form, or request a url.

Submitting a form:

browser.click('Login', function(res, $){
  
});

Submitting with jQuery (no locators):

$('form :submit').click(function(res, $){
  
});

Clicking a link:

browser.click('Register Account', function(res, $){
  
});

Clicking with jQuery (no locators):

$('a.register', function(res, $){
  
});

Browser#submit(locator|fn, fn)

Submit the first form in context:

browser.submit(function(res, $){
  
});

browser.submit(function(){
  
});

Browser#type(locator, str)

"Type" the given str:

browser
  .type('username', 'tj') 
  .type('password', 'foobar');

Browser#{check,uncheck}(locator)

Check or uncheck the given locator:

browser
  .check('agreement')
  .uncheck('agreement');

Browser#select(locator, options)

Select the given option or options:

browser
  .select('colors', 'Red')
  .select('colors', ['Red', 'Green']);

Browser#fill(locator, fields)

Fill the given fields, supporting all types of inputs. For example we might have the following form:

<form>
  <input type="text" name="user[name]" />
  <input type="text" name="user[email]" />
  <input type="checkbox" name="user[agreement]" />
  
  <select name="digest">
    <option value="none">Never</option>
    <option value="daily">Daily</option>
    <option value="weekly">Weekly</option>
  </select>
  
  <select name="favorite-colors" multiple>
    <option value="red">Red</option>
    <option value="green">Green</option>
    <option value="blue">Blue</option>
  </select>
</form> 

Which can be filled using locators:

browser
  .fill({
      'user[name]': 'tj'
    , 'user[email]': '[email protected]'
    , 'user[agreement]': true
    , 'user[digest]': 'Daily'
    , 'user[favorite-colors]': ['red', 'Green']
  }).submit(function(){
    
  });

With jQuery:

$('form')
  .fill({
      'user[name]': 'tj'
    , 'user[favorite-colors]': 'red'
  }).submit(function(){
    
  });

Browser#text(locator)

Return text at the given locator. For example if we have the form option somewhere in our markup:

<option value="once">Once per day</option>

We can invoke browser.text('once') returning "Once per day".

Browser#{context,within}(selector, fn)

Alter the browser context for the duration of the given callback fn. For example if you have several forms on a page, an wish to focus on one:

<div><form id="user-search" method="post" action="/search/users">
  <input type="text" name="query" />
</form></div>

<div><form id="post-search" method="post" action="/search/posts">
  <input type="text" name="query" />
</form></div>

Example test using contexts:

browser.get('/search', function(res, $){

  // Global context has 2 forms
  $('form').should.have.length(2);

  // Focus on the second div
  browser.within('div:nth-child(2)', function(){

    // We now have one form, and no direct input children
    $('> form').should.have.length(1);
    $('> input').should.have.length(0);

    // Focus on the form, we now have a single direct input child
    browser.within('form', function(){
      $('> form').should.have.length(0);
      $('> input').should.have.length(1);
    });

    // Back to our div focus, we have one form again
    $('> form').should.have.length(1);
    $('> input').should.have.length(0);

    // Methods such as .type() etc work with contexts
    browser
    .type('query', 'foo bar')
    .submit(function(res){

    });
  });

  // Back to global context
  $('form').should.have.length(2);
});

Assertions

Tobi extends the should.js assertion library to provide you with DOM and response related assertion methods.

Assertion#text(str|regexp)

Assert element text via regexp or string:

  elem.should.have.text('foo bar');
  elem.should.have.text(/^foo/);
  elem.should.not.have.text('rawr');

When asserting a descendant's text amongst a heap of elements, we can utilize the .include modifier:

  $('*').should.include.text('My Site');

Assertion#many(selector)

Assert that one or more of the given selector is present:

  ul.should.have.many('li');

Assertion#one(selector)

Assert that one of the given selector is present:

  p.should.have.one('input');

Assertion#attr(key[, val])

Assert that the given key exists, with optional val:

  p.should.not.have.attr('href');
  a.should.have.attr('href');
  a.should.have.attr('href', 'http://learnboost.com');

Shortcuts are also provided:

- id()
- title()
- href()
- alt()
- src()
- rel()
- media()
- name()
- action()
- method()
- value()
- enabled
- disabled
- checked
- selected

For example:

  form.should.have.id('user-edit');
  form.should.have.action('/login');
  form.should.have.method('post');
  checkbox.should.be.enabled;
  checkbox.should.be.disabled;
  option.should.be.selected;
  option.should.not.be.selected;

Assertion#class(name)

Assert that the element has the given class name.

  form.should.have.class('user-edit');

Assertion#status(code)

Assert response status code:

  res.should.have.status(200);
  res.should.not.have.status(500);

Assertion#header(field[, val])

Assert presence of response header field and optional val:

  res.should.have.header('Content-Length');
  res.should.have.header('Content-Type', 'text/html');

Testing

Install the deps:

$ npm install

and execute:

$ make test

WWTD

What Would Tobi Do:

Tobi

License

(The MIT License)

Copyright (c) 2010 LearnBoost <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation te rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

tobi's People

Contributors

aheckmann avatar bantic avatar blakmatrix avatar bnoguchi avatar eugeneware avatar kcbanner avatar mhemesath avatar rauchg avatar sorich87 avatar tj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tobi's Issues

Can't interact with loaded remote url

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.

body of 4xx and 5xx errors unavailable

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).

Test pdf generation?

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!

Add ability for DOM contexts

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

Tobi breaks

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.

Clone Browser

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

Connection Refused

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.

Browser events

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!

submitting forms with <button type="submit">

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)

browser.post json object

Hi I have 1 issue and 1 enhancement here :)

Issue:

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.

Enhancement

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

How do I use with Zappa?

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?

Running App in Test Environment

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?

Syntax error in example

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, $){

broken jquery path in npm

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

Npm

version and push to npm

ADDR already in use ?

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.

Update jQuery Version

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.

$ undefined in vows callback

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)

Simple tobi usage results in exception

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?

Docs

lots of docs / examples

Fix test timeout

something funky is going on, the more HTTP related tests added, start to cause expresso timeouts

Cookies with Path= instead of path=

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=.

Can't get Google example to work

/**

  • Module dependencies.
    */

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)

jQuery(".selector").click Throws Exception if Collection Empty

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.

Performance

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.

Encoding option

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

test for 'test select multiple options' in browser.navigation.js fails

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)

Headers should be defaulted

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.

TypeError: Object #<Object> has no method 'listen'

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.

Cookie substr

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'

has no method 'find' when Browser.click invoked.

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

tobi hangs

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.

testing JSON responses

Just played with this for about 5 minutes, and it appears not suited for testing JSON responses, but I am willing to stand corrected.

cookies on header

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.