nathanboktae/mocha-casperjs

Errors when using slimerjs

davidascher opened this issue · 13 comments

davida@suki ~/s/m/component-button> more test/t2.js 
describe('Google searching', function() {
  before(function() {
    casper.start('http://www.google.fr/')
  })

  it('should retrieve 10 or more results', function() {
    casper.then(function() {
      'Google'.should.matchTitle
      'form[action="/search"]'.should.be.inDOM.and.be.visible
      this.fill('form[action="/search"]', {
        q: 'casperjs'
      }, true)
    })

    casper.waitForUrl(/q=casperjs/, function() {
      (/casperjs/).should.matchTitle
    })
  })
})
davida@suki ~/s/m/component-button> mocha-casperjs 


  Google searching
    ◦ should retrieve 10 or more results: 2013-11-18 23:31:16.908 phantomjs[54885:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-11-18 23:31:16.913 phantomjs[54885:110b] CoreText performance note: Set a breakpoint on CTFontLogSuboptimalRequest to debug.
2013-11-18 23:31:16.930 phantomjs[54885:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-11-18 23:31:17.076 phantomjs[54885:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-11-18 23:31:17.085 phantomjs[54885:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-11-18 23:31:17.085 phantomjs[54885:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-11-18 23:31:17.087 phantomjs[54885:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-11-18 23:31:17.088 phantomjs[54885:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
    1) should retrieve 10 or more results
TypeError: 'undefined' is not an object (evaluating ''Google'.should.matchTitle')
TypeError: 'undefined' is not an object (evaluating 'backtrace.forEach')        
  /usr/local/Cellar/casperjs/1.1-beta2/libexec/modules/casper.js:195
  /usr/local/Cellar/casperjs/1.1-beta2/libexec/modules/events.js:104 in emit
  /usr/local/Cellar/casperjs/1.1-beta2/libexec/modules/casper.js:1524 in runStep
  /usr/local/Cellar/casperjs/1.1-beta2/libexec/modules/casper.js:368 in checkStep
    2) should retrieve 10 or more results
davida@suki ~/s/m/component-button> 

(I'm not worried about the phantomjs font complaints, but it's failing your sample, so I must be doing something wrong.

davida@suki ~/s/m/component-button> casperjs --version
1.1.0-beta2
davida@suki ~/s/m/component-button> phantomjs --version
1.9.2

Any ideas?

Made it maybe further, maybe further back:

davida@suki ~/s/m/component-button> mocha-casperjs --log-level=debug --engine=slimerjs
[debug] [phantom] could not load chai Error: /usr/local/lib/node_modules/chai is not a supported type file
Mocha is not defined                                                            
  /Users/davida/src/mozilla-appmaker/component-button:48
davida@suki ~/s/m/component-button> mocha-casperjs --log-level=debug 
[debug] [phantom] could not load casper-chai: CasperError: Can't find module /usr/local/lib/node_modules/casper-chai


  Google searching
[info] [phantom] Starting...
[info] [phantom] Execution timeout set to 10000ms
    ◦ should retrieve 10 or more results: [info] [phantom] Running suite: 4 steps
[debug] [phantom] opening url: http://www.google.fr/, HTTP GET
[debug] [phantom] Navigation requested: url=http://www.google.fr/, type=Other, willNavigate=true, isMainFrame=true
[debug] [phantom] url changed to "http://www.google.fr/"
2013-11-19 16:21:16.849 phantomjs[69180:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-11-19 16:21:16.849 phantomjs[69180:110b] CoreText performance note: Set a breakpoint on CTFontLogSuboptimalRequest to debug.
2013-11-19 16:21:16.863 phantomjs[69180:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-11-19 16:21:17.034 phantomjs[69180:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-11-19 16:21:17.034 phantomjs[69180:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-11-19 16:21:17.036 phantomjs[69180:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-11-19 16:21:17.037 phantomjs[69180:110b] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
[debug] [phantom] Successfully injected Casper client-side utilities
[debug] [phantom] start page is loaded
[info] [phantom] Step anonymous 3/4 http://www.google.fr/ (HTTP 200)
    1) should retrieve 10 or more results
TypeError: 'undefined' is not an object (evaluating ''form[action="/search"]'.should.be.inDOM.and')
TypeError: 'undefined' is not an object (evaluating 'backtrace.forEach')        
  /usr/local/Cellar/casperjs/1.1-beta2/libexec/modules/casper.js:195
  /usr/local/Cellar/casperjs/1.1-beta2/libexec/modules/events.js:104 in emit
  /usr/local/Cellar/casperjs/1.1-beta2/libexec/modules/casper.js:1524 in runStep
  /usr/local/Cellar/casperjs/1.1-beta2/libexec/modules/casper.js:368 in checkStep
    2) should retrieve 10 or more results
davida@suki ~/s/m/component-button> 

Yeah you need to supply the path to Chai and Casper-chai. I do need to improve discovery of this or just depend on chair directly

Try

npm install chai
npm install casper-chai
mocha-casperjs --chai-path=node_modules/chai --casper-chai-path=node_modules/casper-chai

Hmm, that doesn't change anything (same results as above).

Oh your using slimerjs? I haven't tested that yet. Look at the top and you see its failing to require chai, and also saying Mocha isn't defined. There maybe gotchas between the different requires

Also casper-chai should be 0.1.x as 0.2.x won't work but I may have not been explicit with my versioning. I'll need to look into the slimerjs issues.

gdw2 commented

I was getting the error (using casperjs):

TypeError: 'undefined' is not an object (evaluating ''Google'.should.matchTitle')

The suggestions in #5 (comment) helped! Thanks!

I briefly explored getting slimerjs working. Here's what I turned up.

SlimerJS's require() is not phantomjs compatible. By policy, it doesn't understand node_modules or folder modules. And require()d files run in a sandbox. So they can't pass globals out, and require extra work to pass globals in (via require.globals).

So mocha and chai can't Just Work. The browser builds don't use module.export, and the source files can't be loaded.

One solution strategy would be to find/create a phantomjs-compatible require implementation, and shim it in on slimerjs. This would also permit require() to be used normally in people's tests.

Below is a spike of a simpler approach, of faking just enough of require() to load the browser build files. It's a toy: it's been tested on only a single file, and casper-chai doesn't work even there. And I'm unlikely to pursue it further. But fyi. Thanks for your work.

--- node_modules/mocha-casperjs/bin/cli.js.orig 2014-03-23 21:00:58.000000000 -0400
+++ node_modules/mocha-casperjs/bin/cli.js  2014-03-23 21:07:14.000000000 -0400
@@ -7,6 +7,22 @@
   return fs.absolute(opts[what + '-path'] || opts['mocha-casperjs-path'] + '/../../node_modules/' + what)
 }

+// require()
+var require2 = function(mod) { return require(mod) };
+var isSlimerJS = phantom.defaultPageSettings.userAgent.match(/Slimer/);
+if (isSlimerJS) {
+  require2 = function (mod,restOfPath) {
+    if (!restOfPath && !fs.exists(mod) && fs.exists(mod+".js"))
+      restOfPath = ".js"
+    var path = mod + restOfPath;
+    var code = fs.open(path, "r").read();
+    var wrap = new Function('module','exports','global',code);
+    var mod = {exports:{}};
+    wrap(mod,mod.exports,this);
+    return mod.exports;
+  }
+}
+
 if (fs.exists('mocha-casperjs.opts')) {
   var extraOpts = cli.parse(fs.read('mocha-casperjs.opts').split('\n')).options

@@ -36,10 +52,10 @@
 }

 // Load the precompiled mocha from the root of it's module directory
-require(getPathForModule('mocha') + '/mocha')
+require2(getPathForModule('mocha') + '/mocha')

 try {
-  this.chai = require(getPathForModule('chai'))
+  this.chai = require2(getPathForModule('chai'),'/chai.js')
   this.chai.should()

   // expose expect globally if requested
@@ -49,7 +65,7 @@

   // optionally try to use casper-chai if available
   try {
-    this.chai.use(require(getPathForModule('casper-chai')))
+    this.chai.use(require2(getPathForModule('casper-chai'),'/lib/casper-chai.coffee'))
     casper.log('using casper-chai', 'debug', 'mocha-casperjs')
   }
   catch (e) {
@@ -60,7 +76,7 @@
 }

 // Initialize the core of mocha-casperjs given the loaded Mocha class and casper instance
-require(fs.absolute((opts['mocha-casperjs-path'] || '..') + '/mocha-casperjs'))(Mocha, casper, require('utils'))
+require2(fs.absolute((opts['mocha-casperjs-path'] || '..') + '/mocha-casperjs'))(Mocha, casper, require('utils'))

 mocha.setup({
   ui: 'bdd',
@@ -141,7 +157,7 @@
 tests.map(function(test) {
   return fs.absolute(test).replace('.coffee', '').replace('.js', '')
 }).forEach(function(test) {
-  require(test)
+  require2(test)
 })

 // You can now set breakpoints in your scripts since they are loaded now

By policy, it doesn't understand node_modules or folder modules. And require()d files run in a sandbox.

By policy? huh... I thought the overarching goal was phantomjs compatibility...

Thanks for the investigation work - much appreciated.

First off, thanks for the work to get mocha working with phantom so smoothly - it works great. Judging by this threat getting slimerjs to work will be a right faff though. I would have thought that the onus would be on slimerjs to be changed to be more consistent with phantomjs and its "requires" logic. I had a quick dig and this was all I could find - laurentj/slimerjs#170. So perhaps it's not a priority for slimerjs right now.

Can I suggest that the mention of slimerjs at the top of readme is removed for now? (Or perhaps even include a link to this issue as a warning about the current compatbility problems with slimerjs.)

@kelveden the issue you just mentioned is @mncharity 's pull request to fix it getting accepted. Great to see that! I'll look at slimerjs again soon. I've ran into more bugs / gotchas with phantomjs recently so I have more motiviation now.

But yes, if not resolved soon I should do the short term thing and update the readme.

Thanks for the quick response @nathanboktae - and sorry it's taken me so long to respond! It sounds like it's under control: thanks for the update.

FTR comment #5 has a typo --caspet-chai, fixed:

npm install chai
npm install casper-chai
mocha-casperjs --chai-path=node_modules/chai --casper-chai-path=node_modules/casper-chai

fixed, thanks.