Commit 537c4122 authored by Colin Eberhardt's avatar Colin Eberhardt

Merge pull request #1573 from ColinEberhardt/mhoyer-async-tests

Correcting asynchronous testing
parents 4de8afb2 951eb70b
'use strict';
var webdriver = require('selenium-webdriver');
var idSelectors = false;
var idSelectors = true;
module.exports = function Page(browser) {
......@@ -16,35 +16,35 @@ module.exports = function Page(browser) {
};
this.getTodoListXpath = function () {
return !idSelectors ? '//ul[@id="todo-list"]' : '//ul[contains(@class, "todo-list")]';
return idSelectors ? '//ul[@id="todo-list"]' : '//ul[contains(@class, "todo-list")]';
};
this.getMainSectionXpath = function () {
return !idSelectors ? '//section[@id="main"]' : '//section[contains(@class, "main")]';
return idSelectors ? '//section[@id="main"]' : '//section[contains(@class, "main")]';
};
this.getFooterSectionXpath = function () {
return !idSelectors ? '//footer[@id="footer"]' : '//footer[contains(@class, "footer")]';
return idSelectors ? '//footer[@id="footer"]' : '//footer[contains(@class, "footer")]';
};
this.getCompletedButtonXpath = function () {
return !idSelectors ? '//button[@id="clear-completed"]' : '//button[contains(@class, "clear-completed")]';
return idSelectors ? '//button[@id="clear-completed"]' : '//button[contains(@class, "clear-completed")]';
};
this.getNewInputXpath = function () {
return !idSelectors ? '//input[@id="new-todo"]' : '//input[contains(@class,"new-todo")]';
return idSelectors ? '//input[@id="new-todo"]' : '//input[contains(@class,"new-todo")]';
};
this.getToggleAllXpath = function () {
return !idSelectors ? '//input[@id="toggle-all"]' : '//input[contains(@class,"toggle-all")]';
return idSelectors ? '//input[@id="toggle-all"]' : '//input[contains(@class,"toggle-all")]';
};
this.getCountXpath = function () {
return !idSelectors ? '//span[@id="todo-count"]' : '//span[contains(@class, "todo-count")]';
return idSelectors ? '//span[@id="todo-count"]' : '//span[contains(@class, "todo-count")]';
};
this.getFiltersElementXpath = function () {
return !idSelectors ? '//*[@id="filters"]' : '//*[contains(@class, "filters")]';
return idSelectors ? '//*[@id="filters"]' : '//*[contains(@class, "filters")]';
};
this.getFilterXpathByIndex = function (index) {
......@@ -115,9 +115,9 @@ module.exports = function Page(browser) {
return this.getActiveElement().getTagName();
};
this.getFocussedElementName = function () {
this.getFocussedElementIdOrClass = function () {
return this.getActiveElement()
.getAttribute(!idSelectors ? 'id' : 'class');
.getAttribute(idSelectors ? 'id' : 'class');
};
this.getEditInputForItemAtIndex = function (index) {
......@@ -175,9 +175,24 @@ module.exports = function Page(browser) {
});
};
this.waitForVisibleElement = function (getElementFn, timeout) {
var foundVisibleElement;
timeout = timeout || 500;
return browser.wait(function () {
foundVisibleElement = getElementFn();
return foundVisibleElement.isDisplayed();
}, timeout)
.then(function () {
return foundVisibleElement;
})
.thenCatch(function (err) {
return false;
});
}
this.getVisibileLabelIndicies = function () {
var self = this;
var ret;
return this.getItemLabels()
.then(function (elms) {
return elms.map(function (elm, i) {
......@@ -186,18 +201,8 @@ module.exports = function Page(browser) {
})
.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;
return self.waitForVisibleElement(function () {
return self.tryGetItemLabelAtIndex(elmIndex);
});
});
});
......@@ -205,51 +210,57 @@ module.exports = function Page(browser) {
// ----------------- page actions
this.ensureAppIsVisible = function () {
return browser.findElements(webdriver.By.css('#todoapp'))
.then(function (elms) {
if (elms.length > 0) {
return true;
} else {
return browser.findElements(webdriver.By.css('.todoapp'));
}
})
.then(function (elms) {
if (elms === true) {
var self = this;
return browser.wait(function () {
// try to find main element by ID
return browser.isElementPresent(webdriver.By.css('.new-todo'))
.then(function (foundByClass) {
if (foundByClass) {
idSelectors = false;
return true;
}
if (elms.length) {
idSelectors = true;
return true;
// try to find main element by CSS class
return browser.isElementPresent(webdriver.By.css('#new-todo'));
});
}, 5000)
.then(function (hasFoundNewTodoElement) {
if (!hasFoundNewTodoElement) {
throw new Error('Unable to find application, did you start your local server?');
}
throw new Error('Unable to find application root, did you start your local server?');
});
};
this.clickMarkAllCompletedCheckBox = function () {
return this.getMarkAllCompletedCheckBox().then(function (checkbox) {
checkbox.click();
return checkbox.click();
});
};
this.clickClearCompleteButton = function () {
return this.tryGetClearCompleteButton().click();
var self = this;
return self.waitForVisibleElement(function () {
return self.tryGetClearCompleteButton();
})
.then(function (clearCompleteButton) {
return clearCompleteButton.click();
});
};
this.enterItem = function (itemText) {
var self = this;
browser.wait(function () {
return self.getItemInputField().then(function (textField) {
return textField.sendKeys(itemText, webdriver.Key.ENTER)
.then(function () {
return textField;
});
}).then(function (textField) {
return self.getVisibleLabelText()
return browser.wait(function () {
var textField;
return self.getItemInputField().then(function (itemInputField) {
textField = itemInputField;
return textField.sendKeys(itemText, webdriver.Key.ENTER);
})
.then(function () { return self.getVisibleLabelText(); })
.then(function (labels) {
if (labels.indexOf(itemText.trim()) !== -1) {
if (labels.indexOf(itemText.trim()) >= 0) {
return true;
}
......@@ -257,7 +268,6 @@ module.exports = function Page(browser) {
return false;
});
});
});
}, 5000);
};
......
......@@ -15,13 +15,18 @@ module.exports.todoMVCTest = function (frameworkName, baseUrl, speedMode, laxMod
var browser, testOps, page;
// a number of tests use this set of ToDo items.
function createStandardItems() {
function createStandardItems(done) {
page.enterItem(TODO_ITEM_ONE);
page.enterItem(TODO_ITEM_TWO);
page.enterItem(TODO_ITEM_THREE);
return page.enterItem(TODO_ITEM_THREE)
.then(function () {
if (done instanceof Function) {
done();
};
});
}
function launchBrowser() {
function launchBrowser(done) {
var chromeOptions = new chrome.Options();
chromeOptions.addArguments('no-sandbox');
......@@ -30,9 +35,7 @@ module.exports.todoMVCTest = function (frameworkName, baseUrl, speedMode, laxMod
}
browser = new webdriver.Builder()
.withCapabilities({
browserName: browserName
})
.withCapabilities({browserName: browserName})
.setChromeOptions(chromeOptions)
.build();
......@@ -41,135 +44,153 @@ module.exports.todoMVCTest = function (frameworkName, baseUrl, speedMode, laxMod
page = laxMode ? new PageLaxMode(browser) : new Page(browser);
testOps = new TestOperations(page);
// for apps that use require, we have to wait a while for the dependencies to
// be loaded. There must be a more elegant solution than this!
browser.sleep(200);
return page.ensureAppIsVisible()
.then(function () {
if (done instanceof Function) {
done();
};
});
}
function closeBrowser() {
browser.quit();
}
function printCapturedLogs() {
var logs = new webdriver.WebDriver.Logs(browser);
if (speedMode) {
test.before(function () {
launchBrowser();
return logs.get('browser')
.then(function (entries) {
if (entries && entries.length) {
console.log(entries);
}
});
test.after(function () {
closeBrowser();
}
function closeBrowser(done) {
return browser
.quit()
.then(function () {
if (done instanceof Function) {
done();
};
});
test.beforeEach(function () {
page.getItemElements().then(function (items) {
if (items.length > 0) {
}
if (speedMode) {
test.before(launchBrowser);
test.after(closeBrowser);
test.beforeEach(function (done) {
return page.getItemElements()
.then(function (items) {
if (items.length == 0) { return; }
// find any items that are not complete
page.getNonCompletedItemElements().then(function (nonCompleteItems) {
page.getNonCompletedItemElements()
.then(function (nonCompleteItems) {
if (nonCompleteItems.length > 0) {
page.clickMarkAllCompletedCheckBox();
return page.clickMarkAllCompletedCheckBox();
}
page.clickClearCompleteButton();
});
}
});
})
return page.clickClearCompleteButton();
})
.then(function () { done(); });
});
} else {
test.beforeEach(function () {
launchBrowser();
page.ensureAppIsVisible();
});
test.afterEach(function () {
(new webdriver.WebDriver.Logs(browser))
.get('browser')
.then(function (v) {
if (v && v.length) {
console.log(v);
}
});
closeBrowser();
test.beforeEach(launchBrowser);
test.afterEach(function (done) {
printCapturedLogs()
.then(function () {
return closeBrowser(done);
})
});
}
test.describe('When page is initially opened', function () {
test.it('should focus on the todo input field', function () {
testOps.assertFocussedElementId('new-todo');
test.it('should focus on the todo input field', function (done) {
testOps.assertFocussedElement('new-todo')
.then(function () { done(); });
});
});
test.describe('No Todos', function () {
test.it('should hide #main and #footer', function () {
test.it('should hide #main and #footer', function (done) {
testOps.assertItemCount(0);
testOps.assertMainSectionIsHidden();
testOps.assertFooterIsHidden();
testOps.assertFooterIsHidden()
.then(function () { done(); });
});
});
test.describe('New Todo', function () {
test.it('should allow me to add todo items', function () {
test.it('should allow me to add todo items', function (done) {
page.enterItem(TODO_ITEM_ONE);
testOps.assertItems([TODO_ITEM_ONE]);
page.enterItem(TODO_ITEM_TWO);
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_TWO]);
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_TWO])
.then(function () { done(); });
});
test.it('should clear text input field when an item is added', function () {
test.it('should clear text input field when an item is added', function (done) {
page.enterItem(TODO_ITEM_ONE);
testOps.assertItemInputFieldText('');
testOps.assertItemInputFieldText('')
.then(function () { done(); });
});
test.it('should append new items to the bottom of the list', function () {
test.it('should append new items to the bottom of the list', function (done) {
createStandardItems();
testOps.assertItemCount(3);
testOps.assertItemText(0, TODO_ITEM_ONE);
testOps.assertItemText(1, TODO_ITEM_TWO);
testOps.assertItemText(2, TODO_ITEM_THREE);
testOps.assertItemText(2, TODO_ITEM_THREE)
.then(function () { done(); });
});
test.it('should trim text input', function () {
test.it('should trim text input', function (done) {
page.enterItem(' ' + TODO_ITEM_ONE + ' ');
testOps.assertItemText(0, TODO_ITEM_ONE);
testOps.assertItemText(0, TODO_ITEM_ONE)
.then(function () { done(); });
});
test.it('should show #main and #footer when items added', function () {
test.it('should show #main and #footer when items added', function (done) {
page.enterItem(TODO_ITEM_ONE);
testOps.assertMainSectionIsVisible();
testOps.assertFooterIsVisible();
testOps.assertFooterIsVisible()
.then(function () { done(); });
});
});
test.describe('Mark all as completed', function () {
test.beforeEach(function () {
createStandardItems();
});
test.beforeEach(createStandardItems);
test.it('should allow me to mark all items as completed', function () {
test.it('should allow me to mark all items as completed', function (done) {
page.clickMarkAllCompletedCheckBox();
testOps.assertItemAtIndexIsCompleted(0);
testOps.assertItemAtIndexIsCompleted(1);
testOps.assertItemAtIndexIsCompleted(2);
testOps.assertItemAtIndexIsCompleted(2)
.then(function () { done(); });
});
test.it('should correctly update the complete all checked state', function () {
test.it('should correctly update the complete all checked state', function (done) {
// manually check all items
page.toggleItemAtIndex(0);
page.toggleItemAtIndex(1);
page.toggleItemAtIndex(2);
// ensure checkall is in the correct state
testOps.assertCompleteAllIsChecked();
testOps.assertCompleteAllIsChecked()
.then(function () { done(); });
});
test.it('should allow me to clear the completion state of all items', function () {
test.it('should allow me to clear the completion state of all items', function (done) {
page.clickMarkAllCompletedCheckBox();
page.clickMarkAllCompletedCheckBox();
testOps.assertItemAtIndexIsNotCompleted(0);
testOps.assertItemAtIndexIsNotCompleted(1);
testOps.assertItemAtIndexIsNotCompleted(2);
testOps.assertItemAtIndexIsNotCompleted(2)
.then(function () { done(); });
});
test.it('complete all checkbox should update state when items are completed / cleared', function () {
test.it('complete all checkbox should update state when items are completed / cleared', function (done) {
page.clickMarkAllCompletedCheckBox();
testOps.assertCompleteAllIsChecked();
// all items are complete, now mark one as not-complete
......@@ -178,12 +199,13 @@ module.exports.todoMVCTest = function (frameworkName, baseUrl, speedMode, laxMod
// now mark as complete, so that once again all items are completed
page.toggleItemAtIndex(0);
testOps.assertCompleteAllIsChecked();
testOps.assertCompleteAllIsChecked()
.then(function () { done(); });
});
});
test.describe('Item', function () {
test.it('should allow me to mark items as complete', function () {
test.it('should allow me to mark items as complete', function (done) {
page.enterItem(TODO_ITEM_ONE);
page.enterItem(TODO_ITEM_TWO);
......@@ -193,10 +215,11 @@ module.exports.todoMVCTest = function (frameworkName, baseUrl, speedMode, laxMod
page.toggleItemAtIndex(1);
testOps.assertItemAtIndexIsCompleted(0);
testOps.assertItemAtIndexIsCompleted(1);
testOps.assertItemAtIndexIsCompleted(1)
.then(function () { done(); });
});
test.it('should allow me to un-mark items as complete', function () {
test.it('should allow me to un-mark items as complete', function (done) {
page.enterItem(TODO_ITEM_ONE);
page.enterItem(TODO_ITEM_TWO);
......@@ -206,102 +229,101 @@ module.exports.todoMVCTest = function (frameworkName, baseUrl, speedMode, laxMod
page.toggleItemAtIndex(0);
testOps.assertItemAtIndexIsNotCompleted(0);
testOps.assertItemAtIndexIsNotCompleted(1);
testOps.assertItemAtIndexIsNotCompleted(1)
.then(function () { done(); });
});
});
test.describe('Editing', function () {
test.beforeEach(function () {
test.describe('Editing', function (done) {
test.beforeEach(function (done) {
createStandardItems();
page.doubleClickItemAtIndex(1);
page.doubleClickItemAtIndex(1)
.then(function () { done(); });
});
test.it('should focus the input', function () {
test.it('should focus the input', function (done) {
testOps.assertInputFocused();
testOps.assertNewInputNotFocused();
testOps.assertNewInputNotFocused()
.then(function () { done(); });
});
test.it('should hide other controls when editing', function () {
test.it('should hide other controls when editing', function (done) {
testOps.assertItemToggleIsHidden(1);
testOps.assertItemLabelIsHidden(1);
testOps.assertItemLabelIsHidden(1)
.then(function () { done(); });
});
test.it('should save edits on enter', function () {
test.it('should save edits on enter', function (done) {
page.editItemAtIndex(1, 'buy some sausages' + webdriver.Key.ENTER);
testOps.assertItems([TODO_ITEM_ONE, 'buy some sausages', TODO_ITEM_THREE]);
testOps.assertItems([TODO_ITEM_ONE, 'buy some sausages', TODO_ITEM_THREE])
.then(function () { done(); });
});
test.it('should save edits on blur', function () {
test.it('should save edits on blur', function (done) {
page.editItemAtIndex(1, 'buy some sausages');
// click a toggle button so that the blur() event is fired
page.toggleItemAtIndex(0);
testOps.assertItems([TODO_ITEM_ONE, 'buy some sausages', TODO_ITEM_THREE]);
testOps.assertItems([TODO_ITEM_ONE, 'buy some sausages', TODO_ITEM_THREE])
.then(function () { done(); });
});
test.it('should trim entered text', function () {
test.it('should trim entered text', function (done) {
page.editItemAtIndex(1, ' buy some sausages ' + webdriver.Key.ENTER);
testOps.assertItems([TODO_ITEM_ONE, 'buy some sausages', TODO_ITEM_THREE]);
testOps.assertItems([TODO_ITEM_ONE, 'buy some sausages', TODO_ITEM_THREE])
.then(function () { done(); });
});
test.it('should remove the item if an empty text string was entered', function () {
test.it('should remove the item if an empty text string was entered', function (done) {
page.editItemAtIndex(1, webdriver.Key.ENTER);
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_THREE]);
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_THREE])
.then(function () { done(); });
});
test.it('should cancel edits on escape', function () {
test.it('should cancel edits on escape', function (done) {
page.editItemAtIndex(1, 'foo' + webdriver.Key.ESCAPE);
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_TWO, TODO_ITEM_THREE]);
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_TWO, TODO_ITEM_THREE])
.then(function () { done(); });
});
});
test.describe('Counter', function () {
test.it('should display the current number of todo items', function () {
test.it('should display the current number of todo items', function (done) {
page.enterItem(TODO_ITEM_ONE);
testOps.assertItemCountText('1 item left');
page.enterItem(TODO_ITEM_TWO);
testOps.assertItemCountText('2 items left');
testOps.assertItemCountText('2 items left')
.then(function () { done(); });
});
});
test.describe('Clear completed button', function () {
test.beforeEach(function () {
createStandardItems();
});
test.beforeEach(createStandardItems);
test.it('should display the correct text', function () {
test.it('should display the correct text', function (done) {
page.toggleItemAtIndex(1);
testOps.assertClearCompleteButtonText('Clear completed');
testOps.assertClearCompleteButtonText('Clear completed')
.then(function () { done(); });
});
test.it('should remove completed items when clicked', function () {
test.it('should remove completed items when clicked', function (done) {
page.toggleItemAtIndex(1);
page.clickClearCompleteButton();
testOps.assertItemCount(2);
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_THREE]);
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_THREE])
.then(function () { done(); });
});
test.it('should be hidden when there are no items that are completed', function () {
test.it('should be hidden when there are no items that are completed', function (done) {
page.toggleItemAtIndex(1);
testOps.assertClearCompleteButtonIsVisible();
page.clickClearCompleteButton();
testOps.assertClearCompleteButtonIsHidden();
testOps.assertClearCompleteButtonIsHidden()
.then(function () { done(); });
});
});
test.describe('Persistence', function () {
test.it('should persist its data', function () {
// set up state
page.enterItem(TODO_ITEM_ONE);
page.enterItem(TODO_ITEM_TWO);
page.toggleItemAtIndex(1);
test.it('should persist its data', function (done) {
function stateTest() {
// wait until things are visible
browser.wait(function () {
......@@ -309,13 +331,16 @@ module.exports.todoMVCTest = function (frameworkName, baseUrl, speedMode, laxMod
return labels.length > 0;
});
}, 5000);
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_TWO]);
testOps.assertItemAtIndexIsCompleted(1);
testOps.assertItemAtIndexIsNotCompleted(0);
return testOps.assertItemAtIndexIsNotCompleted(0);
}
// test it
// set up state
page.enterItem(TODO_ITEM_ONE);
page.enterItem(TODO_ITEM_TWO);
page.toggleItemAtIndex(1);
stateTest();
// navigate away and back again
......@@ -323,66 +348,60 @@ module.exports.todoMVCTest = function (frameworkName, baseUrl, speedMode, laxMod
browser.get(baseUrl);
// repeat the state test
stateTest();
stateTest()
.then(function () { done(); });
});
});
test.describe('Routing', function () {
test.beforeEach(function () {
createStandardItems();
});
test.it('should allow me to display active items', function () {
test.beforeEach(createStandardItems);
test.it('should allow me to display active items', function (done) {
page.toggleItemAtIndex(1);
page.filterByActiveItems();
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_THREE]);
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_THREE])
.then(function () { return done(); });
});
test.it('should respect the back button', function () {
test.it('should respect the back button', function (done) {
page.toggleItemAtIndex(1);
page.filterByActiveItems();
page.filterByCompletedItems();
// should show completed items
testOps.assertItems([TODO_ITEM_TWO]);
// then active items
page.back();
testOps.assertItems([TODO_ITEM_TWO]);// should show completed items
page.back(); // then active items
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_THREE]);
// then all items
page.back();
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_TWO, TODO_ITEM_THREE]);
page.back(); // then all items
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_TWO, TODO_ITEM_THREE])
.then(function () { done(); });
});
test.it('should allow me to display completed items', function () {
test.it('should allow me to display completed items', function (done) {
page.toggleItemAtIndex(1);
page.filterByCompletedItems();
testOps.assertItems([TODO_ITEM_TWO]);
page.filterByAllItems() // TODO: why
.then(function () { done(); });
});
test.it('should allow me to display all items', function () {
test.it('should allow me to display all items', function (done) {
page.toggleItemAtIndex(1);
// apply the other filters first, before returning to the 'all' state
page.filterByActiveItems();
page.filterByCompletedItems();
page.filterByAllItems();
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_TWO, TODO_ITEM_THREE]);
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_TWO, TODO_ITEM_THREE])
.then(function () { done(); });
});
test.it('should highlight the currently applied filter', function () {
test.it('should highlight the currently applied filter', function (done) {
// initially 'all' should be selected
testOps.assertFilterAtIndexIsSelected(0);
page.filterByActiveItems();
testOps.assertFilterAtIndexIsSelected(1);
page.filterByCompletedItems();
testOps.assertFilterAtIndexIsSelected(2);
testOps.assertFilterAtIndexIsSelected(2)
.then(function () { done(); });
});
});
});
......
......@@ -16,15 +16,16 @@ function TestOperations(page) {
function testIsVisible(elements, name) {
assert.equal(elements.length, 1);
elements[0].isDisplayed().then(function (isDisplayed) {
return elements[0].isDisplayed()
.then(function (isDisplayed) {
assert(isDisplayed, 'the ' + name + ' element should be displayed');
});
}
this.assertNewInputNotFocused = function () {
return page.getFocussedElementName()
.then(function (name) {
assert.notEqual(name, 'new-todo');
return page.getFocussedElementIdOrClass()
.then(function (focussedElementIdOrClass) {
assert.equal(focussedElementIdOrClass.indexOf('new-todo'), -1);
});
};
......@@ -35,85 +36,105 @@ function TestOperations(page) {
});
};
this.assertFocussedElementId = function (expectedId) {
page.getFocussedElementName().then(function (id) {
assert.notEqual(id.indexOf(expectedId), -1, 'The focused element did not have the expected id ' + expectedId);
this.assertFocussedElement = function (expectedIdentifier) {
return page.getFocussedElementIdOrClass()
.then(function (focusedElementIdentifier) {
var failMsg = 'The focused element did not have the expected class or id "' + expectedIdentifier + '"';
assert.notEqual(focusedElementIdentifier.indexOf(expectedIdentifier), -1, failMsg);
});
};
this.assertClearCompleteButtonIsHidden = function () {
page.tryGetClearCompleteButton().then(function (element) {
testIsHidden(element, 'clear completed items button');
return page.tryGetClearCompleteButton()
.then(function (element) {
return testIsHidden(element, 'clear completed items button');
}, function (_error) {
assert(_error.code === 7, 'error accessing clear completed items button, error: ' + _error.message);
});
};
this.assertClearCompleteButtonIsVisible = function () {
page.tryGetClearCompleteButton().then(function (element) {
testIsVisible([element], 'clear completed items button');
return page.waitForVisibleElement(function () {
return page.tryGetClearCompleteButton();
})
.then(function (clearCompleteButton) {
assert(clearCompleteButton, 'the clear completed items button element should be displayed');
});
};
this.assertItemCount = function (itemCount) {
page.getItemElements().then(function (toDoItems) {
return page.getItemElements()
.then(function (toDoItems) {
assert.equal(toDoItems.length, itemCount,
itemCount + ' items expected in the todo list, ' + toDoItems.length + ' items observed');
});
};
this.assertClearCompleteButtonText = function (buttonText) {
return page.tryGetClearCompleteButton()
.getText().then(function (text) {
assert.equal(text, buttonText);
return page.waitForVisibleElement(function () {
return page.tryGetClearCompleteButton();
})
.then(function (clearCompleteButton) {
return clearCompleteButton.getText();
})
.then(function (text) {
return assert.equal(text, buttonText);
});
};
this.assertMainSectionIsHidden = function () {
page.tryGetMainSectionElement().then(function (mainSection) {
testIsHidden(mainSection, 'main');
return page.tryGetMainSectionElement()
.then(function (mainSection) {
return testIsHidden(mainSection, 'main');
});
};
this.assertFooterIsHidden = function () {
page.tryGetFooterElement().then(function (footer) {
testIsHidden(footer, 'footer');
return page.tryGetFooterElement()
.then(function (footer) {
return testIsHidden(footer, 'footer');
});
};
this.assertMainSectionIsVisible = function () {
page.tryGetMainSectionElement().then(function (mainSection) {
testIsVisible(mainSection, 'main');
return page.tryGetMainSectionElement()
.then(function (mainSection) {
return testIsVisible(mainSection, 'main');
});
};
//TODO: fishy!
this.assertItemToggleIsHidden = function (index) {
page.tryGetToggleForItemAtIndex(index).then(function (toggleItem) {
testIsHidden(toggleItem, 'item-toggle');
return page.tryGetToggleForItemAtIndex(index)
.then(function (toggleItem) {
return testIsHidden(toggleItem, 'item-toggle');
});
};
this.assertItemLabelIsHidden = function (index) {
page.tryGetItemLabelAtIndex(index).then(function (toggleItem) {
testIsHidden(toggleItem, 'item-label');
return page.tryGetItemLabelAtIndex(index)
.then(function (toggleItem) {
return testIsHidden(toggleItem, 'item-label');
});
};
this.assertFooterIsVisible = function () {
page.tryGetFooterElement().then(function (footer) {
testIsVisible(footer, 'footer');
return page.tryGetFooterElement()
.then(function (footer) {
return testIsVisible(footer, 'footer');
});
};
this.assertItemInputFieldText = function (text) {
page.getItemInputField().getText().then(function (inputFieldText) {
return page.getItemInputField().getText()
.then(function (inputFieldText) {
assert.equal(inputFieldText, text);
});
};
this.assertItemText = function (itemIndex, textToAssert) {
page.getItemLabelAtIndex(itemIndex).getText().then(function (text) {
return page.getItemLabelAtIndex(itemIndex).getText()
.then(function (text) {
assert.equal(text, textToAssert,
'A todo item with text \'' + textToAssert + '\' was expected at index ' +
itemIndex + ', the text \'' + text + '\' was observed');
......@@ -129,53 +150,63 @@ function TestOperations(page) {
};
this.assertItemCountText = function (textToAssert) {
page.getItemsCountElement().getText().then(function (text) {
return page.getItemsCountElement().getText()
.then(function (text) {
assert.equal(text.trim(), textToAssert, 'the item count text was incorrect');
});
};
// tests for the presence of the 'completed' CSS class for the item at the given index
this.assertItemAtIndexIsCompleted = function (index) {
page.getItemElements().then(function (toDoItems) {
toDoItems[index].getAttribute('class').then(function (cssClass) {
assert(cssClass.indexOf('completed') !== -1,
'the item at index ' + index + ' should have been marked as completed');
});
return page.getItemElements()
.then(function (toDoItems) {
return toDoItems[index].getAttribute('class');
})
.then(function (cssClass) {
var failMsg = 'the item at index ' + index + ' should have been marked as completed';
assert(cssClass.indexOf('completed') !== -1, failMsg);
});
};
this.assertItemAtIndexIsNotCompleted = function (index) {
page.getItemElements().then(function (toDoItems) {
toDoItems[index].getAttribute('class').then(function (cssClass) {
return page.getItemElements()
.then(function (toDoItems) {
return toDoItems[index].getAttribute('class');
})
.then(function (cssClass) {
// the maria implementation uses an 'incompleted' CSS class which is redundant
// TODO: this should really be moved into the pageLaxMode
assert(cssClass.indexOf('completed') === -1 || cssClass.indexOf('incompleted') !== -1,
'the item at index ' + index + ' should not have been marked as completed');
});
var failMsg = 'the item at index ' + index + ' should not have been marked as completed';
assert(cssClass.indexOf('completed') === -1 || cssClass.indexOf('incompleted') !== -1, failMsg);
});
};
this.assertFilterAtIndexIsSelected = function (selectedIndex) {
page.findByXpath(page.getSelectedFilterXPathByIndex(selectedIndex + 1))
return page.findByXpath(page.getSelectedFilterXPathByIndex(selectedIndex + 1))
.then(function (elm) {
assert.notEqual(elm, undefined, 'the filter / route at index ' + selectedIndex + ' should have been selected');
var failMsg = 'the filter / route at index ' + selectedIndex + ' should have been selected';
assert.notEqual(elm, undefined, failMsg);
});
};
this.assertCompleteAllIsClear = function () {
page.getMarkAllCompletedCheckBox().then(function (markAllCompleted) {
markAllCompleted.isSelected().then(function (isSelected) {
return page.getMarkAllCompletedCheckBox()
.then(function (markAllCompleted) {
return markAllCompleted.isSelected();
})
.then(function (isSelected) {
assert(!isSelected, 'the mark-all-completed checkbox should be clear');
});
});
};
this.assertCompleteAllIsChecked = function () {
page.getMarkAllCompletedCheckBox().then(function (markAllCompleted) {
markAllCompleted.isSelected().then(function (isSelected) {
return page.getMarkAllCompletedCheckBox()
.then(function (markAllCompleted) {
return markAllCompleted.isSelected();
})
.then(function (isSelected) {
assert(isSelected, 'the mark-all-completed checkbox should be checked');
});
});
};
}
......
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