Giter Club home page Giter Club logo

zombie's Introduction

👏 Hey there, I’m Assaf.

🏖 Right now I'm “inbetween startups“, just a fancy way of saying I do some consulting/advising, while planning the next move.

☕️ I blog at https://labnotes.org/ about software design and development, people and management, culture and technology.

Feel free to subscribe.

zombie's People

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

zombie's Issues

Inline scripts get executed after external scripts

When doing zombie tests with our app, I've noticed, that the inline scripts in the head get executed after the loaded scripts. For example in the following test, it'll run external jquery first and the script in the head after that. In the browser the inline scripts get executed immediately.

I'm running v0.8.6.
var zombie = require('zombie');
var assert = require("assert");

// Load the page
zombie.visit("http://jsbin.com/onomi4", {debug:true}, function (err, browser) {
  if(err){
    console.error('!!', err.message);
  }else{
  }
});

Here's the log output:

Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: GET http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js
Zombie: GET /js/render/edit.js
Zombie: GET http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js => 200
Zombie: Running script from /ajax/libs/jquery/1.4.4/jquery.min.js
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
Zombie: GET /js/render/edit.js => 200
Zombie: Running script from /js/render/edit.js
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
this is called in the HEAD tag
Zombie: Running script from http://jsbin.com/onomi4:undefined:undefined<script>
this is called in the BODY tag

as you can see it executes jquery before the inline script in the head :(

Timeouts with strings instead of function references fail

Here's an example



<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>


<script>
function test(){
console.log('Hey!');
}
$(document).ready(function(){
setTimeout("test()",100);
})
</script>

Will fail.
node.js:66
throw e; // process.nextTick error, or 'error' event on first tick
^
test is not defined

Yet, evaling the same thing works?
$(document).ready(function(){
setTimeout(function(){
eval("test()");
},100);
})

Zombie: Running script from http://bjn-chase:1337/zombietest:undefined:undefined<script>
Hey!
chase@bjn-chase:~/zombie$

Strange. I haven't gone through how you're sandboxing the javascript context yet, but since eval doesn't seem to throw the error, I would suspect it's an easy fix.

I don't like putting code in quotes like that for timeouts, but it exists in the wild :\

Apache error: request without hostname

When I try it on my apache which has passenger on it, I get this error from apache log:

client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23): GET

Broken tests on master

After following the setup instructions, with from-scratch Node, NPM and Coffee-Script installs, I get 8 failures on master:

  adding script using document.write
    ✗ should run script
      » expected 'Script document.write',
    got  '' (==) // vows.js:95

  adding script using appendChild
    ✗ should run script
      » expected 'Script appendChild',
    got  '' (==) // vows.js:95

  open page
    ✗ should run jQuery.onready
      » expected 'Awesome',
    got  'Whatever' (==) // vows.js:95

  click link
    ✗ should run all events
      » expected 'The Dead',
    got  '' (==) // vows.js:95

  receive cookies
    ✗ should process cookies in XHR response
      » expected 'lol',
    got  undefined (==) // vows.js:95

  redirect
    ✗ should send cookies in XHR response
      » expected 'redirected: yes',
    got  undefined (==) // vows.js:95

  load asynchronously
    ✗ should load resource
      » expected expression to evaluate to true, but was undefined // vows.js:95

  send cookies
    ✗ should send cookies in XHR response
      » expected 'yes',
    got  undefined (==) // vows.js:95

✗ Broken » 181 honored ∙ 8 broken (2.725s)

Got no response from a vanilla zombie.visit()

Hey! Thanks for creating Zombie.js, I'm just trying it out and playing with it a little.

So far, with a specific url, I'm not getting callback execution when calling zombie.visit(), but seems like the url is loaded as far as I can tell doing a console.log(body) in History.js:104

What am I leaving out here?

Here's the code:
var zombie = require("zombie");
zombie.visit("http://vi.sualize.us/", function (err, browser) {
console.log(err);
console.log('got in');
});

Thanks!

Resources.stringify breaks on string data

I'm doing a simple XHR POST using JQuery like this:

$.post("/login", function() { ... });

The entity body is empty, in which case JQuery seem to pass down the string "" as XHR data. This kills the whole XHR request and Zombie ends up in a not really dead, not really alive state (eh!). I tracked it down to Resources.makeRequest which does a stringify in the "application/x-www-form-urlencoded". Resources.stringify expects something that accepts map and a string doesn't.

I've fixed it by adding the following as first statement in stringify:

return object.toString() unless object.map

Also makeRequest should probably be surrounded by a try/catch to invoke the callback in case of error, otherwise errors go totally unnoticed.

Missing dependency: htmlparser

After a clean install with npm, I get the following error multiple times when calling zombie.visit(url):

###########################################################
#  WARNING: No HTML parser could be found.
#  Element.innerHTML setter support has been disabled
#  Element.innerHTML getter support will still function
#  Download: http://github.com/tautologistics/node-htmlparser
###########################################################

After manually installing htmlparser everything works fine. As I haven't found any occurrence of "htmlparser" in zombie.js, I guess it's a (indirect) bug in one of its dependencies.

Parse error

When trying the following I get a parse error:
var zombie = require("zombie");

b = new zombie.Browser();
b.debug(true);
b.visit("http://www.esn.me", function (err, browser) {
  if (err) {
    console.log("Error");
    return;
  }
});

Not sure how I'm supposed to debug this efficiently. It's a public website, try running it yourself.
I'm running zombie 0.7.7 off npm.

PHP Sessions not held between requests

The PHP session id is not being held between requests. This has been run on 2 different LAMP / Node setups and both return the same result. If the form in submitted in a browser (FF 3.6.13 in this case) we see 'logged in' as the response. But if we run the node file it shows the form and the session id's do not match between requests. I have not had a chance to see if this is only PHP related or not.

The Zombie

    var zombie = require("zombie");
    var assert = require("assert");
    b = new zombie.Browser();
    // Load the page from localhost
    b.visit("http://elnormo.net/login_test.php", function (err, browser) {
      console.log('intial page load');
      intialSessionId = browser.cookies('elnormo.net').get('PHPSESSID');
      console.log(intialSessionId);
      // Fill from and submit form
      browser.
        fill("username", "pedro").
        fill("password", "runaway").
        pressButton("login", function(err, br) {
            console.log('form posted');
            console.log(br.lastRequest);
            console.log(br.lastResponse);
            console.log(br.lastError);
            innerSessionId = br.cookies('elnormo.net').get('PHPSESSID');
            console.log(intialSessionId);
            console.log(innerSessionId);
            assert.equal(intialSessionId, innerSessionId);

        })
    });

The PHP

<?php
session_start();

if(!empty($_POST)){
   $_SESSION['user'] = 'test';
   header('Location: /login_test.php');
   exit();
}

// if no session show form
if(!isset($_SESSION['user'])){ ?>
<!DOCTYPE html>
<html>
<head>
    <title>Test HTML5!</title>
    <meta charset="utf-8" />
</head>
<body>

   <form method="POST" action="/login_test.php">
      <input name="username" />
      <input name="password" />
      <input type="submit" name="login" value="login"/>
   </form>

</body>
</html>
<?php
}else{
   exit('logged in');
}
?>

Have callbacks on fil, check, choose, etc

Hello,

When your app is responding to user interactions like field changes, it would be good to have a callback to know when the action is completely completed (any XHR for exemple).

I modified my copy to do so, you can have a look here.
juggy@aac88ea

