Here is the failing test:
describe("Checking errors", function () {
var scope = {};
beforeEach(function () {
browser.get("/#endpoint");
browser.waitForAngular();
scope.page = new MyPage();
});
it("should not show any errors", function () {
expect(scope.page.errors).toBeEmptyArray();
});
});
where MyPage
is a Page Object:
var MyPage = function () {
this.errors = element.all(by.css("div.error-block b.error"))
.filter(function (elm) {
return elm.isDisplayed().then(function (value) {
return value;
});
})
.map(function (elm) {
return elm.getText();
});
};
module.exports = MyPage;
where errors
supposed to be an array of visible error texts found on a page.
Here is the error we are getting:
Failures:
1) Checking errors should not show any errors
Message:
Expected [ ] to be empty array.
Stacktrace:
Error: Failed expectation
FYI, toBeEmptyArray()
matcher is ing from jasmine-matchers
third-party.
I've tried to print out the value of scope.page.errors
this way:
scope.page.errors.then(function (errors) {
console.log(errors);
});
And it is printed out as []
. Array.isArray(errors)
returns true
.
From what I see, scope.page.errors
is an empty array, but the expectation fails. What I a missing?
Here is the failing test:
describe("Checking errors", function () {
var scope = {};
beforeEach(function () {
browser.get("/#endpoint");
browser.waitForAngular();
scope.page = new MyPage();
});
it("should not show any errors", function () {
expect(scope.page.errors).toBeEmptyArray();
});
});
where MyPage
is a Page Object:
var MyPage = function () {
this.errors = element.all(by.css("div.error-block b.error"))
.filter(function (elm) {
return elm.isDisplayed().then(function (value) {
return value;
});
})
.map(function (elm) {
return elm.getText();
});
};
module.exports = MyPage;
where errors
supposed to be an array of visible error texts found on a page.
Here is the error we are getting:
Failures:
1) Checking errors should not show any errors
Message:
Expected [ ] to be empty array.
Stacktrace:
Error: Failed expectation
FYI, toBeEmptyArray()
matcher is ing from jasmine-matchers
third-party.
I've tried to print out the value of scope.page.errors
this way:
scope.page.errors.then(function (errors) {
console.log(errors);
});
And it is printed out as []
. Array.isArray(errors)
returns true
.
From what I see, scope.page.errors
is an empty array, but the expectation fails. What I a missing?
- What do you get if you log Array.isArray(errors)? – Ryan Commented Mar 18, 2015 at 23:12
-
@Ryan was not expecting this, but it prints
true
..weird. Thanks. – alecxe Commented Mar 18, 2015 at 23:15 -
Does
expect(scope.page.errors.length).toBe(0);
work? You might be running into a problem from the scopes webdriver creates (like iframes in a page) that have their own "Array" definition. See stackoverflow./a/2265999/960524 (so this might be a bug in thetoBeEmptyArray()
method -- its probably failing the "array"-ness part of the check.) – P.T. Commented Mar 18, 2015 at 23:36 -
@P.T. thank you for the point, the expectation you've posted fails with
Expected undefined to be 0
. I actually suspect this has smth to do withElementArrayFinder
..this particular ment could be related to what we are experiencing:You can treat an ElementArrayFinder as an array of WebElements for most purposes...
– alecxe Commented Mar 18, 2015 at 23:45 -
Does
expect(scope.page.errors).toBeArray();
pass? – phts Commented Apr 4, 2015 at 21:38
2 Answers
Reset to default 3 +100the answer is four lines down in the protractor src.
ElementArrayFinder extends Promise
, while jasmine-matchers checks first checks that errors is an actual array exactly how Array.isArray is done , which will return false;
This is also consistent with expect(scope.page.errors.length).toBe(0)
being undefined because promises do not have lengths.
Just run errors.then
on your promise, and test that the argument is []
You've also shown that can be done when you ran scope.page.errors.then
Inside test script your code line "scope.page = new MyPage();" is creating new empty MyPage object.Code which you have written in application script is creating page object locally and its not bounded with any angular scope.When there is requirement of testing such objects you need to replicate code for page object creation in beforeEach(); block of test script.And test it.
describe("Checking errors", function () {
var scope = {};
var MyPage ;
beforeEach(function () {
browser.get("/#endpoint");
browser.waitForAngular();
MyPage = function () {
this.errors = element.all(by.css("div.error-block b.error"))
.filter(function (elm) {
return elm.isDisplayed().then(function (value) {
return value;
});
})
.map(function (elm) {
return elm.getText();
});
};
});
it("should not show any errors", function () {
expect(MyPage.errors).toBeEmptyArray();
});
});