Closed mg closed 9 years ago
Made some chances to karma.conf.js, register the browserify framework first, removed reporting plugin, only include spec file in files and preprocessor:
module.exports = function(karma) {
karma.set({
autoWatch : false,
singleRun: true,
frameworks: ['browserify', 'jasmine'],
browsers : ['PhantomJS'],
plugins : [
'karma-browserify',
'karma-jasmine',
'karma-phantomjs-launcher'
],
files: ['hello.spec.js'],
preprocessors: {
'hello.spec.js': [ 'browserify' ]
},
browserify: {
plugin: ['proxyquireify/plugin']
},
});
};
Still the same output:
DEBUG [config]: Loading config /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/karma.conf.js
DEBUG [plugin]: Loading plugin karma-browserify.
DEBUG [plugin]: Loading plugin karma-jasmine.
DEBUG [plugin]: Loading plugin karma-phantomjs-launcher.
DEBUG [framework.browserify]: created browserify bundle: /var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/9409150f6698b81bf6aaf0b28d56eb7f01704769.browserify
DEBUG [framework.browserify]: add bundle to config.files at position 0
INFO [karma]: Karma v0.12.28 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
DEBUG [temp-dir]: Creating temp dir at /var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/karma-24170408
DEBUG [launcher]: /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/karma-phantomjs-launcher/node_modules/phantomjs/lib/phantom/bin/phantomjs /var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/karma-24170408/capture.js
DEBUG [framework.browserify]: building bundle
DEBUG [framework.browserify]: adding hello.spec.js to bundle
DEBUG [framework.browserify]: bundling
INFO [framework.browserify]: 7920 bytes written (0.11 seconds)
INFO [framework.browserify]: bundle built
DEBUG [watcher]: Resolved files:
/Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/karma-jasmine/lib/jasmine.js
/Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/karma-jasmine/lib/boot.js
/Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/karma-jasmine/lib/adapter.js
/var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/9409150f6698b81bf6aaf0b28d56eb7f01704769.browserify
/Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/hello.spec.js
DEBUG [web-server]: serving: /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/karma/static/client.html
DEBUG [web-server]: serving: /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/karma/static/karma.js
DEBUG [web-server]: upgrade /socket.io/1/websocket/F88RIvgGCOov3ux-QC2z
DEBUG [karma]: A browser has connected on socket F88RIvgGCOov3ux-QC2z
INFO [PhantomJS 1.9.8 (Mac OS X)]: Connected on socket F88RIvgGCOov3ux-QC2z with id 24170408
DEBUG [launcher]: PhantomJS (id 24170408) captured in 2.007 secs
DEBUG [web-server]: serving: /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/karma/static/context.html
DEBUG [web-server]: serving (cached): /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/karma-jasmine/lib/jasmine.js
DEBUG [web-server]: serving (cached): /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/karma-jasmine/lib/boot.js
DEBUG [web-server]: serving (cached): /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/karma-jasmine/lib/adapter.js
DEBUG [web-server]: serving (cached): /var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/9409150f6698b81bf6aaf0b28d56eb7f01704769.browserify
DEBUG [web-server]: serving (cached): /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/hello.spec.js
PhantomJS 1.9.8 (Mac OS X) ERROR
ReferenceError: Can't find variable: require
at /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/hello.spec.js:1
DEBUG [karma]: Run complete, exiting.
DEBUG [launcher]: Disconnecting all browsers
DEBUG [framework.browserify]: cleaning up
DEBUG [launcher]: Process PhantomJS exited with code 0
DEBUG [temp-dir]: Cleaning temp dir /var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/karma-24170408
Could you please push up a repo that reproduces this.
My guess is that karma somehow does something that breaks what proxyquireify is trying to do.
Could you please include a script in the package json that allows me to just run it to reproduce your problem? Also please ensure that everything I need is included as a package dependency.
npm install karma start karma.conf.js --log-level debug
Don't have karma, so needs to be part of the dependency. Please do as I suggested and prep the repo so all we have to do is:
npm install && npm test
Thanks.
No problem. npm test works now
Some update. Chanced the spec file to only require, not use proxyquerify:
var Hello= require('./hello');
//var proxyquire = require('proxyquireify')(require);
describe('testing hello', function () {
//var Hello= proxyquire('./hello');
it('should say hi', function() {
expect(Hello.hello()).toBe('hello');
});
});
Still got the same error. Commented out the proxyquirefy plugin in karma.conf.js:
module.exports = function(karma) {
karma.set({
autoWatch : false,
singleRun: true,
frameworks: ['browserify', 'jasmine'],
browsers : ['PhantomJS'],
plugins : [
'karma-browserify',
'karma-jasmine',
'karma-phantomjs-launcher'
],
files: ['hello.spec.js'],
preprocessors: {
'hello.spec.js': [ 'browserify' ]
},
browserify: {
//plugin: ['proxyquireify/plugin']
},
logLevel: karma.LOG_DEBUG
});
};
Now it works, i.ie. the test runs, but of course I can't stub and mock. So the error went away after I removed the proxyquireyf plugin.
I've put some console.log entries in the proxyquireify module, specifically at the entry at each of the functions plugin and replacePrelude in replace-prelude.js and outer, findProxyquireifyName, newRequire, req and moduleRequire in prelude.js.
The output is:
~/G/B/S/C/browserifytest (master) npm test
> @1.0.0 test /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest
> ./node_modules/karma/bin/karma start karma.conf.js
in plugin
in replacePrelude
INFO [karma]: Karma v0.12.28 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
in replacePrelude
INFO [framework.browserify]: 11481 bytes written (0.09 seconds)
INFO [framework.browserify]: bundle built
INFO [PhantomJS 1.9.8 (Mac OS X)]: Connected on socket KNhOZTZSGjf9Fs82NCX6 with id 26579723
PhantomJS 1.9.8 (Mac OS X) LOG: 'in outer'
PhantomJS 1.9.8 (Mac OS X) LOG: 'findProxyquireifyName'
PhantomJS 1.9.8 (Mac OS X) LOG: 'in newRequire'
PhantomJS 1.9.8 (Mac OS X) ERROR
ReferenceError: Can't find variable: require
at /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/hello.spec.js:1
npm ERR! Test failed. See above for more details.
npm ERR! not ok code 0
Could you try to isolate this by removing karma from the equation?
I.e. just use proxyquireify
somehow -- don't even have to test anything.
You could also see if you have more luck with zuul.
Cant not use karma, since that is the testing solution we use.
But what is there anything in this example that is unusual? Isn't this as plain vanilla combination of karma + browserify + karma-browserify + proxyquireify as it can get? Why isn't everyone using proxyquireify with karma not getting this error? What am I doing that is so unique?
I added https://github.com/bendrucker/proxyquire-universal and registered it as a plugin instead of proxyquireify, failed the same way.
Cant not use karma, since that is the testing solution we use.
I'm not saying to not use it ever, just in order to narrow down the problem it would be interesting to take it out of the equation for a second.
@mg, I get the exact same error with the same sort of simple setup you have.
@thlorenz it is not trivial to take Karma out of the equation since that is what actually runs the tests.
Without it, we wouldn't be able to run the tests in a browser to attempt to check if that solves it. We would end up needing to wire up PhantomJS, WebkitTestDriver, and others manually which would likely just have other issues. Do you have any recommendations of something we are overlooking?
it is not trivial to take Karma out of the equation
It is quite trivial actually, just create a file that uses proxyquireify
, browserify it and load the bundle into your browser.
Keep in mind that this is not the end solution, just in order to diagnose the problem.
We need to figure out if it's Karma not working together properly here. I haven't seen this problem anywhere without it. It may be doing something that conflicts with proxyquireify
and may have to be fixed there, but first we need to narrow down the cause of the problem.
hi @thlorenz, I asked the people at karma-browserify and they said, quote:
"Proxyquireify rewrites the bundle prelude such that there's no longer a global require which karma-browserify depends on."
Does that clarify what is going on?
This is a temporary fix, i made to counter this issue in my gulp based test system,
make it can help solve the issue temporarily until there is a proper fix
@git-jiby-me Awesome, I'll give that a try. Just for us to be explicit, that modified line is technically window.request = newRequest
, correct?
@mg I was suspecting something along those lines.
proxyquireify has to change the prelude in order to inject itself into the require
chain. There is no other way to do this that I'm aware of.
I'm unclear why karma depends on a global require.
If renaming the require
to something else as outlined in the stackoverflow answer above fixes things we could ponder making proyquireify doing this to begin with.
@jhiesey would like to get your input on this.
Renaming the require does indeed solve the problem and gives me access to both the original and the new require in my karma tests.
@TheSavior the modified line is
require = newRequire;
as global require is already in the scope, so just need to assign to it, no need to do directly in window
@git-jiby-me that fix doesn't seem to work for me, blows up with:
PhantomJS 1.9.8 (Mac OS X) testing hello encountered a declaration exception FAILED
TypeError: 'undefined' is not a function (evaluating 'Error.captureStackTrace(this, ProxyquireifyError)')
at ProxyquireifyError (/var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/9409150f6698b81bf6aaf0b28d56eb7f01704769.browserify:98:0 <- node_modules/proxyquireify/index.js:5:0)
at validateArguments (/var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/9409150f6698b81bf6aaf0b28d56eb7f01704769.browserify:117:0 <- node_modules/proxyquireify/index.js:24:0)
at /var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/9409150f6698b81bf6aaf0b28d56eb7f01704769.browserify:159:0 <- node_modules/proxyquireify/index.js:66:0
at /var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/9409150f6698b81bf6aaf0b28d56eb7f01704769.browserify:202:0 <- hello.spec.js:4:0
at /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/karma-jasmine/lib/boot.js:59
at /var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/9409150f6698b81bf6aaf0b28d56eb7f01704769.browserify:208:0 <- hello.spec.js:10:0
at newRequire (/var/folders/qg/r32h5c8s3sb5s4xy6lpthn680000gn/T/9409150f6698b81bf6aaf0b28d56eb7f01704769.browserify:75:0 <- /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/node_modules/proxyquireify/lib/prelude.js:75:0)
at /Users/magnusorngylfason/Google Drive/Business/Shopping Network/Code/browserifytest/hello.spec.js:1
PhantomJS 1.9.8 (Mac OS X): Executed 1 of 1 (1 FAILED) ERROR (0.015 secs / 0.001 secs)
@mg That seems like an unrelated error and is part of your browserified bundle: https://www.google.com/search?q=captureStackTrace+is+not+a+function
It turned out that I wasn't sending a stub object with proxyquireify, .e.g.
var Obj= proxyquireify('./obj.js');
Once I added the stub, the error went away. So Im totally down with require=newRequire, happy days, thank you @git-jiby-me
Clearly this is working for people right now as is, it just breaks for us using Karma. Has anyone tried using this fix in a non-karma environment?
I've bumped into this to. Karma + Browserify + Reactify. @git-jiby-me 's fix worked a charm - although it does make me feel a little uneasy :baby_chick:
This should be a relatively easy fix on proxyquireify's end of things. Basically the prelude replacement code needs to check b._expose
. If it's empty, require
won't be global normally and the replacement doesn't need to be either. If it has any keys, then newRequire
needs to be on the window
with as b._options.externalRequireName
('require'
by default).
If you want details on why karma-browserify exposes your test files, read on:
I'm a maintainer over at karma-browserify and just wanted to weigh in on exactly what's going on here and especially speak to the questions Thorsten raised in https://github.com/thlorenz/proxyquireify/issues/21#issuecomment-66531714. karma-browserify is essentially a collection of hacks that deals with shortcomings in the Karma API and quirks in the Browserify API.
The core issue is that portion of Karma's API that allows for changing the files that it synchronizes with the browser is synchronous. The framework API was designed for things like karma-mocha
which just needs to add two static scripts: mocha and some glue between the Mocha API and the Karma browser API. karma-browserify isn't that simple. Generating the bundle is async. The preprocessor API in Karma (e.g. compiling CoffeeScript to JS) is async.
karma-browserify is typically receiving a glob of files that matches multiple test files. Then this is what it does:
'require(' + path ')'
back to KarmaOn top of this, it hacks in a preprocessor for the randomized static bundle. This preprocessor is basically there to hold up Karma until the initial bundle has finished. This is why, when in doubt, you design your APIs to be async.
Seems like a weird quirk with karma-browserify/karma then. Possibly ask them to fix/remove some of their hacks?
If there is a straightforward solution we could apply to proxyquireify to fix this I'm open to it, but seems like we'd have to fix one hack with another ugly hack.
I'm leaning towards closing this, @bendrucker if you agree go ahead and do so. Thanks.
This should be a relatively easy fix on proxyquireify's end of things
If anyone wants to stab at this however I'm open to merging this in (as long as its not too ugly and won't potentially cause problems in other cases).
Yeah unfortunately it's a karma thing and karma-browserify is hacky because that's the only way to go.
I just dug in and this is a proxyquireify bug and a one line fix :)
Wait til you see
So technically it was a 2 line fix :smile:
My missive about the crazy hoops karma-browserify jumps through above was totally unnecessary. This was just an obscure proxyquireify bug. Commit message describes the issue if anyone cares to take a look for themselves.
bad news: Anyone using @git-jiby-me 's patch will find their lives ruined by the v1.2.0 good news: You can just remove the patch entirely and everything will be fine!
This is why the advice on the SO post is bad. If you catch a bug in a project and need to hotfix it you should always fork and use a git dep.
@Dakuan so removing that patch and using the latest proxyquireify version makes it work with karma for you as well?
@thlorenz correct!
Can't get rid of this error. Here's my package.json:
karma.conf.js
hello.js
hello.spec.js
Output from karma start karma.conf.js --log-level debug
Any ideas? This has been driving my crazy all weekend.