I think it should be in the main repo.

Thanks,
Julien.

cake setup fails

/zombie$ cake setup
Need Vows and Express to run test suite, installing ...
Need Ronn and Docco to generate documentation, installing ...
Need runtime dependencies, installing ...
Error: Command failed: npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm ERR! Error: Using '>=' with 0.5.x makes no sense. Don't do it.
npm ERR! at /home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:94:29
npm ERR! at String.replace (native)
npm ERR! at replaceXRange (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:88:25)
npm ERR! at Array.map (native)
npm ERR! at replaceXRanges (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:84:17)
npm ERR! at Array.map (native)
npm ERR! at toComparators (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:66:8)
npm ERR! at Object.validRange (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:138:11)
npm ERR! at install_ (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/install.js:101:22)
npm ERR! at /home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/install.js:76:42
npm ERR! Report this entire log at http://github.com/isaacs/npm/issues
npm ERR! or email it to [email protected]
npm ERR! Just tweeting a tiny part of the error will not be helpful.
npm not ok

at ChildProcess.exithandler (child_process:80:15)
at ChildProcess.emit (events:27:15)
at ChildProcess.onexit (child_process:168:12)
at node.js:773:9

Error: Command failed: npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm ERR! Error: Using '>=' with 0.3.x makes no sense. Don't do it.
npm ERR! at /home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:94:29
npm ERR! at String.replace (native)
npm ERR! at replaceXRange (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:88:25)
npm ERR! at Array.map (native)
npm ERR! at replaceXRanges (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:84:17)
npm ERR! at Array.map (native)
npm ERR! at toComparators (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:66:8)
npm ERR! at Object.validRange (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:138:11)
npm ERR! at install_ (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/install.js:101:22)
npm ERR! at /home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/install.js:76:42
npm ERR! Report this entire log at http://github.com/isaacs/npm/issues
npm ERR! or email it to [email protected]
npm ERR! Just tweeting a tiny part of the error will not be helpful.
npm not ok

at ChildProcess.exithandler (child_process:80:15)
at ChildProcess.emit (events:27:15)
at ChildProcess.onexit (child_process:168:12)
at node.js:773:9

Error: Command failed: npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm ERR! Error: Using '>=' with 0.3.x makes no sense. Don't do it.
npm ERR! at /home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:94:29
npm ERR! at String.replace (native)
npm ERR! at replaceXRange (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:88:25)
npm ERR! at Array.map (native)
npm ERR! at replaceXRanges (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:84:17)
npm ERR! at Array.map (native)
npm ERR! at toComparators (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:66:8)
npm ERR! at Object.validRange (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:138:11)
npm ERR! at install_ (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/install.js:101:22)
npm ERR! at /home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/install.js:76:42
npm ERR! Report this entire log at http://github.com/isaacs/npm/issues
npm ERR! or email it to [email protected]
npm ERR! Just tweeting a tiny part of the error will not be helpful.
npm not ok

at ChildProcess.exithandler (child_process:80:15)
at ChildProcess.emit (events:27:15)
at ChildProcess.onexit (child_process:168:12)
at node.js:773:9

Error: Command failed: npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm ERR! Error: Using '>=' with 1.0.x makes no sense. Don't do it.
npm ERR! at /home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:94:29
npm ERR! at String.replace (native)
npm ERR! at replaceXRange (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:88:25)
npm ERR! at Array.map (native)
npm ERR! at replaceXRanges (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:84:17)
npm ERR! at Array.map (native)
npm ERR! at toComparators (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:66:8)
npm ERR! at Object.validRange (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/utils/semver.js:138:11)
npm ERR! at install_ (/home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/install.js:101:22)
npm ERR! at /home/alfred/local/lib/node/.npm/npm/0.2.12-1/package/lib/install.js:76:42
npm ERR! Report this entire log at http://github.com/isaacs/npm/issues
npm ERR! or email it to [email protected]
npm ERR! Just tweeting a tiny part of the error will not be helpful.
npm not ok

at ChildProcess.exithandler (child_process:80:15)
at ChildProcess.emit (events:27:15)
at ChildProcess.onexit (child_process:168:12)
at node.js:773:9

Errors on a couple of well-known sites

I'm not sure if this is an issue with zombie or a problem with either my install or these sites, but I'm getting very long and unclear errors when I try to visit Google, Wikipedia, or the W3C Validation Service. I was trying to verify that I had installed zombie correctly and was able to write a test on something that (I thought) would work before moving on to a new project.

var zombie = require("zombie");

// var url = "http://google.com";
// var url = "http://en.wikipedia.org";
var url = "http://validator.w3.org/";

zombie.visit(url, {debug: true}, function(err, browser) {
  if (err) {
    console.log(err.message);
  } else {
    browser.dump();
  }
});

Each produces what looks to be a javascript error. Here's the one for the validation service (I can supply the other ones if requested. I think Google may have an illegal character.):

Zombie: GET http://validator.w3.org/
Zombie: GET http://validator.w3.org/ => 200
Zombie: GET scripts/mootools.js
Zombie: GET scripts/w3c-validator.js
Zombie: GET http://www.w3.org/QA/Tools/don_prog.js
Zombie: GET scripts/mootools.js => 200
Zombie: Running script from /scripts/mootools.js
Zombie: TypeError: Cannot set property 'constructor' of undefined,    at new <anonymous> (/scripts/mootools.js:3:374)
Cannot set property 'constructor' of undefined
Zombie: GET scripts/w3c-validator.js => 200
Zombie: Running script from /scripts/w3c-validator.js
Zombie: TypeError: Object [object Context] has no method 'addEvent',    at /scripts/w3c-validator.js:177:8
13 Jan 23:05:25 - The onerror handler

 on target 

{ frames: [ [Circular] ]
, contentWindow: [Circular]
, window: [Circular]
, self: [Circular]
, location: [Getter/Setter]
, addEventListener: [Function]
, dispatchEvent: [Function]
, browser: [Getter]
, cookies: [Getter]
, sessionStorage: [Getter]
, localStorage: [Getter]
, setTimeout: [Function]
, setInterval: [Function]
, clearTimeout: [Function]
, clearInterval: [Function]
, perform: [Function]
, wait: [Function]
, request: [Function]
, history: [Getter]
, XMLHttpRequest: [Function]
, JSON: {}
, onerror: [Function]
, Image: [Function]
, _document: 
   { _childNodes: [ [Object], [Object] ]
   , _version: 2179
   , _children: 
      { '0': [Circular]
      , '1': [Circular]
      , _element: [Circular]
      , _query: [Function]
      , _version: 2179
      , _snapshot: [Circular]
      , _length: 2
      }
   , _nodeValue: null
   , _parentNode: null
   , _ownerDocument: [Circular]
   , _attributes: 
      { _nodes: {}
      , _length: 0
      , _ownerDocument: null
      , _readonly: false
      , _parentNode: [Circular]
      }
   , _nodeName: '#document'
   , _readonly: false
   , style: { position: 'static' }
   , _tagName: '#document'
   , _contentType: 'text/html'
   , _doctype: null
   , _implementation: { _ownerDocument: undefined, _features: [Object] }
   , _documentElement: [Circular]
   , _ids: 
      { banner: [Object]
      , title: [Object]
      , logo: [Object]
      , tagline: [Object]
      , frontforms: [Object]
      , tabset_tabs: [Object]
      , fields: [Object]
      , 'validate-by-uri': [Object]
      , uri: [Object]
      , extra_opt_uri: [Object]
      , toggleiconURI: [Object]
      , 'uri-charset': [Object]
      , 'uri-fbc': [Object]
      , 'uri-doctype': [Object]
      , 'uri-fbd': [Object]
      , urigroup_no: [Object]
      , urigroup_yes: [Object]
      , 'uri-ss': [Object]
      , 'uri-st': [Object]
      , 'uri-outline': [Object]
      , 'uri-No200': [Object]
      , 'uri-verbose': [Object]
      , 'validate-by-upload': [Object]
      , uploaded_file: [Object]
      , extra_opt_upload: [Object]
      , 'upload-charset': [Object]
      , 'upload-fbc': [Object]
      , 'upload-doctype': [Object]
      , 'upload-fbd': [Object]
      , uploadgroup_no: [Object]
      , uploadgroup_yes: [Object]
      , 'upload-ss': [Object]
      , 'upload-st': [Object]
      , 'upload-outline': [Object]
      , 'upload-No200': [Object]
      , 'upload-verbose': [Object]
      , 'validate-by-input': [Object]
      , fragment: [Object]
      , extra_opt_direct: [Object]
      , direct_prefill_no: [Object]
      , choice_full: [Object]
      , 'direct-doctype': [Object]
      , 'direct-fbd': [Object]
      , direct_prefill_yes: [Object]
      , choice_frag: [Object]
      , directfill_doctype_html401: [Object]
      , directfill_doctype_xhtml10: [Object]
      , directgroup_no: [Object]
      , directgroup_yes: [Object]
      , 'direct-ss': [Object]
      , 'direct-st': [Object]
      , 'direct-outline': [Object]
      , 'direct-No200': [Object]
      , 'direct-verbose': [Object]
      , don_program: [Object]
      , menu: [Object]
      , footer: [Object]
      , activity_logos: [Object]
      , support_logo: [Object]
      , version_info: [Object]
      }
   , _URL: 'http://validator.w3.org/'
   , _documentRoot: 'http:/'
   , _queue: { paused: false, tail: [Object], push: [Function] }
   , readyState: 'complete'
   , createWindow: [Function]
   , _parentWindow: [Circular]
   , _sessionStorage: 
      { length: [Getter]
      , key: [Function]
      , getItem: [Function]
      , setItem: [Function]
      , removeItem: [Function]
      , clear: [Function]
      , dump: [Function]
      }
   , _localStorage: 
      { length: [Getter]
      , key: [Function]
      , getItem: [Function]
      , setItem: [Function]
      , removeItem: [Function]
      , clear: [Function]
      , dump: [Function]
      }
   , window: [Circular]
   , uid: 2
   , html: [Circular]
   , '$family': { name: 'document' }
   }
, uid: 1
, Element: [Function: $empty]
, '$family': { name: 'window' }
, _vars: 
   [ [ 'pageXOffset', 0 ]
   , [ 'pageYOffset', 0 ]
   , [ 'screenX', 0 ]
   , [ 'screenY', 0 ]
   , [ 'screenLeft', 0 ]
   , [ 'screenTop', 0 ]
   , [ 'scrollX', 0 ]
   , [ 'scrollY', 0 ]
   , [ 'scrollTop', 0 ]
   , [ 'scrollLeft', 0 ]
   ]
}

 threw error 

{ message: 'Uncaught, unspecified \'error\' event.'
, stack: [Getter/Setter]
}

 handling event 

{ _eventType: 'HTMLEvents'
, _type: 'error'
, _bubbles: true
, _cancelable: false
, _target: 
   { frames: [ [Circular] ]
   , contentWindow: [Circular]
   , window: [Circular]
   , self: [Circular]
   , location: [Getter/Setter]
   , addEventListener: [Function]
   , dispatchEvent: [Function]
   , browser: [Getter]
   , cookies: [Getter]
   , sessionStorage: [Getter]
   , localStorage: [Getter]
   , setTimeout: [Function]
   , setInterval: [Function]
   , clearTimeout: [Function]
   , clearInterval: [Function]
   , perform: [Function]
   , wait: [Function]
   , request: [Function]
   , history: [Getter]
   , XMLHttpRequest: [Function]
   , JSON: {}
   , onerror: [Function]
   , Image: [Function]
   , _document: 
      { _childNodes: [Object]
      , _version: 2179
      , _children: [Object]
      , _nodeValue: null
      , _parentNode: null
      , _ownerDocument: [Circular]
      , _attributes: [Object]
      , _nodeName: '#document'
      , _readonly: false
      , style: [Object]
      , _tagName: '#document'
      , _contentType: 'text/html'
      , _doctype: null
      , _implementation: [Object]
      , _documentElement: [Object]
      , _ids: [Object]
      , _URL: 'http://validator.w3.org/'
      , _documentRoot: 'http:/'
      , _queue: [Object]
      , readyState: 'complete'
      , createWindow: [Function]
      , _parentWindow: [Circular]
      , _sessionStorage: [Object]
      , _localStorage: [Object]
      , window: [Circular]
      , uid: 2
      , html: [Circular]
      , '$family': [Object]
      }
   , uid: 1
   , Element: [Function: $empty]
   , '$family': { name: 'window' }
   , _vars: 
      [ [Object]
      , [Object]
      , [Object]
      , [Object]
      , [Object]
      , [Object]
      , [Object]
      , [Object]
      , [Object]
      , [Object]
      ]
   }
, _currentTarget: null
, _eventPhase: 2
, _timeStamp: null
, _preventDefault: false
, _stopPropagation: false
, error: 
   { message: [Getter/Setter]
   , stack: [Getter/Setter]
   , type: 'undefined_method'
   , arguments: [ 'addEvent', [Circular] ]
   }
}
Zombie: GET http://www.w3.org/QA/Tools/don_prog.js => 200
Zombie: Running script from /QA/Tools/don_prog.js
Zombie: GET http://api.flattr.com/js/0.6/load.js?mode=auto
Zombie: GET http://api.flattr.com/js/0.6/load.js?mode=auto => 200
Zombie: Running script from /js/0.6/load.js

So, is it ok to ignore these and assume that I can start a greenfield project and use zombie for testing?

Thanks.

Install with "cake setup" failing

I am sorry if this is stupid, but I have tried to install several times with different versions of node and am having no luck. If anyone could point me in the right direction that would be very helpful.

I am getting this output when running cake setup:

Need runtime dependencies, installing into node_modules ...
Need development dependencies, installing ...
Installing coffee-script >= 1.0.0
Installing docco 0.3.0
Installing express 1.0.1
Installing ronn 0.3.5
Installing vows 0.5.3
Error: Command failed: npm info it worked if it ends with ok npm info using [email protected]
npm info using [email protected]
npm ERR! sudon't!
npm ERR! sudon't! Running npm as root is not recommended!
npm ERR! sudon't! Seriously, don't do this!
npm ERR! sudon't!
npm info range opts@>=1.2.0
npm info preinstall [email protected]
npm info preinstall [email protected]
npm WARN bins installing to /home/node/zombie/node_modules/.bin, outside PATH
npm ERR! linking /home/node/zombie/node_modules/.npm/opts/1.2.1 to /home/node/zombie/node_modules/.npm/ronn/0.3.5/dependson/[email protected]
npm ERR! install failed Error: EPERM, Operation not permitted './../../../opts/1.2.1'
npm info install failed rollback
npm info uninstall [ '[email protected]', '[email protected]' ]
npm ERR! linking /home/node/zombie/node_modules/.npm/ronn/0.3.5 to /home/node/zombie/node_modules/.npm/opts/1.2.1/dependents/[email protected]
npm info preuninstall [email protected]
npm info preuninstall [email protected]
npm info uninstall [email protected]
npm info uninstall [email protected]
npm info auto-deactive not symlink
npm info auto-deactive not symlink
npm info postuninstall [email protected]
npm info postuninstall [email protected]
npm info uninstall [email protected] complete
npm info uninstall [email protected] complete
npm info install failed rolled back
npm ERR! Error: EPERM, Operation not permitted './../../../opts/1.2.1'
npm ERR! Report this *entire* log at <http://github.com/isaacs/npm/issues>
npm ERR! or email it to <[email protected]>
npm ERR! Just tweeting a tiny part of the error will not be helpful.
npm not ok

