I'll describe the problem best as I can - if I've left out details, please tell me - I'm still learning about Protractor.
I'm writing my first protractor test for a website, and its contents are really simple.
teacher.js
describe("teacher list", function () {
beforeEach(function () {
browser.get('http://127.0.0.1:9000/teachers');
});
it("has teacher", function () {
initiateDebug();
var teachers = element.all(by.repeater("teacher in items track by $index"));
initiateDebug();
expect(teachers.count()).toBe(20);
initiateDebug();
})
});
...where initiateDebug() is a function defined in the onPrepare function in protractor_conf.js as follows:
initiateDebug()
global.initiateDebug = function() {
browser.pause(debugPortNumber);
debugPortNumber++;
};
The reason I included this was because calling browser.pause() results in the error:
Port 5858 is already in use. Please specify another port to debug.
[launcher] Process exited with error code 1
and I copied a temp fix proposed by a member in this issue's thread: https://github.com/angular/protractor/issues/2206.
Back to the problem
Question 1
If I run this code, the page just hangs there, and nothing loads. Googling came up with this (Getting error: Error while waiting for Protractor to sync with the page: {}), and I directly used browser.driver.get() and that seems like a workable solution.
However, my first question is - is this a case of it not being able to find angular? Because I distinctly remember that when I ran Protractor a week before, if it couldn't find Angular, it throws this error:
UnknownError: javascript error: angular is not defined
The error from my console, however, is this:
1) teacher list has teacher
Message:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Stack:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
at [object Object]._onTimeout (/Users/Baggio/project/project_bugs/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1812:23)
Question: Is the fact that this error is thrown because the page is forever stuck loading, and the async call never runs? Or could it be that angular doesn't load? Or is it something else?
I'm quite sure protractor loads because I outputted it in the console, it it enumerates all of the object properties.
And as an extension of question 1, here's the next question I don't understand.
Question 2
If I try running this test with browser.driver.get(), I get the exact same error message:
1) teacher list has teacher
Message:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Stack:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
at [object Object]._onTimeout (/Users/Baggio/project/project_bugs/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1812:23)
So it shouldn't have anything to do with the page loading or not.
What I tried
I tried, after calling initiateDebug() in interactive debug mode (entering the exact same line proceeding the first breakpoint, and I got this:
wd-debug> repl
> element.all(by.repeater("teacher in items track by $index"))
A Jasmine spec timed out. Resetting the WebDriver Control Flow.
A Jasmine spec timed out. Resetting the WebDriver Control Flow.
F
If I read this correct (https://github.com/angular/protractor/blob/master/docs/debugging.md), entering a protractor command should yield something, but here, it just resumed the control flow outside debug mode, failing the Jasmine spec.
I'll present the relevant code here that:
The html the element.all line is supposed to grab from
<section ng-if="staFlag" class="teacher-item yes-cursor cursor-over" ng-repeat="teacher in items track by $index">
Question 2: Why does Protractor fail here?
Question 3
What I've tried as well - thinking that this is a case where Protractor might not be able to find Angular, defining the rootElement property in protractor_conf.js, (adding ng-app='kp' in the root html file, and rootElement: 'html' in the config file) but it returns yet the exact same error message:
1) teacher list has teacher
Message:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Stack:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
at [object Object]._onTimeout (/Users/Baggio/project/project_bugs/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1812:23)
Message:
Thought 3: Can this effectively prove that this isn't a problem where Protractor can't find Angualr?
Additional information
I have to run this test on the same server where the website is running locally, because for some reason if this starts on a different server, the website doesn't work at all. By "doesn't work", I mean: the page loads correctly, but all bits that require data to be fetched from the backend via Restangular don't show.
Short version question
What exactly is preventing this Protractor test from running correctly? I think I'm missing something very obvious - but I've been looking at this for hours and I haven't come up with any ideas.
I'd really appreciate pointers to the right direction, or a solution if possible - thank you very much.
Related
I am following the ember tutorials, and specifically I'm on services.
I am 99.9% certain that I have the exact code in place -- I am copying by hand, because I believe that helps me absorb it more completely, but if anything fails I start using a diff checker to see if I made a typo. To my knowledge, no typos.
The App I have written performs identically to the screen shots in the tutorials, and the only error I get is a lint error for having a test that doesn't have an assert in it (yet).
Prior to this unit, all other tests have passed as well. But now I am getting failed tests that previously passed. They appear to all stem from the stubbed call to the map service failing. The first test that fails is integration/component/rental-listing-test.js:
hooks.beforeEach(function() {
this.rental = {
image: 'fake.png',
title: 'test-title',
owner: 'test-owner',
type: 'test-type',
city: 'test-city',
bedrooms: 3
};
});
test('should display rental details', async function(assert) {
await render(hbs`{{rental-listing rental=rental}}`);
assert.equal(this.element.querySelector('.listing h3').textContent.trim(), 'test-title', 'Title: test-title');
assert.equal(this.element.querySelector('.listing .owner').textContent.trim(), 'Owner: test-owner', 'Owner: test-owner');
});
If I remove the new line from rental-listing.hbs ( {{location-map location=rental.city}} ), thus preventing the map from being used, these tests once again pass (though the new tests for the component using the service have issues).
So either I am doing something wrong that I can't find, or else the fine folk at emberjs.com have not provided complete information in this tutorial. Do I need to somehow stub the map service? that appears in the .hbs file for the above test to pass? If so, why do you think they failed to mention this?
ETA assertion:
Ajax authorization failed # 273 ms
Source: Error: Ajax authorization failed
at new EmberError (http://localhost:7357/assets/vendor.js:13635:31)
at new AjaxError (http://localhost:7357/assets/vendor.js:116954:13)
at new UnauthorizedError (http://localhost:7357/assets/vendor.js:116968:13)
at Class._createCorrectError (http://localhost:7357/assets/vendor.js:117533:25)
at Class.handleResponse (http://localhost:7357/assets/vendor.js:117528:25)
at Object.jqXHR.done.fail (http://localhost:7357/assets/vendor.js:117380:41)
at fire (http://localhost:7357/assets/vendor.js:3609:31)
at Object.fireWith [as rejectWith] (http://localhost:7357/assets/vendor.js:3739:7)
at done (http://localhost:7357/assets/vendor.js:9648:14)
at XMLHttpRequest.<anonymous> (http://localhost:7357/assets/vendor.js:9889:9)
You shouldn't need the api key to run the tests. Have you tried the super rentals repo to see if it has the same issue? https://github.com/ember-learn/super-rentals
If it does have the same problem we'll probably need to PR a fix to the tutorial.
Update
I see that the integration test in question is missing a stub maps service definition. It is there in the rentals repo, but not mentioned in the guides tutorial. See https://github.com/ember-learn/super-rentals/blob/master/tests/integration/components/rental-listing-test.js for the code. I've added this info to an issue for updating the guides: https://github.com/ember-learn/guides-source/issues/347
So I finally had time to look at it. The problem is that this is set up for the external map service to use an environment variable for an API key. This is why it runs the app fine (I use KEY=value ember s to start the app) but the tests were not. Simply using KEY=value ember t -s causes these tests to pass. And I'm left with only linting issues.
For the record, this is the sort of thing that should be in the tutorial itself, and I'm not sure why I didn't think of it before.
When I am importing more than 300 record in firebase using google cloud function than am getting error :
Error: function crashed out of request scope Function killed.
Function execution took 31903 ms, finished with status: 'connection error'
Without a glimpse into your code, I only can guess. "Function crashed outside of request scope" indicates that the cloud function had finished before the asynchronous function(s) did. See for documentation for handling async functions and promises:
https://firebase.google.com/docs/functions/terminate-functions
Take a closer look at your returns. Make sure you don't forget to return the promise to functions. For an example see also here: https://github.com/firebase/firebase-functions/issues/18#issuecomment-288375709
I had the same problem and it ended up being a problem with the mysql connection I was using in the project.
In this case I used https://www.npmjs.com/package/mysql2 and the system was losing connections to the database.
It was not clear where it was happening and I got the following errors and no indication where the problem was occurring.
- Error: function crashed out of request scope Function killed.
- Function execution took 31903 ms, finished with status: 'connection error'
Placing try..catch around the database calls revealed the correct error and location where it was happening.
Yout might have gone passed a limit, please look at https://firebase.google.com/docs/database/usage/limits.
If this is the case, you could use multiple databases.
In a NodeJS 6.10.2/SailsJS 0.12.13 based JavaScript application I experience since several months a strange error behavior.
In a Sails controller, I try to retrieve a property of a literal object:
console.log(someObject.someProperty);
console.log("I am still here!");
However, in my case someObject is undefined. So, I'd expect to get an error like 'Cannot read property someProperty of undefined.' - and then either Node.js to stop completely or the code to go on (with the next console.log).
Instead, the code simply stops executing at that point and I get a strange warning: "(node:4822) Warning: Possible EventEmitter memory leak detected. 11 close listeners added. Use emitter.setMaxListeners() to increase limit." It is however, unpredictable how often this error occurs. Somethings only once, somethings about 20 times right after each other.
What I found out so for is that it is somehow connected to the question whether there was already a response or not. Consider the following:
mySailsControllerFunction: function(req, res) {
console.log(someObject.someProperty);
console.log("I am still here!");
res.json({"foo":"dahoo"});
}
This will result in Sending 500 ("Server Error") response: ReferenceError: someObject is not defined - exactly what I expect.
However, now I first send some response and then trying to access my non existing property, turning the code into:
mySailsControllerFunction: function(req, res) {
res.json({"foo":"dahoo"});
setTimeout(function () {
console.log("Yeah!");
console.log(someObject.someProperty);
console.log("I am still here!");
},1000);
}
then I often get simply nothing: 'Yeah!' displayed, but nothing comes afterwards. The event listener error is sometimes there, sometimes not. Very strange.
Additionally, and strange enough, the problem seems to be somehow connected to the time passed since the start of Sails. I put the code you see above inside a Sails controller function which is called immediately after the clients re-connect. I then played around with the timeout values, restarting the Sails server several times. Outcome: If I set the timeout to 1s, in 4 of 5 tests, I will get the correct error behavior. For 10 seconds it is about 50%, for 30s the error will always be ignored without any console output.
However, if I put my test code outside of the Sails controller, I always get the correct error behavior by Node. So, I'm quite sure this is a wrong behavior of Sails, not Node.
Disclaimer: I don't know Sails. So it may or may not be related, but my answer may offer a clue.
From the Sails documentation:
http://sailsjs.com/documentation/reference/response-res/res-json
This method is terminal, meaning it is generally the last line of code
your app should run for a given request (hence the advisory usage of
return throughout these docs).
Thus, when you use res.json({"foo":"dahoo"});, Sails probably sends the response back to the client, closing the call sequence, which, if it uses Promises or some other async mechanism, may kind of "swallow" further code, as also suggested in an above comment. This is probably internal coding in Sails, so it's not immediately obvious from the outside WHY your second code block specifically doesn't work.
So you should stick to the first pattern: access your property first, and put res.json() at the end of the controller function.
For reference: I finally solved that issue.
There were, somehow hidden in the code, process exit handlers defined:
process.on('exit', myErrorFunction.bind());
process.on('SIGINT', myErrorFunction.bind());
process.on('uncaughtException', myErrorFunction.bind());
The problem was: The function in which these lines were in was bound to a cronjob. So, each time the cronjob executed, new handlers were registered. So, my assumption above (before vs. after response) was wrong: In fact everything worked till the cronjob was executed for the first time. From then on, it didn't. And eventually, the warning was fired (correctly!).
I would have never found out without this answer: Make node show stack trace after EventEmitter warning
You have to add one line of code to get the stack trace:
process.on('warning', e => console.warn(e.stack));
Additionally, speaking of stack traces: In the Sails serverError response (api/api/responses/serverError.js), it is convenient to access it like this:
module.exports = function serverError (data, options) {
console.log(data.stack);
/* ... */
};
I'm trying to unit test the resolution/rejection of external promises.
The problem is that those promises are never finished when ngMock module is injected - which is mandatory, as I'm triggering HTTP requests and timeouts.
Take for example angular-pouchdb, which is a dependency of my project. As of v2.0.0, because PouchDB promises are used, the tests no longer finish when ngMock is injected.
Example code, adapted from angular-pouchdb tests:
var scope;
beforeEach(function() {
var $injector = angular.injector(['ng', 'ngMock', 'pouchdb']);
var pouchDB = $injector.get('pouchDB');
scope = $injector.get('$rootScope');
db = pouchDB('db');
});
it('should wrap destroy', function(done) {
db.destroy()
.then(shouldBeOK)
.catch(shouldNotBeCalled)
.finally(done);
// No matter what's used ($apply, $applySync, $timeout.flush, etc) -- the tests will never finish.
scope.$apply();
});
The log for the above test is the following:
C:\Users\Gustavo\Projetos\main\angular-pouchdb (master)
λ karma start
INFO [karma]: Karma v0.12.37 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Windows 8 0.0.0)]: Connected on socket s1A7jIzmtcOxkGCtzYke with id 42899233
PhantomJS 1.9.8 (Windows 8 0.0.0) Angular-aware PouchDB public API should wrap destroy FAILED
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
So, my question boils down to: is there something I'm missing from unit testing Angular? Or is it an internal bug in ngMock?
This issue has been created in the angular-pouchdb repository as well.
Edit 8/25: So we have actually solved this issue but I am still looking into what caused it. I will have a more updated write up in a few days.
Alright after hitting at this problem in my spare time for a number of days I have narrowed this down to some sort of exception failure in a 3rd party promise from pouchDB where it hits a 10 second timeout and doesn't throw a clean error back. I am able to get this by updating my
jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
If I got back through and tweak a custom build and put some logging in to pouchDB I can confirm that the promise is not getting returned correctly in there, I have been able to replicate this in 3.6 and 4.0 pouchDB. From my wrapped console logs around the call nothing ever comes out of the wrapped call. Around test 3 I get uncaught 409 errors so there is clearly something not being handled correctly in pouchDB.
Here is an example without ngMock turned on so you can see how far it gets without it.
I do not think it's ngMock issue, but I think it's because PhantomJS is not ready to support PouchDB yet.
https://github.com/ariya/phantomjs/issues/10992
https://github.com/pouchdb/pouchdb/blob/c55db55d7edbf0821538e027399536c260af5876/docs/adapters.md
I've been working on a project, a socket server, using NodeJS, with some great help from people on this site, my project is nearing completion, but I have an error generated on my code every once in a while, and I can't seem to pin point the error down, since the error log does not give a name of a variable, function or anything related to the problem, it just throws off this message:
Exception: TypeError: Cannot read property '0' of undefined
My problem also arises from the fact that there is nothing much moving in my code unless someone is connected to it, I do have an interval that runs every 4 minutes and send an update query to my DB so the connection to the DB will stay alive (we don't want to change the mySQL server wait_timeout since we use the same DB for other projects and products that needs it that way), and a kind of a global timer also set with setInterval that execute actions being sent to it from dynamicaly created game rooms, but again, the error pops up even if simply restart the service, and leave it untouched, it will come up every 10-20 minutes or so...
So far I've been using this simple code to catch errors:
process.on('uncaughtException', function(err){
_log('Exception: ' + err+"<br>");
});
but this does not give the information I need to know how to debug and find the problem.
My question is is there another way to handle these errors in a way that will return a little more information about the nature of the problem?
Thanks!
The err argument holds more properties like err.message and err.stack.