Getting "Error while waiting for Protractor to sync with the page: "both angularJS testability and angular testability are undefined ...."" - protractor

I'm fairly new to Protractor and JS. I wrote a simple code to add few numbers using an online calculator. Add I am doing by calling a add() function where I am returning a Promise. This Promise I am handling in my it block where it is causing issue and giving above error.
Tried updating the versions but no help
describe("Using Protractor and working", function(){
var resultsExpected = [];
function add(a,b){
return new Promise(function(resolve, reject){
element(by.model("first")).sendKeys(String(a));
element(by.model("second")).sendKeys(String(b));
element(by.id("gobutton")).click();
var len=0;
len = resultsExpected.length;
resultsExpected[len] = {value:String(a+b)};
console.log("Length is: "+resultsExpected.length);
console.log("Item inside: "+resultsExpected[len].value);
resolve();
});
}
it("Addition from calc should give correct result", function(){
browser.get('http://juliemr.github.io/protractor-demo/');
add(2,4).then(function(ff){
expect(element(by.css("h2.ng-binding")).getText()).toEqual("6");
return add(5,3);
}).then(function(ff){
expect(element(by.css("h2.ng-binding")).getText()).toEqual("8");
return add(5,8);
}).then(function(ff){
expect(element(by.css("h2.ng-binding")).getText()).toEqual("13");
})
})
})
Failures:
1) Using Protractor and working Addition from calc should give correct result
Message:
[31m Error: Error while waiting for Protractor to sync with the page: "both angularJS testability and angular testability are undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor's bootstrapping. See http://git.io/v4gXM for details"[0m
Stack:
Error: Error while waiting for Protractor to sync with the page: "both angularJS testability and angular testability are undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor's bootstrapping. See http://git.io/v4gXM for details"
at runWaitForAngularScript.then (D:\JavaScriptWorkSpace\FirstProtractor\protractor\built\browser.js:463:23)
at ManagedPromise.invokeCallback_ (D:\JavaScriptWorkSpace\FirstProtractor\protractor\node_modules\selenium-webdriver\lib\promise.js:1376:14)
at TaskQueue.execute_ (D:\JavaScriptWorkSpace\FirstProtractor\protractor\node_modules\selenium-webdriver\lib\promise.js:3084:14)
at TaskQueue.executeNext_ (D:\JavaScriptWorkSpace\FirstProtractor\protractor\node_modules\selenium-webdriver\lib\promise.js:3067:27)
at asyncRun (D:\JavaScriptWorkSpace\FirstProtractor\protractor\node_modules\selenium-webdriver\lib\promise.js:2927:27)
at D:\JavaScriptWorkSpace\FirstProtractor\protractor\node_modules\selenium-webdriver\lib\promise.js:668:7
at process._tickCallback (internal/process/next_tick.js:68:7)Error
at ElementArrayFinder.applyAction_ (D:\JavaScriptWorkSpace\FirstProtractor\protractor\built\element.js:459:27)
at ElementArrayFinder.(anonymous function).args [as getText] (D:\JavaScriptWorkSpace\FirstProtractor\protractor\built\element.js:91:29)
at ElementFinder.(anonymous function).args [as getText] (D:\JavaScriptWorkSpace\FirstProtractor\protractor\built\element.js:831:22)
at D:\JavaScriptWorkSpace\FirstProtractor\WorkinWithDropDown.js:55:45
at process._tickCallback (internal/process/next_tick.js:68:7)

Try the below one
it("Addition from calc should give correct result", async() =>{
await brwoser.waitForAngularEnabled(true);
await browser.get('http://juliemr.github.io/protractor-demo/');
})
});
Hope it helps you