at ChildProcess.exithandler (child_process.js:76:15)
at ChildProcess.emit (events.js:34:17)
at ChildProcess.onexit (child_process.js:164:12)

You can see I ran this one as root, but I have tried both ways. Sorry again if this is not the right place to post.

Zombie.js install fails on base64

npm info using [email protected]
npm info using [email protected]

...

npm ERR! Some dependencies failed to bundle
npm ERR! Bundle them separately with
npm ERR! npm bundle install
npm ERR! Error: [email protected] install: node-waf configure build
npm ERR! sh failed with 1
npm ERR! at ChildProcess. (/usr/local/lib/node/.npm/npm/0.2.14-3/package/lib/utils/exec.js:25:18)
npm ERR! at ChildProcess.emit (events.js:34:17)
npm ERR! at ChildProcess.onexit (child_process.js:164:12)
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is most likely a problem with the base64 package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node-waf configure build
npm ERR! You can get their info via:
npm ERR! npm owner ls base64
npm ERR! There may be additional logging output above.
npm not ok

On OS X.

HTML5 Parser error

I don't know where is the html5 module used by Zombie so I'll report this error here:

Zombie: GET http://www.facebook.com/group.php?gid=104369172929110&_fb_noscript=1 => 200

/usr/local/lib/node/.npm/html5/0.2.12/package/lib/html5/tokenizer.js:62
                throw(e);
    ^
TypeError: Cannot call method 'toLowerCase' of undefined
    at Object.endTagFormatting (/usr/local/lib/node/.npm/html5/0.2.12/package/lib/html5/parser/in_body_phase.js:646:85)
    at Object.processEndTag (/usr/local/lib/node/.npm/html5/0.2.12/package/lib/html5/parser/phase.js:50:36)
    at EventEmitter.do_token (/usr/local/lib/node/.npm/html5/0.2.12/package/lib/html5/parser.js:97:20)
    at EventEmitter.<anonymous> (/usr/local/lib/node/.npm/html5/0.2.12/package/lib/html5/parser.js:112:30)
    at EventEmitter.emit (events:27:15)
    at EventEmitter.emitToken (/usr/local/lib/node/.npm/html5/0.2.12/package/lib/html5/tokenizer.js:84:7)
    at EventEmitter.emit_current_token (/usr/local/lib/node/.npm/html5/0.2.12/package/lib/html5/tokenizer.js:813:7)
    at EventEmitter.tag_name_state (/usr/local/lib/node/.npm/html5/0.2.12/package/lib/html5/tokenizer.js:358:8)
    at EventEmitter.<anonymous> (/usr/local/lib/node/.npm/html5/0.2.12/package/lib/html5/tokenizer.js:59:25)
    at EventEmitter.emit (events:27:15)

window.load event not triggered when bound via addEventListener

When trying to execute a QUnit testpage, the window.load event is never triggered. Here's my test script:

require("zombie").visit("http://jquery.bassistance.de/qunit/test/", { debug: true }, function(err, browser) {
    if (err) {
        throw err;
    }
    console.log(browser.text("#qunit-testresult"))
});

I also tried to build a simpler testpage using jsbin, but that fails due to some Google Analytics code: http://jsbin.com/ocino5

Here's a seperate file with just an inline script and a window-load event listener, no overhead and fails to output anything: http://jquery.bassistance.de/qunit/load-test.html

Capybara's drag & drop examples fail (because elements don't have position or dimension)

The mousedown, mousemove, and mouseup events are being fired as expected, but jQuery checks that the dragging element intersects with the drop target. I'm pretty sure drag & drop is failing at that juncture.

What we need is a way of calculating elements' position, height, and width; but these values should be calculated on-demand so that zombie is generally, well, insanely fast.

Scripts with window.eval do not work.

If a script contains a window.eval() zombie fails.

var zombie = require("zombie");
b = new zombie.Browser();
b.visit("http://cowholio4.com/pages/window", function (err, browser) {
  if (err) {
    console.log(err.message + "\n" + err.stack);
    return;
  }
});

I tried to create document.eval but can't seem to get it to work correctly. For some reason doing this in the sandbox is harder than it should be. Any help would be appreciated.

Multiple Cookies not handled correctly?

I'm using v0.8.3 with a very simple script:

var zombie = require("zombie");

var browser = new zombie.Browser({ debug: true });

browser.visit("http://bing.com", function (err, browser) {

  if(err) {
    throw(err.message);
  }

  browser.
    fill("q", "kittens").
    pressButton("#sb_form_go", function(err, browser) {
      assert.ok(browser.querySelector("#results"));
    })

});

Which produces:

Zombie: GET http://bing.com
Zombie: GET http://bing.com => 301
Zombie: GET http://www.bing.com/
Zombie: GET http://www.bing.com/ => 200
(DEBUG:) typeof serialized:  object ownProperties:  [ '0', '1', '2', '3', '4', '5', '6', 'length' ]
(DEBUG:) [ '_SS=SID=653506CC3A554354AA0CA7F48FA28C5F; domain=.bing.com; path=/',
  'MUID=698EF70D22284689B8B959E8D806AEEC; expires=Sun, 30-Dec-2012 04:23:48 GMT; domain=.bing.com; path=/',
  'OrigMUID=698EF70D22284689B8B959E8D806AEEC%2caf2347e4c093413f8f4c21ff585f2795; expires=Sun, 30-Dec-2012 04:23:48 GMT; domain=.bing.com; path=/',
  'OVR=flt=0&flt2=0&flt3=0&flt4=0&flt5=0&ramp1=0&release=or3&preallocation=0&R=1; domain=.bing.com; path=/',
  'SRCHD=D=1577063&MS=1577063&AF=NOFORM; expires=Sun, 30-Dec-2012 04:23:48 GMT; domain=.bing.com; path=/',
  'SRCHUID=V=2&GUID=5E16F3E5B50F445DB1DE8E6C9E5064FD; expires=Sun, 30-Dec-2012 04:23:48 GMT; path=/',
  'SRCHUSR=AUTOREDIR=0&GEOVAR=&DOB=20101231; expires=Sun, 30-Dec-2012 04:23:48 GMT; domain=.bing.com; path=/' ]

/Users/barnaby/local/lib/node/.npm/zombie/0.8.3/package/lib/zombie/cookies.js:117
      _ref = serialized.split(/,(?=[^;,]*=)|,$/);
                        ^
