_From @warren-bank on September 21, 2016 23:48_
_(edit: you can jump ahead to my final comment.. to see the very minor code patch I would suggest be applied, which would fix this issue)_
I was super pleased to discover that the karma test runner could be used in conjunction with the interactive debugger:
tns test android --debug-brk
However, I did want to raise one small issue..
The application crashed because of an uncaught exception. You can look at "stackTrace" or "nativeException" for more detailed information about the exception.
com.tns.NativeScriptException:
Calling js method run failed
TypeError: document.createElement is not a function
File: "/data/data/org.nativescript.ExampleProject/files/app/tns_modules/zone.js/dist/zone-node.js, line: 201, column: 25
StackTrace:
Frame: function:'JSONPPolling.doPoll', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/nativescript-unit-test-runner/socket.io.js', line: 1085, column: 25
Frame: function:'Polling.poll', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/nativescript-unit-test-runner/socket.io.js', line: 1740, column: 8
Frame: function:'Polling.doOpen', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/nativescript-unit-test-runner/socket.io.js', line: 1684, column: 8
Frame: function:'Transport.open', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/nativescript-unit-test-runner/socket.io.js', line: 827, column: 10
Frame: function:'Socket.open', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/nativescript-unit-test-runner/socket.io.js', line: 248, column: 13
Frame: function:'Socket', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/nativescript-unit-test-runner/socket.io.js', line: 129, column: 8
Frame: function:'Socket', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/nativescript-unit-test-runner/socket.io.js', line: 55, column: 41
Frame: function:'Manager.open.Manager.connect', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/nativescript-unit-test-runner/socket.io.js', line: 4549, column: 17
Frame: function:'', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/nativescript-unit-test-runner/socket.io.js', line: 4859, column: 12
Frame: function:'ZoneDelegate.invokeTask', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/zone.js/dist/zone-node.js', line: 323, column: 38
Frame: function:'Zone.runTask', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/zone.js/dist/zone-node.js', line: 223, column: 48
Frame: function:'ZoneTask.invoke', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/zone.js/dist/zone-node.js', line: 391, column: 34
Frame: function:'ZoneDelegate.invoke', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/zone.js/dist/zone-node.js', line: 290, column: 29
Frame: function:'Zone.runGuarded', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/zone.js/dist/zone-node.js', line: 197, column: 48
Frame: function:'', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/zone.js/dist/zone-node.js', line: 173, column: 30
Frame: function:'java.lang.Runnable.run', file:'/data/data/org.nativescript.ExampleProject/files/app/tns_modules/timer/timer.js', line: 17, column: 13
the file nativescript-unit-test-runner/socket.io.js is pretty much littered with references to the DOM, and attempts to perform DOM updates.
in particular:
JSONPPolling.prototype.doPollJSONPPolling.prototype.doWriteuseColorslocalstoragenavigator.userAgentI haven't done any digging into this.
I'm not aware of the low-level details of precisely how socket.io is used by the test runner,
or why the debugger would trigger additional polling,
or why this error didn't occur while either:
and only occurs while debugging these unit tests.
Maybe this is nothing more than pilot error (on my part)..
I wouldn't rule it out, though I don't think that I've done anything wrong.
In any case, I just wanted to share my observations..
in case somebody who knows the code and how things are glued together..
might read this and mutter: "oh shoot, yep.. easy fix"
_Copied from original issue: NativeScript/nativescript-unit-test-runner#17_
_From @warren-bank on September 22, 2016 0:55_
wait.. there's a chance this is the result of something I did wrong (pilot error)..
I'm re-running some tests now, and will report back shortly..
_From @warren-bank on September 22, 2016 1:48_
ok.. it's a legit issue.. has nothing to do with a bit of zone.js error-catching trickery that I had in place.
zone.js wasn't even included under tns_modulessocket.io.js within the function JSONPPolling.prototype.doPoll at the line where document.createElement is first used_From @warren-bank on September 22, 2016 1:57_
incidentally.. and feel free to completely ignore this suggestion.. which has very little to do with the issue at hand (though it may actually help to catch this and other uncaught exceptions, and conditionally ignore them).. but is just a feature that you may want to consider including.. possibly as an optional feature that could be toggled on/off with a boolean flag in karma.conf.js
and please keep in mind that this code is very rough.. and I'm still working on getting it right.. but something along the lines of:
/* ------------------------------------------------------------------
* summary:
* --------
* all tests are passed to the testing framework
* using the function signature:
* it('Do this and then do that', function (done) {...}
*
* when timers (ex: setTimeout) are called by the code under test,
* Exceptions that may occur when the timer triggers will NOT
* be caught by the testing framework,
* and will result in the test suite ending prematurely,
* with a terse error message about an "uncaught Exception".
*
* the purpose of this file is to use "zone.js"
* to wrap the "it" function,
* in such a way that Exceptions raised by asynchronous timers
* will NOT result in an "uncaught Exception".
*
* the Zone will report the error to mocha,
* which will then fail the particular test,
* and then continue processing the remainder of the test suite.
* ------------------------------------------------------------------
* references:
* -----------
* https://github.com/angular/zone.js/
* https://github.com/angular/zone.js/issues/418
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length
* ------------------------------------------------------------------
*/
require('zone.js/dist/zone-node');
var old_it = global.it;
var new_it = function(desc, test){
// it.skip()
if (test === undefined){
return old_it(desc);
}
var my_done;
var my_zone = global.Zone.current.fork({
onHandleError: function(){
var error = arguments[3];
my_done(error);
// zone-node.js, lines: 201, 292
// return value serves as a boolean flag for whether or not to throw the exception.
// - truthy: throw, which will be uncaught and crash the test runner.
return false;
}
});
return old_it(desc, function(done){
my_done = done;
my_zone.run(function(){
test(done);
if (test.length === 0){
done();
}
});
});
};
new_it.skip = old_it.skip;
new_it.only = old_it.only;
new_it.retries = old_it.retries;
global.it = new_it;
karma.conf.js:...
files: [
'app/components/**/*.js',
'app/*.js',
'app/tests/*.js'
],
frameworks: ['mocha', 'chai'],
reporters: ['mocha'],
colors: false,
singleRun: true,
captureTimeout : 300000, // default: 60,000
browserDisconnectTimeout : 10000, // default: 2,000
browserDisconnectTolerance : 1, // default: 0
browserNoActivityTimeout : 50000, // default: 10,000
...
require('./lib/zones.js');
global.mocha.setup({
timeout: 300000
});
global.chai.config.includeStack = true;
global.chai.config.truncateThreshold = 0;
global.chai.use( require('./lib/chai-as-promised.js') );
describe('test suite', function () {
require('./units/test.01.js');
require('./units/test.02.js');
require('./units/test.03.js');
});
_From @warren-bank on September 22, 2016 5:29_
sorry for being so verbose, but i have a few additional observations regarding the issue..
ExampleProject/platforms/android/src/main/assets/app/tns_modules/nativescript-unit-test-runnerconfig.jsmodule.exports = {"port":"9876","ips":["192.168.1.104","127.0.0.1"],"options":{"debugTransport":false,"debugBrk":true,"watch":false}}main-view-model.js...
function enableSocketIoDebugging() {
console.log('enabling socket.io debugging');
global.localStorage = {
debug: "*"
};
global.window = global;
}
var config = require('./config');
...
if (config.options.debugTransport) {
enableSocketIoDebugging();
}
...
var io = require('./socket.io');
var socket = this.socket = io.connect(this.baseUrl, {forceBase64: true});
...
if (config.options.debugBrk) {
debugger;
}
...
socket.io.jsmodule.exports = exports = lookup;
exports.connect = lookup;
function lookup(uri, opts) {
...
io = Manager(source, opts);
...
return io.socket(parsed.path);
}
Manager.prototype.socket = function(nsp){
...
socket = new Socket(this, nsp);
...
};
function Socket(uri, opts){
...
this.transports = opts.transports || ['polling', 'websocket'];
...
}
main-view-model.jsvar socket = this.socket = io.connect(this.baseUrl, {forceBase64: true, transports: ['websocket']});_From @warren-bank on September 22, 2016 6:36_
(update: please disregard the information in this comment)
yeah, looks good now.
I'm stepping through an enormous test suite..
giving it plenty of time to poll or do whatever else might cause a problem..
I left the breakpoint in "socket.io.js" but it hasn't been hit at all..
it may be premature to call this patch a fix, but it certainly appears to be.
short tldr; version
nativescript-unit-test-runner/main-view-model.jsvar socket = this.socket = io.connect(this.baseUrl, {forceBase64: true});var socket = this.socket = io.connect(this.baseUrl, {forceBase64: true, transports: ['websocket']});_From @warren-bank on September 22, 2016 7:36_
(update: please disregard the information in this comment)
I have another observation, which is loosely related and most-likely a fairly minor issue..
NSUTR-socket.io: transport close
/data/data/org.nativescript.ExampleProject/files/app/tns_modules/nativescript-unit-test-runner/main-view-model.js:90
NSUTR-socket.io: 1
/data/data/org.nativescript.ExampleProject/files/app/tns_modules/nativescript-unit-test-runner/main-view-model.js:90
socket.io.js at the line in JSONPPolling.prototype.doPoll that touches the DOM and triggers the uncaught exceptionso..
_From @warren-bank on September 22, 2016 8:56_
ok, this is embarrassing..
tns test android --debug-brkExampleProject/platforms/android/src/main/assets/app/tns_modules/nativescript-unit-test-runner/main-view-model.jsExampleProject/node_modules/nativescript-unit-test-runner/main-view-model.jshere's what I'm seeing now:
forceBase64: true, transports: ['websocket']``` text
NSUTR: connecting to karma at http://192.168.1.104:9876
NSUTR: socket.io error on connect: timeout
NSUTR-socket.io: 1
NSUTR: socket.io error on connect: timeout
NSUTR-socket.io: 2
NSUTR: socket.io error on connect: timeout
NSUTR-socket.io: 3
NSUTR: socket.io error on connect: timeout
```
forceBase64: true, transports: ['websocket'], jsonp: false``` text
NSUTR: connecting to karma at http://192.168.1.104:9876
NSUTR: socket.io error on connect: timeout
NSUTR-socket.io: 1
NSUTR: socket.io error on connect: timeout
NSUTR-socket.io: 2
NSUTR: socket.io error on connect: timeout
NSUTR-socket.io: 3
NSUTR: socket.io error on connect: timeout
```
forceBase64: true, jsonp: false``` text
NSUTR: successfully connected to karma
...
NSUTR: beginning test run
```
``` text
NSUTR-socket.io: transport close
NSUTR-socket.io: 1
NSUTR: socket.io error on connect: timeout
NSUTR-socket.io: 2
NSUTR: socket.io error on connect: timeout
NSUTR-socket.io: 3
```
socket.io.js at the line in JSONPPolling.prototype.doPoll that touches the DOM and triggers the uncaught exception was not reached{jsonp: false} is the one that prevents attempts at intra-session DOM updates (ie: adding jsonp <script> tags)took a while, but we got there :)
_From @warren-bank on September 22, 2016 9:1_
_updated_:
short tldr; version
nativescript-unit-test-runner/main-view-model.js``` javascript
var socket = this.socket = io.connect(this.baseUrl, {
forceBase64: true
});
```
``` javascript
var socket = this.socket = io.connect(this.baseUrl, {
forceBase64: true,
jsonp: false
});
```
_From @warren-bank on September 22, 2016 22:31_
a few closing comments regarding reconnect attempts..
karma.conf.js, I had changed the valuesingleRun: falsesingleRun: trueand thought that maybe that was the reason that the server closed its connection and became unavailable, but I changed the value back to test that assertion and the behavior was unchanged
javascript
var socket = this.socket = io.connect(this.baseUrl, {
forceBase64: true,
jsonp: false,
reconnection: false
});
javascript
var socket = this.socket = io.connect(this.baseUrl, {
forceBase64: true,
jsonp: false,
reconnectionAttempts: 5
});
the default behavior is to make infinite attempts, at intervals determined by a backoff strategy. this results in log messages pertaining to the reconnect attempts being scattered throughout the console output.
Hey @warren-bank ,
Do you still have an issue with that or you've found a workaround to the problem?
Hi,
Wish I could offer additional insight beyond the original thread of code/observations, but I haven't used NativeScript in quite a while.. so I'm not sure if this has been addressed/solved in the time since then.
As for a workaround, please refer to the 2 comments that precede yours. That's what I ended up doing at the time, and it worked just fine. Specifically:
nativescript-unit-test-runner/main-view-model.jsvar socket = this.socket = io.connect(this.baseUrl, {
forceBase64: true,
jsonp: false,
reconnection: false
});
I'm a big fan of what you guys are building. When I swing back around to doing mobile UI, I'm sure I'll start using it again.
Sorry I couldn't be more helpful.
Hi again,
I just took a quick peek at the repo.
Here is the current version of the (above mentioned) file (before being transpiled to js).
Looks like that line of code hasn't been changed.
Hi @warren-bank,
Thanks for the kind words and the detailed analysis on the problem that you provided. We are currently in a process of figuring out what is the best way to further develop our testing story. Once we are done, we will be able to follow up with more information.
I'm experiencing the same thing...
@etabakov do you have any insight in the new testing story? Is the current one broken?
@dtopuzov I have a similar issue, though it isn't related to websockets in my case. I'm using aws-appsync and when I try to require it I get:
JavaScript error:
file:///app/tns_modules/setimmediate/setImmediate.js:175:64: JS ERROR TypeError: doc.createElement is not a function. (In 'doc.createElement("script")', 'doc.createElement' is undefined)
Error-causing code:
const AWSAppSyncClient = require('aws-appsync');