This may not help, because I don't see browser.wait() in your code, but FWIW we spent days debugging this exact error message, and eventually fixed it by updating all browser.wait() calls with an explicit timeouts. E.g.
browser.wait(condition, 5000);
Instead of
browser.wait(condition);
We started by verifying that browser.waitForAngularEnabled() was set to true, which it was (we're testing a pure Angular app with Cucumber/Protrator/Selenium/Chai, no non-angular pages, so no reason to turn off waitForAngular). So no luck there.
Then, after much experimentation, we concluded that browser.wait() doesn't always throw an exception and fail the test when the expected condition never becomes true, UNLESS you provide the timeout argument. Without the timeout, the best case scenario was that the test would hit the global cucumber timeout and we would get an unhelpful generic failure message. The worst case scenario was that execution would occasionally continue to the next feature, while the first feature was timing out in the background. When the first feature finally timed out, it caused the second feature to fail with the cryptic message both angularJS testability and angular testability are undefined. There's no mention of this behavior in the documentation for wait().
We tried increasing the global cucumber timeout and setting a global protractor timeout, but it had no effect. So we did a blanket update to always provide the timeout parameter, and haven't seen the error since.
I suspect that the whole misadventure might be related to our use of Chai instead of Jasmine, since the documentation mentions jasmineNodeOpts.defaultTimeoutInterval, so maybe there's some assumption in the code that we're breaking.

Related

Protractor test does not finish, seems to loop until the jasmine timeout error hits

I feel pretty dumb to not be able to get the most basic protractor test to work. Given protractor 5.4.1 i have a spec.js
describe('my example tests', () => {
const EC = protractor.ExpectedConditions;
it('tests google', async () => {
await browser.waitForAngularEnabled(false);
await browser.get("https://google.com");
await browser.wait(EC.visibilityOf($('input')));
await element(by.css("input")).click();});});
and a conf of
exports.config = {
directConnect: true,
specs: ['tests/**/*.js'],
capabilities: {
browserName: 'chrome',
},
SELENIUM_PROMISE_MANAGER: false,
jasmineNodeOpts: {
defaultTimeoutInterval: 40000
}
};
when running protractor conf.js the browser opens, goes to the page and then nothing happens until the 40s jasmine timeout hits. What I get are ~25 warnings per second
W/element - more than one element found for locator By(css selector, input) - the first result will be used
as if some command is running in an endless loop until I get an error Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. which does not tell me much and is hard to google.
Has anyone experienced this issue?
On the Google page, the locator $('input') matches many elements, which is why you got the warning. The first one was used, but unfortunately, the first one was hidden. so await browser.wait(EC.visibilityOf($('input'))); failed, which gave the timeout error.
Using a locator that locates a unique and not hidden input element on the page, like element(by.name('q')) ought to work better.
I like the Hetzner cloud protractor test helper which provides wrappers like waitToBeDisplayed whose error reporting is less generic, if I recall correctly (it has been a while since I used it).

Checking if an element is present in protractor

I have a protractor test that expects a certain panel to be NOT PRESENT after login. My code is below, but every time it is executed, protractor hangs and then fails later on.
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
it('The team overlay page should not be present when another user logs in.', function() {
loginPage.login(user.username, user.password);
expect(element(by.css('div.panel#myPanel')).isPresent()).toBe(false);
});
I also tried using .count() but it also does the same thing. Same error as above.
expect(element.all(by.css('div.panel#myPanel')).count()).toBe(0);
You could try waiting for the element by allowing the browser to fully load with some of the following:
browser.driver.sleep(time in milliseconds)
browser.waitForAngular()
You could increase the timeout interval:
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000
Otherwise:
Make sure your locator via css is working correctly (i.e, test it when the panel should be present), and make sure the webpage you are trying to access supports Angular. My bet is there is something incorrect with the format of your locator, as I don't see what else could be an issue.

Empty response on long running query SailsJS

I'm currently running SailsJS on a Raspberry Pi and all is working well however when I execute a sails.models.nameofmodel.count() when I attempt to respond with the result I end up getting a empty response.
getListCount: function(req,res)
{
var mainsource = req.param("source");
if(mainsource)
{
sails.models.gatherer.find({source: mainsource}).exec(
function(error, found)
{
if(error)
{
return res.serverError("Error in call");
}
else
{
sails.log("Number found "+found.length);
return res.ok({count: found.length});
}
}
);
}
else
{
return res.ok("Error in parameter");
}
},
I am able to see in the logs the number that was found (73689). However when responding I still get an empty response. I am using the default stock ok.js file, however I did stick in additional logging to try to debug and make sure it is going through the correct paths. I was able to confirm that the ok.js was going through this path
if (req.wantsJSON) {
return res.jsonx(data);
}
I also tried adding .populate() to the call before the .exec(), res.status(200) before I sent out a res.send() instead of res.ok(). I've also updated Sails to 11.5 and still getting the same empty response. I've also used a sails.models.gatherer.count() call with the same result.
You can try to add some logging to the beginning of your method to capture the value of mainsource. I do not believe you need to use an explicit return for any response object calls.
If all looks normal there, try to eliminate the model's find method and just evaluate the request parameter and return a simple response:
getListCount: function(req, res) {
var mainsource = req.param("source");
sails.log("Value of mainsource:" + mainsource);
if (mainsource) {
res.send("Hello!");
} else {
res.badRequest("Sorry, missing source.");
}
}
If that does not work, then your model data may not actually be matching on the criteria that you are providing and the problem may lie there; in which case, your response would be null. You mentioned that you do see the resulting count of the query within the log statement. If the res.badRequest is also null, then you may have a problem with the version of express that is installed within sailsjs. You mention that you have 11.5 of sailsjs. I will assume you mean 0.11.5.
This is what is found in package.json of 0.11.5
"express": "^3.21.0",
Check for any possible bugs within the GitHub issues for sailsjs regarding express and response object handling and the above version of express.
It may be worthwhile to perform a clean install using the latest sailsjs version (0.12.0) and see if that fixes your issue.
Another issue may be in how you are handling the response. In this case .exec should execute the query immediately (i.e. a synchronous call) and return the response when complete. So there should be no asynchronous processing there.
If you can show the code that is consuming the response, that would be helpful. I am assuming that there is a view that is showing the response via AJAX or some kind of form POST that is being performed. If that is where you are seeing the null response, then perhaps the problem lies in the view layer rather than the controller/model.
If you are experiencing a true timeout error via HTTP even though your query returns with a result just in time, then you may need to consider using async processing with sailjs. Take a look at this post on using a Promise instead.

Protractor: test loading state

I'm setting up protractor for our web app, and all works fine, except one thing: When someone clicks the "login" button, while the HTTP request is running, the button should have class "loading". However, when I try to test this, protractor waits for the HTTP request to finish before it runs the expectation, which then fails, because the loading class is removed again.
How can I assert that the loading class is added?
describe('Authorization', function() {
it('the site loads', () => {
browser.get('/');
expect(browser.getCurrentUrl()).toBe('http://localhost:8000/#/login');
element(by.model('vm.credentials.username')).sendKeys('username');
element(by.model('vm.credentials.password')).sendKeys('password');
element(by.css('#sign-in')).click();
expect(element(by.css('#sign-in')).getAttribute('class')).toMatch(/\bloading\b/);
});
});
I think I found the solution.
The element() function waits for angular to settle in, but browser.driver.findElement() doesn't. So by changing the assertion line to
expect(browser.driver.findElement(by.css('#sign-in')).getAttribute('class')).toMatch(/\bloading\b/);
the tests now pass
As per your problem, protractor is executing your expect statement along with click() function. Protractor is async and fast so it executes everything that it can and then waits for promise/callback to be returned. Try waiting for the click to happen first and then try to assert the class. Here's how you can do it -
element(by.css('#sign-in')).click().then(function(){
expect(element(by.css('#sign-in')).getAttribute('class')).toMatch(/\bloading\b/);
});
Also if the http request is blocking your execution, then try to wait for the element to be displayed. If the element is displayed then it's as good as your element is verified.
browser.wait(protractor.ExpectedConditions.visibilityOf($('.loading')), 10000)
.then(function(){
expect(true).toBe(true);
});
Hope this helps.

Test after spinner

I'm experiencing same issue as described here I need to wait site loading and I can know it finihed when spinner goes away and then I need make my tests. But such an easy tests:
beforeAll(function(){
Core.login(env.currentUser).then(function(){
var foo = browser.wait(function(){
return !browser.isElementPresent(by.css('.modal .env-waiting-content'));
}, 50000);
console.log("page loaded");
mainPage.navBar.buttons.logIncident.click();
});
});
it('should work', function(){
expect(1).toBe(1);
});
failed with error:
Message:
Failed: ENOTFOUND getaddrinfo ENOTFOUND
Stack:
Error: Failed: ENOTFOUND getaddrinfo ENOTFOUND
at /home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/jasminewd2/index.js:104:16
at /home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/base.js:1582:15
at [object Object].webdriver.promise.ControlFlow.runInNewFrame_ (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1654:20)
at notify (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:465:12)
at notifyAll (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:442:7)
at resolve (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:420:7)
at reject (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:545:5)
at /home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/base.js:1582:15
at [object Object].webdriver.promise.ControlFlow.runInNewFrame_ (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1654:20)
at notify (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:465:12)
at notifyAll (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:442:7)
at resolve (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:420:7)
at [object Object].reject (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:545:5)
at /home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1529:10
at newFrame.onAbort (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1679:7)
at [object Object].webdriver.promise.Frame_.notify_ (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1914:5)
at [object Object]._onTimeout (/home/set/.nvm/v0.10.28/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1887:13)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
How can I avoid this error and why it occur?
why console.log("page loaded"); output message much earlier than spinner disappear and what is the way to execute some code after when, some kind of then ?
what is the difference between browser.wait and browser.driver.wait?
Your error looks like a basic networking issue. Are you able to get the example tests that Protractor ships with working?
The second issue (why console.log happens so early) is because Protractor commands do not do things, they queue things to be done later (promises that the underlying webdriver "control flow" executes). Read this https://github.com/angular/protractor/blob/master/docs/control-flow.md and https://code.google.com/p/selenium/wiki/WebDriverJs#Understanding_the_API. So, the console.log ends up running as the steps are queued, not executed.
Generally, in protractor the "top-level" APIs like browser and protractor and by are all "Angular-aware". The browser.driver API is the underlying Selenium webdriver API (which is not aware of Angular). In the particular case of wait, I don't think there is much difference (but I'm not 100% confident of that).