TypeError: Object _SS=SID=653506CC3A554354AA0CA7F48FA28C5F; domain=.bing.com; path=/,MUID=698EF70D22284689B8B959E8D806AEEC; expires=Sun, 30-Dec-2012 04:23:48 GMT; domain=.bing.com; path=/,OrigMUID=698EF70D22284689B8B959E8D806AEEC%2caf2347e4c093413f8f4c21ff585f2795; expires=Sun, 30-Dec-2012 04:23:48 GMT; domain=.bing.com; path=/,OVR=flt=0&flt2=0&flt3=0&flt4=0&flt5=0&ramp1=0&release=or3&preallocation=0&R=1; domain=.bing.com; path=/,SRCHD=D=1577063&MS=1577063&AF=NOFORM; expires=Sun, 30-Dec-2012 04:23:48 GMT; domain=.bing.com; path=/,SRCHUID=V=2&GUID=5E16F3E5B50F445DB1DE8E6C9E5064FD; expires=Sun, 30-Dec-2012 04:23:48 GMT; path=/,SRCHUSR=AUTOREDIR=0&GEOVAR=&DOB=20101231; expires=Sun, 30-Dec-2012 04:23:48 GMT; domain=.bing.com; path=/ has no method 'split'
    at Cookies.update (/Users/barnaby/local/lib/node/.npm/zombie/0.8.3/package/lib/zombie/cookies.js:117:25)
    at History.<anonymous> (/Users/barnaby/local/lib/node/.npm/zombie/0.8.3/package/lib/zombie/history.js:113:63)
    at IncomingMessage.<anonymous> (

I added the "(DEBUG:)" output to Cookies.update which I believe is actually expecting a string . Simple fix? :)

Thanks!

Test failures

Hi again!

I just ran the test suite and got some failures. I expect you did not see them when pushing the code. So, where do these come from? Is it the platform (here: Ubuntu 10.04 64bit, node 0.2.5) or the dependencies? Can you publish your environment in which all tests pass?

It looks like the failures gather around the more sophisticated DOM manipulation, XHR and event stuff.

Another strange thing I noticed in my own code: right after a jQuery.prependTo() DOM manipulation the newly inserted element is available through browser.querySelector([id=foobar]) but not through browser.querySelector("#foobar").

Here's the dump of the failed tests:

♢ XMLHttpRequest

  load asynchronously
    ✗ should load resource
      » expected expression to evaluate to true, but was undefined // vows.js:95
  redirect
    ✗ should send cookies in XHR response
      » expected 'redirected: yes',
    got  undefined (==) // vows.js:95
  send cookies
    ✗ should send cookies in XHR response
      » expected 'yes',
    got  undefined (==) // vows.js:95
  receive cookies
    ✗ should process cookies in XHR response
      » expected 'lol',
    got  undefined (==) // vows.js:95

♢ Browser

  adding script using document.write
    ✗ should run script
      » expected 'Script document.write',
    got  '' (==) // vows.js:95
  adding script using appendChild
    ✗ should run script
      » expected 'Script appendChild',
    got  '' (==) // vows.js:95

  open page
    ✓ should create HTML document
    ✓ should load document from server
    ✓ should load external scripts
    ✗ should run jQuery.onready
      » expected 'Awesome',
    got  'Whatever' (==) // vows.js:95
  click link
    ✓ should change location
    ✗ should run all events
      » expected 'The Dead',
    got  '' (==) // vows.js:95

location.search should be empty string

Context: Running QUnit testsuite via Zombie.js.

Problem: QUnit checks for window.location, and if defined, assumes that window.location.search is defined and at least an empty string. When running with Zombie.js, window.location is present, but location.search is undefined.

Proposed solution: Initialize the search property with an empty string, if no actual search value is present.

PS: Could be a jsdon issue. Didn't yet get a chance to dig into the source.

Need our own RunInContext

Node.js implements RunInContext by creating a context and using the sandbox to copy properties in/out of the context.

To make it work synchronously we start by having Windows be the context and the define certain properties to be non-configurable (location, storage, etc) so Node doesn't attempt to copy them (e.g. copying location from context to sandbox redirects the page).

But that doesn't work asynchronously, asynchronous events that run later on (e.g. XHR) operate on the context, properties changed them (global/window) do not propagate back to the sandbox.

So we're going to need our own implementation that can evaluate a script in the context of an object we give it (Window) without all the variable copying. And we know we can trust the evaluated code because, well, we're running tests.

Js variable with minus sign.

Hi. I have problem with Js variables containing minus "-" or "&" sign.
Problem occurs only when when variables are defined in html in script tags.

e.g.

...
<body>

<script>

var error1 = "-aaaa";

var error2 = "&aaaa";

</script>

</body>
...

generates error:
Error: SyntaxError: Unexpected token ILLEGAL
26 Jan 09:43:26 - The onerror handler

on target

{ frames: [ [Circular] ]
, contentWindow: [Circular]
, window: [Circular]
, self: [Circular]
, location: [Getter/Setter]
, addEventListener: [Function]
, dispatchEvent: [Function]
, browser: [Getter]
, title: [Getter/Setter]
, cookies: [Getter]
, sessionStorage: [Getter]
, localStorage: [Getter]
, setTimeout: [Function]
, setInterval: [Function]
, clearTimeout: [Function]
, clearInterval: [Function]
, perform: [Function]
, wait: [Function]
, request: [Function]
, history: [Getter]
, alert: [Function]
, confirm: [Function]
, prompt: [Function]
, XMLHttpRequest: [Function]
, JSON: {}
, onerror: [Function]
, Image: [Function]
, _document:
{ _childNodes: [ [Object], [Object] ]
, _version: 29
, _children:
{ '0': [Circular]
, '1': [Circular]
, _element: [Circular]
, _query: [Function]
, _version: 28
, _snapshot: [Circular]
, _length: 2
}
, _nodeValue: null
, _parentNode: null
, _ownerDocument: [Circular]
, _attributes:
{ _nodes: {}
, _length: 0
, _ownerDocument: null
, _readonly: false
, _parentNode: [Circular]
}
, _nodeName: '#document'
, _readonly: false
, style: { position: 'static' }
, _tagName: '#document'
, _contentType: 'text/html'
, _doctype:
{ _childNodes: []
, _version: 0
, _children: [Object]
, _nodeValue: null
, _parentNode: null
, _ownerDocument: [Circular]
, _attributes: [Object]
, _nodeName: 'HTML'
, _readonly: false
, style: [Object]
, _name: 'HTML'
, _tagName: 'HTML'
, _entities: [Object]
, _notations: [Object]
, _publicId: ''
, _systemId: ''
, _fullDT: ''
, toString: [Function]
}
, _implementation: { _ownerDocument: undefined, _features: [Object] }
, _documentElement: [Circular]
, _ids: {}
, _URL: 'http://localhost/start.html'
, _documentRoot: 'http://localhost'
, _queue: { paused: false, tail: [Object], push: [Function] }
, readyState: 'complete'
, createWindow: [Function]
, _parentWindow: [Circular]
, _sessionStorage:
{ length: [Getter]
, key: [Function]
, getItem: [Function]
, setItem: [Function]
, removeItem: [Function]
, clear: [Function]
, dump: [Function]
}
, _localStorage:
{ length: [Getter]
, key: [Function]
, getItem: [Function]
, setItem: [Function]
, removeItem: [Function]
, clear: [Function]
, dump: [Function]
}
}
, _vars:
[ [ 'pageXOffset', 0 ]
, [ 'pageYOffset', 0 ]
, [ 'screenX', 0 ]
, [ 'screenY', 0 ]
, [ 'screenLeft', 0 ]
, [ 'screenTop', 0 ]
, [ 'scrollX', 0 ]
, [ 'scrollY', 0 ]
, [ 'scrollTop', 0 ]
, [ 'scrollLeft', 0 ]
]
}

threw error

'Unexpected token ILLEGAL'

handling event

{ _eventType: 'HTMLEvents'
, _type: 'error'
, _bubbles: true
, _cancelable: false
, _target:
{ frames: [ [Circular] ]
, contentWindow: [Circular]
, window: [Circular]
, self: [Circular]
, location: [Getter/Setter]
, addEventListener: [Function]
, dispatchEvent: [Function]
, browser: [Getter]
, title: [Getter/Setter]
, cookies: [Getter]
, sessionStorage: [Getter]
, localStorage: [Getter]
, setTimeout: [Function]
, setInterval: [Function]
, clearTimeout: [Function]
, clearInterval: [Function]
, perform: [Function]
, wait: [Function]
, request: [Function]
, history: [Getter]
, alert: [Function]
, confirm: [Function]
, prompt: [Function]
, XMLHttpRequest: [Function]
, JSON: {}
, onerror: [Function]
, Image: [Function]
, _document:
{ _childNodes: [Object]
, _version: 29
, _children: [Object]
, _nodeValue: null
, _parentNode: null
, _ownerDocument: [Circular]
, _attributes: [Object]
, _nodeName: '#document'
, _readonly: false
, style: [Object]
, _tagName: '#document'
, _contentType: 'text/html'
, _doctype: [Object]
, _implementation: [Object]
, _documentElement: [Object]
, _ids: {}
, _URL: 'http://localhost/start.html'
, _documentRoot: 'http://localhost'
, _queue: [Object]
, readyState: 'complete'
, createWindow: [Function]
, _parentWindow: [Circular]
, _sessionStorage: [Object]
, _localStorage: [Object]
}
, _vars:
[ [Object]
, [Object]
, [Object]
, [Object]
, [Object]
, [Object]
, [Object]
, [Object]
, [Object]
, [Object]
]
}
, _currentTarget: null
, _eventPhase: 2
, _timeStamp: null
, _preventDefault: false
, _stopPropagation: false
, error:
{ message: [Getter/Setter]
, stack: [Getter/Setter]
, type: 'unexpected_token'
, arguments: [ 'ILLEGAL' ]
}
}

Trouble with YUI 3 style JavaScript loading

I got Zombie setup, then pointed this zombie script at my site and got the following output:

yui: NOT loaded: ttw-window-landing
Cannot read property 'LandingWindow' of undefined
TipTheWeb — Support Your Favorite Stuff Online

This would mean that something is getting messed up when zombie is loading our external external scripts. Our script loading is using some advanced techniques with YUI 3 and combing files together on the server and maybe part of the issue.

These external script files should be loaded by zombie before the following callback in an inline script is executed:

function(Y){
    (new Y.TTW.LandingWindow({
        "appRootPath":"/",
        "sublimeUrl":"http://cdn.sublimevideo.net/js/lrsfz74x.js"
    }));
}

Here is the output of the same zombie script with debug turned on:

Zombie: GET http://tiptheweb.org/
Zombie: GET http://tiptheweb.org/ => 200
Zombie: Running script from http://tiptheweb.org/:undefined:undefined<script>
Zombie: Running script from http://tiptheweb.org/:undefined:undefined<script>
Zombie: GET /combo/?yui3:_v_3.3.0.PR3/yui/yui-min.js;44b0m6neh3zsx55rvs35hebp68&yui3:_v_3.3.0.PR3/loader/loader-min.js;xpp217cqc6ah58aceqp499k5ac&utils:yui_config;05p40pwqscw0n5g7675gfrecbc&res:yui_config;bw1knegscrpwbj2sftpfzw0f68
Zombie: GET /combo/?yui3:_v_3.3.0.PR3/yui/yui-min.js;44b0m6neh3zsx55rvs35hebp68&yui3:_v_3.3.0.PR3/loader/loader-min.js;xpp217cqc6ah58aceqp499k5ac&utils:yui_config;05p40pwqscw0n5g7675gfrecbc&res:yui_config;bw1knegscrpwbj2sftpfzw0f68 => 200
Zombie: Running script from /combo/
Zombie: Running script from http://tiptheweb.org/:undefined:undefined<script>
Zombie: Running script from http://tiptheweb.org/:undefined:undefined<script>
Zombie: Running script from http://tiptheweb.org/:undefined:undefined<script>
Zombie: Running script from http://tiptheweb.org/:undefined:undefined<script>
Zombie: Running script from http://tiptheweb.org/:undefined:undefined<script>
Zombie: Running script from http://tiptheweb.org/:undefined:undefined<script>
yui: NOT loaded: ttw-window-landing
Cannot read property 'LandingWindow' of undefined
Zombie: Running script from http://tiptheweb.org/:undefined:undefined<script>
Zombie: GET http://www.google-analytics.com/ga.js
Zombie: GET http://www.google-analytics.com/ga.js => 200
Zombie: Running script from /ga.js
TipTheWeb — Support Your Favorite Stuff Online

Also I'm not sure what all this :undefined:undefined stuff is…

Serializing multiple complex values (e.g. addresses[][city]) does not work as expected

A Capybara test fails for the capybara-zombie driver because zombie.js doesn't serialize this:

<input name="addresses[][street]" value="Pennsylvania Ave" id="address1_street" />
<input name="addresses[][city]" value="Washington, DC" id="address1_city" />
<input name="addresses[][street]" value="Michigan Ave" id="address2_street" />
<input name="addresses[][city]" value="Chicago" id="address2_city" />

as an array, addresses, of two objects that each have street and city keys.

In fact, zombie.js serializes them as an array of four objects (each with one key).

(I added vows for these on a topic branch: boblail/zombie@588c740)

Is Capybara's expectation in line with how Zombie should behave?

jQuery & append

Hello,

I do the following:
var t = $("#my-template").clone();
$("body").append(t);
$(".line", t).append("<a href=...");

The first append is working, the second is not. After investigating, $(".line", t) does not return any nodes. Works in a browser.

Any idea or pointers for me to look at?
Thanks
Julien.

TypeError: Cannot call method 'addEventListener' of undefined

Trying to run tests, I get the following error:

[23:07][:~/src/zombie(master)]$ vows

node.js:63
    throw e;
    ^
TypeError: Cannot call method 'addEventListener' of undefined
    at Browser.visit (/Users/torgo/src/zombie/src/zombie/browser.coffee:102:25)
    at Browser.<anonymous> (/Users/torgo/src/zombie/spec/helpers.coffee:72:19)
    at Array.<anonymous> (/Users/torgo/src/zombie/spec/helpers.coffee:3:63)
    at EventEmitter._tickCallback (node.js:55:22)
    at node.js:773:9

I'm not sure where to go from here. Any suggestions?

HTML parse error?

Tried scripting some more zombies and hit this error while trying out http://beaconpush.com

This is the script:
var zombie = require("zombie");
b = new zombie.Browser();
b.visit("http://beaconpush.com/", function (err, browser) {
if (err) {
console.log("Error");
return;
}
});

and running it returns this output:

$ node test.js 

/usr/local/lib/node/.npm/html5/0.2.5/package/lib/html5/tokenizer.js:62
                throw(e);
    ^
Error
    at Object.appendChild (/usr/local/lib/node/.npm/jsdom/0.1.22/package/lib/jsdom/level1/core.js:1312:13)
    at Object.insert_html_element (/usr/local/lib/node/.npm/html5/0.2.5/package/lib/html5/parser/before_html_phase.js:41:21)
    at Object.processStartTag (/usr/local/lib/node/.npm/html5/0.2.5/package/lib/html5/parser/before_html_phase.js:29:7)
    at EventEmitter.do_token (/usr/local/lib/node/.npm/html5/0.2.5/package/lib/html5/parser.js:94:20)
    at EventEmitter.<anonymous> (/usr/local/lib/node/.npm/html5/0.2.5/package/lib/html5/parser.js:112:30)
    at EventEmitter.emit (events:27:15)
    at EventEmitter.emitToken (/usr/local/lib/node/.npm/html5/0.2.5/package/lib/html5/tokenizer.js:84:7)
    at EventEmitter.emit_current_token (/usr/local/lib/node/.npm/html5/0.2.5/package/lib/html5/tokenizer.js:813:7)
    at EventEmitter.tag_name_state (/usr/local/lib/node/.npm/html5/0.2.5/package/lib/html5/tokenizer.js:358:8)
    at EventEmitter.<anonymous> (/usr/local/lib/node/.npm/html5/0.2.5/package

Feels like there's something up with the HTML parser. Possibly due to bad HTML?

assert is not defined?

I'm bumping into some weird issues with assert not being defined. I'm running node 0.2.6 (though it happened on 0.2.5 as well) and zombie 0.8.6.

This happens any time I try an assert, but here's a simple illustration test.js:

var zombie = require("zombie");
var browser = new zombie.Browser();

var url = "http://semanticart.com";

browser.visit(url, function(err, browser) {
  var title = browser.text("title");

  assert.equal (title, "Semantic Art");   // ugh, assert not defined
});

which gives this error:

node.js:63
    throw e;
    ^
ReferenceError: assert is not defined
    at /Users/torgo/src/zombie/test.js:9:3
    at Browser.<anonymous> (/usr/local/lib/node/.npm/zombie/0.8.6/package/lib/zombie/browser.js:81:18)
    at /usr/local/lib/node/.npm/zombie/0.8.6/package/lib/zombie/browser.js:9:60
    at EventLoop.<anonymous> (/usr/local/lib/node/.npm/zombie/0.8.6/package/lib/zombie/eventloop.js:137:18)
    at Array.<anonymous> (/usr/local/lib/node/.npm/zombie/0.8.6/package/lib/zombie/eventloop.js:2:61)
    at EventEmitter._tickCallback (node.js:55:22)
    at node.js:773:9

I tried requiring assert in test_with_require.js:

var vows = require('vows'),
    assert = require('assert');

var zombie = require("zombie");
var browser = new zombie.Browser();

var url = "http://semanticart.com";

browser.visit(url, function(err, browser) {
  var title = browser.text("title");

  assert.equal (title, "Semantic Art");   // This is correct and throws no errors
  assert.equal (title, "Robocop Villa");  // This is incorrect, but the error message is poor
});

but the failing assertion gives a poor error message:

node.js:63
    throw e;
    ^
<error: TypeError: Cannot call method 'match' of undefined>
    at /Users/torgo/src/zombie/test_with_require.js:13:10
    at Browser.<anonymous> (/usr/local/lib/node/.npm/zombie/0.8.6/package/lib/zombie/browser.js:81:18)
    at /usr/local/lib/node/.npm/zombie/0.8.6/package/lib/zombie/browser.js:9:60
    at EventLoop.<anonymous> (/usr/local/lib/node/.npm/zombie/0.8.6/package/lib/zombie/eventloop.js:137:18)
    at Array.<anonymous> (/usr/local/lib/node/.npm/zombie/0.8.6/package/lib/zombie/eventloop.js:2:61)
    at EventEmitter._tickCallback (node.js:55:22)
    at node.js:773:9

I'm probably missing something obvious. Any help would be greatly appreciated.

Scripts are loaded in distinct environments

In a browser, the environment in which each script is loaded is shared among all scripts. So when you declare a top-level var in script A, script B will see it. That doesn't seem to work with Zombie, which I'm guessing is either directly due to jsdom or to how it's used. This breaks require.js but it's likely to break other scripts.

To reproduce, here are a few dummy files:

index.html

<html>
  <head>
    <script src="first.js"></script>
    <script src="second.js"></script>
  </head>
  <body><p>Rock on.</p></body>
</html>

first.js

var poof = 2;

second.js

console.log(poof);

The output will be:

Zombie: GET http://hommie/zombie-test/index.html => 200
Zombie: GET first.js
Zombie: GET second.js
Zombie: GET first.js => 200
Zombie: Running script from /zombie-test/first.js
Zombie: GET second.js => 200
Zombie: Running script from /zombie-test/second.js
poof is not defined

I'll see if I can dig out a fix, just need to read some code ;-) Thanks for zombie.js by the way.

Jammit issues

I'm not sure if this is Jammit or not, but basically it seems like I'm having load order problems with my javascript dependencies.

I created a sample application using Rails 3/backbone.js/jammit

The example is here:

http://backbone-rails3.heroku.com/#addresses

This works fine in firefox/chrome -- no warnings or errors.

When I try to run this through zombie.js (node v0.2.6) like:

var zombie = require("zombie");

zombie.visit("http://backbone-rails3.heroku.com/#addresses", { debug: true },
  function(err, browser) {
    if (err)
      console.log(err.stack);
    else
      console.log("The page:", browser.html());
  }
);

I get:

[~] node zombie-test.js
Zombie: GET http://backbone-rails3.heroku.com/#addresses
Zombie: GET http://backbone-rails3.heroku.com/#addresses => 200
Zombie: GET /assets/application.js?1294036300
Zombie: GET /assets/application.js?1294036300 => 200
Zombie: Running script from /assets/application.js
$ is not defined
Zombie: Running script from http://backbone-rails3.heroku.com/#addresses:undefined:undefined<script>
Zombie: Running script from http://backbone-rails3.heroku.com/#addresses:undefined:undefined<script>
The page: <!DOCTYPE html>
<--SNIP-->

Al the JS is 'jammed' up, so it's hard to read. I get errors locally too (when it's not compressed), about other symbols not being defined. Let me know if I can do anything to provide better information.

base64 dependency missing

The dependency is missing from package.json. I wanted to add it on my own, but were unsure which of the four base64 for node.js implementations I found on github you were intended to use ;)

Form submit

Hello,

It seems I can't get a form to submit. I used the browser.pressButton and browser.fire("click"...) with no success. The callback is triggered without errors but the browser location is not changed and no request are made.

I am using the latest node.js v0.3.7-pre and zombie 8.10 thru capybara-zombie (with some added code to do logging and check pressButton)

Am I missing something? Should I do anything special?

Thanks,
Julien.

Should cookies be set for the hostname and path they specify?

In history.coffee you set a cookie for a hostname and path like this:

browser.cookies(url.hostname, url.pathname).update response.headers["set-cookie"]

Should cookies instead be stored for the domain and path they they specify (if they do)? or not? Is that a security issue?

boblail/zombie@c483e8f is a commit that uses the cookie's path instead of the current request's path.

This commit causes zombie.js to behave as Capybara expects, but a few of Zombie's vows are broken. Before I changed those, I wanted to see if this was the way you would like Zombie to function.

