Commit 4176377a authored by Sam Saccone's avatar Sam Saccone

tests: Fix flakey list tests.

This test was causing us issues on CI for several reasons. The first
being that we were touching the DOM outside of webdrivers promise loop
(via Q). The second cause of issues was that we were holding onto DOM
nodes for a long time after we first queried the DOM, allowing the
pointers to potentially go stale.
parent f290e349
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
"mocha": "*", "mocha": "*",
"mocha-known-issues-reporter": "git+https://github.com/ColinEberhardt/mocha-known-issues-reporter.git#v0.0.0", "mocha-known-issues-reporter": "git+https://github.com/ColinEberhardt/mocha-known-issues-reporter.git#v0.0.0",
"optimist": "^0.6.1", "optimist": "^0.6.1",
"q": "^1.0.1",
"selenium-webdriver": "^2.45.1" "selenium-webdriver": "^2.45.1"
}, },
"scripts": { "scripts": {
......
...@@ -99,11 +99,11 @@ module.exports = function Page(browser) { ...@@ -99,11 +99,11 @@ module.exports = function Page(browser) {
this.tryGetToggleForItemAtIndex = function (index) { this.tryGetToggleForItemAtIndex = function (index) {
var xpath = this.xPathForItemAtIndex(index) + '//input[contains(@class,"toggle")]'; var xpath = this.xPathForItemAtIndex(index) + '//input[contains(@class,"toggle")]';
return this.tryFindByXpath(xpath); return this.findByXpath(xpath);
}; };
this.tryGetItemLabelAtIndex = function (index) { this.tryGetItemLabelAtIndex = function (index) {
return this.tryFindByXpath(this.xPathForItemAtIndex(index) + '//label'); return this.findByXpath(this.xPathForItemAtIndex(index) + '//label');
}; };
// ----------------- DOM element access methods // ----------------- DOM element access methods
...@@ -146,6 +146,55 @@ module.exports = function Page(browser) { ...@@ -146,6 +146,55 @@ module.exports = function Page(browser) {
return this.tryFindByXpath(xpath); return this.tryFindByXpath(xpath);
}; };
this.getVisibleLabelText = function () {
var self = this;
return this.getVisibleItemLabels()
.then(function (indicies) {
return webdriver.promise.map(indicies, function (elmIndex) {
var ret;
return browser.wait(function () {
return self.tryGetItemLabelAtIndex(elmIndex).getText()
.then(function (v) {
ret = v;
return true;
})
.thenCatch(function () { return false; });
}, 5000)
.then(function () {
return ret;
});
});
});
};
this.getVisibleItemLabels = function () {
var self = this;
var ret;
return this.getItemLabels()
.then(function (elms) {
return elms.map(function (elm, i) {
return i;
});
})
.then(function (elms) {
return webdriver.promise.filter(elms, function (elmIndex) {
return browser.wait(function () {
return self.tryGetItemLabelAtIndex(elmIndex).isDisplayed()
.then(function (v) {
ret = v;
return true;
})
.thenCatch(function () {
return false;
});
}, 5000)
.then(function () {
return ret;
});
});
});
};
// ----------------- page actions // ----------------- page actions
this.ensureAppIsVisible = function () { this.ensureAppIsVisible = function () {
return browser.findElements(webdriver.By.css('#todoapp')) return browser.findElements(webdriver.By.css('#todoapp'))
...@@ -190,10 +239,7 @@ module.exports = function Page(browser) { ...@@ -190,10 +239,7 @@ module.exports = function Page(browser) {
}; };
this.toggleItemAtIndex = function (index) { this.toggleItemAtIndex = function (index) {
return this.tryGetToggleForItemAtIndex(index).then(function (elements) { return this.tryGetToggleForItemAtIndex(index).click();
var toggleElement = elements[0];
toggleElement.click();
});
}; };
this.editItemAtIndex = function (index, itemText) { this.editItemAtIndex = function (index, itemText) {
...@@ -226,15 +272,29 @@ module.exports = function Page(browser) { ...@@ -226,15 +272,29 @@ module.exports = function Page(browser) {
}); });
}; };
this.filterBy = function (selectorFn) {
var self = this;
return browser.wait(function () {
return self.findByXpath(selectorFn()).click()
.then(function () {
return self.findByXpath(selectorFn()).getAttribute('class');
})
.then(function (klass) {
return klass.indexOf('selected') !== -1;
});
}, 5000);
};
this.filterByActiveItems = function () { this.filterByActiveItems = function () {
return this.findByXpath(this.getFilterActiveXpath()).click(); return this.filterBy(this.getFilterActiveXpath.bind(this));
}; };
this.filterByCompletedItems = function () { this.filterByCompletedItems = function () {
return this.findByXpath(this.getFilterCompletedXpath()).click(); return this.filterBy(this.getFilterCompletedXpath.bind(this));
}; };
this.filterByAllItems = function () { this.filterByAllItems = function () {
return this.findByXpath(this.getFilterAllXpath()).click(); return this.filterBy(this.getFilterAllXpath.bind(this));
}; };
}; };
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var Q = require('q');
function TestOperations(page) { function TestOperations(page) {
// unfortunately webdriver does not have a decent API for determining if an // unfortunately webdriver does not have a decent API for determining if an
...@@ -109,40 +108,9 @@ function TestOperations(page) { ...@@ -109,40 +108,9 @@ function TestOperations(page) {
// tests that the list contains the following items, independant of order // tests that the list contains the following items, independant of order
this.assertItems = function (textArray) { this.assertItems = function (textArray) {
page.getItemLabels().then(function (labels) { return page.getVisibleLabelText()
.then(function (visibleText) {
// obtain all the visible items assert.deepEqual(textArray.sort(), visibleText.sort());
var visibleLabels = [];
var tests = labels.map(function (label) {
return label.isDisplayed().then(function (isDisplayed) {
if (isDisplayed) {
visibleLabels.push(label);
}
});
});
// check that they match the supplied text
return Q.all(tests).then(function () {
assert.equal(textArray.length, visibleLabels.length,
textArray.length + ' items expected in the todo list, ' + visibleLabels.length + ' items observed');
// create an array of promises which check the presence of the
// label text within the 'textArray'
tests = [];
for (var i = 0; i < visibleLabels.length; i++) {
// suppressing JSHint - the loop variable is not being used in the function.
/* jshint -W083 */
tests.push(visibleLabels[i].getText().then(function (text) {
var index = textArray.indexOf(text);
assert(index !== -1, 'A todo item with text \'' + text + '\' was not expected');
// remove this item when found
textArray.splice(index, 1);
}));
}
// execute all the tests
return Q.all(tests);
});
}); });
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment