JSCover with PhantomJS - TypeError: 'null' is not an object

4.4k Views Asked by At

When I try to run JSCover with PhantomJS, I see below ERROR:

Steps followed:

1) Run the JSCover Server:

java -jar ~/JSCover/target/dist/JSCover-all.jar -ws --report-dir=report

2) Run the PhantomJS runner with JSCover: *phantomjs --debug=true ~/JSCover/src/test/javascript/lib/PhantomJS/run-jscover-jasmine.js localhost8080/<app>/module/framework/test/SpecRunner.html

TypeError: 'null' is not an object(evaluating''document.body.querySelector('.description').innerText')`

phantomjs://webpage.evaluate():3 phantomjs://webpage.evaluate():22 phantomjs://webpage.evaluate():22 2013-09-19T16:36:07 [DEBUG] WebPage - evaluateJavaScript result QVariant(, ) 2013-09-19T16:36:07 [DEBUG] WebPage - evaluateJavaScript "(function() { return (function () { jscoverage_report('phantom'); })(); })()" 2013-09-19T16:36:07 [DEBUG] WebPage - evaluateJavaScript result QVariant(, ) 2013-09-19T16:36:07 [DEBUG] Network - Resource request error: 5 ( "Operation canceled" ) URL: localhost8080/<app_home>/lib/backbone/1.0.0/backbone.js?cb=0.5381254460662603

3

There are 3 best solutions below

0
edtay On

I faced with the same issue when I try running Jasmine with PhantomJS. I realized that the latest version of Jasmine-html.js (jasmine-2.0.0-rc2) does not go along with PhantomJS's run-jasmine.js (phantomjs-1.9.2-windows).

In the jasmine-2.0.0-rc2 version of Jasmine-html.js, The '.description' class is not available if all tests passed. This 'description' class is created only if any test failed.

Thus, when I run the phantomjs with all tests passed, I get the above error message. I modified run-jasmine.js to adapt to Jasmine-html.js (jasmine-2.0.0-rc2) to resolve this issue.

1
Gareth On

Are you loading your tests asynchronously? I use requirejs for modular javascript. It is also used to load the test specs:

<script data-main='SpecRunner' src='/test/scripts/libs/require.js'></script>

When using JSCover, the run-jscover-jasmine.js script does not account for this async behaviour, so the DOM nodes referenced in the query do not exist (yet). I modified the script to delay the waitFor call by 1 second:

page.open(system.args[1], function(status){
    if (status !== "success") {
        console.log("Unable to access network");
        phantom.exit();
    } else {
        // Added 1s delay here
        window.setTimeout(function() {
            waitFor(function(){
                return page.evaluate(function(){
                    return document.body.querySelector('.symbolSummary .pending') === null
                });
            }, function(){
                var exitCode = page.evaluate(function(){
                    console.log('');
                    console.log(document.body.querySelector('.description').innerText);
                    var list = document.body.querySelectorAll('.results > #details > .specDetail.failed');
                    if (list && list.length > 0) {
                        console.log('');
                        console.log(list.length + ' test(s) FAILED:');
                        for (i = 0; i < list.length; ++i) {
                            var el = list[i],
                                desc = el.querySelector('.description'),
                                msg = el.querySelector('.resultMessage.fail');
                            console.log('');
                            console.log(desc.innerText);
                            console.log(msg.innerText);
                            console.log('');
                        }
                        return 1;
                    } else {
                        console.log(document.body.querySelector('.alert > .passingAlert.bar').innerText);
                        return 0;
                    }
                });
                page.evaluate(function(){
                    jscoverage_report('phantom');
                });
                phantom.exit(exitCode);
            });
        }, 1000);
    }
});

Depending on the amount of code loaded, you may have to increase the delay.

2
Dr.Knowitall On

This was an issue that I ran into yesterday. It turns out that the example script does not work for newer versions, so I built a new Phantom Script that works for Jasmine 2.X which fixes it. You can locate the working script here in my repository:

https://github.com/tkaplan/PhantomJS-Jasmine