top/window.top does not work properly

This is my first time playing with Zombie (or Node.js for that matter) so forgive me if I'm missing something obvious!

Basic framebuster code in javascript raises errors in Zombie that no browsers seem to exhibit - see a simple example of the JS here: http://en.wikipedia.org/wiki/Framekiller

My test script is:

var zombie = require("zombie");

zombie.visit("http://vm?version=v2", { debug: false }, function(err, browser) {
    if (err) {
        console.log(err.message);
    }
    else {
        console.log(browser.html());
        browser.clickLink("#thelogin a", function(err, browser) {
            if (err) {
                console.log(err.message);
            }
            else {
                console.log(browser.lastResponse);
                browser.dump();
            }
        });
    }

});

Produces the following output:

[successful requests]
Zombie: GET http://vm/js/default.js => 200
Zombie: Running script from /js/default.js
Zombie: ReferenceError: top is not defined, at Object. (/js/default.js:100:2)
top is not defined
[requests on rest of page]

You can check the actual JS file here: https://www.wepay.com/js/default.js. The relevant piece is here:

if (top != self) {
    // tries three times to bust frame, if successful will redirect away
    for (i = 0; top != self && i < 3; i++) {
        window.setTimeout(top.location.replace(self.location.href), 200);
    }
    // if redirect fails, throw up a big warning
}

Commenting out the framebuster entirely fixes the error. Adding if (typeof top == 'undefined') var top = window.top; causes window.setTimeout(top.location.replace(self.location.href), 200); to fail with the following error:
Zombie: TypeError: Cannot read property 'location' of undefined, at Object. (/js/default.js:110:25)
Cannot read property 'location' of undefined

NPM install still fails

npm install zombie
npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm info preinstall [email protected]
npm info preinstall [email protected]
npm info install [email protected]
npm info postinstall [email protected]
npm info preactivate [email protected]
npm info activate [email protected]
npm info postactivate [email protected]
npm info install [email protected]
Checking for program g++ or c++ : /usr/bin/g++
Checking for program cpp : /usr/bin/cpp
Checking for program ar : /usr/bin/ar
Checking for program ranlib : /usr/bin/ranlib
Checking for g++ : ok
Checking for node path : ok /home/felipe/.node_libraries
Checking for node prefix : ok /usr/local
'configure' finished successfully (0.063s)
Waf: Entering directory /home/felipe/.node_libraries/.npm/base64/1.0.1/package/build' [1/2] cxx: base64.cc -> build/default/base64_1.o ../base64.cc: In function ‘v8::Handle<v8::Value> base64_encode_binding(const v8::Arguments&)’: ../base64.cc:132: error: ‘class node::Buffer’ has no member named ‘data’ ../base64.cc:132: error: ‘class node::Buffer’ has no member named ‘length’ ../base64.cc: In function ‘v8::Handle<v8::Value> base64_decode_binding(const v8::Arguments&)’: ../base64.cc:150: error: ‘class node::Buffer’ has no member named ‘data’ ../base64.cc:150: error: ‘class node::Buffer’ has no member named ‘length’ Waf: Leaving directory/home/felipe/.node_libraries/.npm/base64/1.0.1/package/build'
Build failed: -> task failed (err #1):
{task: cxx base64.cc -> base64_1.o}
npm info [email protected] Failed to exec install script
npm ERR! install failed Error: [email protected] install: node-waf configure build
npm ERR! install failed sh failed with 1
npm ERR! install failed at ChildProcess. (/home/felipe/.node_libraries/.npm/npm/0.2.15/package/lib/utils/exec.js:25:18)
npm ERR! install failed at ChildProcess.emit (events.js:34:17)
npm ERR! install failed at ChildProcess.onexit (child_process.js:164:12)
npm info install failed rollback
npm info uninstall [ '[email protected]',
npm info uninstall '[email protected]' ]
npm info preuninstall [email protected]
npm info preuninstall [email protected]
npm info uninstall [email protected]
npm info uninstall [email protected]
npm info auto-deactive not symlink
npm info postuninstall [email protected]
npm info predeactivate [email protected]
npm info deactivate [email protected]
npm info postdeactivate [email protected]
npm info postuninstall [email protected]
npm info uninstall [email protected] complete
npm info uninstall [email protected] complete
npm info install failed rolled back
npm ERR! Error: [email protected] install: node-waf configure build
npm ERR! sh failed with 1
npm ERR! at ChildProcess. (/home/felipe/.node_libraries/.npm/npm/0.2.15/package/lib/utils/exec.js:25:18)
npm ERR! at ChildProcess.emit (events.js:34:17)
npm ERR! at ChildProcess.onexit (child_process.js:164:12)
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is most likely a problem with the base64 package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node-waf configure build
npm ERR! You can get their info via:
npm ERR! npm owner ls base64
npm ERR! There may be additional logging output above.
npm not ok

Cookie behavior

I have noticed a strange things in Cookies in general. I have an app in my hands that sets the cookie as below:

Set-Cookie: test=test

I've been reading the set-cookie documentation and it clearly says that the path for the cookie must be set to the path of the current resource setting the cookie:

      Path   Defaults to the path of the request URL that generated the
                Set-Cookie response, up to, but not including, the
                right-most /.

This is current Zombie.js behavior, it is completely fine. But all browsers that I've tested (Google Chrome and Firefox 3), they set the path to "/", which makes Zombie.js and browsers navigation inconsistent with each other.

I've been able to make a patch in Zombie.js to reflect browsers' behavior, but sounds really strange. Do you know anything in the issue?

CSSOM

I've noticed your repo includes CSSOM.js in dep/cssom.js and as a submodule. May I ask you whats's for?

One-file version of CSSOM.js (e.g. dep/cssom.js) primarily suited for browsers. It doesn't have CommonJS stuff like exports and require.

Today I've published cssom on npm. You can use it if you like.

Doesn't work on CentOS 5.5

My hands are tied and I'm forced to use CentOS 5.5. npm installed zombie and the various dependencies.

However, this:

var zombie = require("zombie");

console.log("Starting Zombie tests...");

b = new zombie.Browser();
b.visit("http://hudson2.company.com/login", function(err, browser) {
    console.log("wtf");
});


zombie.visit("http://hudson2.company.com/login", function(err, browser) {
    console.log("Logged in?");
    console.log(err);
    browser.
    fill("__ac_name", "username").
    fill("__ac_password", "password").
    pressButton("Login", function(err, browser) {
        console.log("what");
        console.log(err);
        console.log(browser.querySelector("li.username.first"));
    });
});

...doesn't work. Nothing in the functions passed to visit() seems to execute.

Typo in README.md

"Zombie.js is a lightweight framefork" => "... framework"

By the way, I love the documentation. "The Guts", "The Brains" really had me chuckling!

zombie.visit issues DNS request even for localhost/127.0.0.1

Example:

zombie.visit("http://127.0.0.1/", function (err, browser) {
    console.log(err);
});

yields

events:12
    throw arguments[1];
                   ^
Error: ECONNREFUSED, Could not contact DNS servers
    at IOWatcher.callback (dns:52:15)
    at node.js:773:9

when there's no internet connection. This breaks offline development.

I tried the following without the indirection through zombie, and this works perfectly fine:

var http = require('http');
var client = http.createClient(80, 'localhost');
var request = client.request('GET', '/', {'host': 'localhost'});
request.end();

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.