414 lines
12 KiB
JavaScript
414 lines
12 KiB
JavaScript
'use strict';
|
|
|
|
var webdriver = require('selenium-webdriver');
|
|
var chrome = require('selenium-webdriver/chrome');
|
|
var test = require('selenium-webdriver/testing');
|
|
var Page = require('./page');
|
|
var PageLaxMode = require('./pageLaxMode');
|
|
var TestOperations = require('./testOperations');
|
|
|
|
var argv = require('optimist').default('laxMode', false).default('browser', 'chrome').argv;
|
|
|
|
function todoMVCTest(baseUrl, speedMode, laxMode, browserName) {
|
|
test.describe('TodoMVC: ', function () {
|
|
|
|
var TODO_ITEM_ONE = 'buy some cheese';
|
|
var TODO_ITEM_TWO = 'feed the cat';
|
|
var TODO_ITEM_THREE = 'book a doctors appointment';
|
|
var browser, testOps, page;
|
|
|
|
// a number of tests use this set of ToDo items.
|
|
function createStandardItems(done) {
|
|
page.enterItem(TODO_ITEM_ONE);
|
|
page.enterItem(TODO_ITEM_TWO);
|
|
return page.enterItem(TODO_ITEM_THREE)
|
|
.then(function () {
|
|
if (done instanceof Function) {
|
|
done();
|
|
}
|
|
});
|
|
}
|
|
|
|
function launchBrowser(done) {
|
|
var chromeOptions = new chrome.Options();
|
|
chromeOptions.addArguments('no-sandbox');
|
|
|
|
if (process.env.CHROME_PATH !== undefined) {
|
|
chromeOptions.setChromeBinaryPath(process.env.CHROME_PATH);
|
|
}
|
|
|
|
browser = new webdriver.Builder()
|
|
.withCapabilities({browserName: browserName})
|
|
.setChromeOptions(chromeOptions)
|
|
.build();
|
|
|
|
browser.get(baseUrl);
|
|
|
|
page = laxMode ? new PageLaxMode(browser) : new Page(browser);
|
|
testOps = new TestOperations(page);
|
|
|
|
return page.ensureAppIsVisibleAndLoaded()
|
|
.then(function () {
|
|
if (done instanceof Function) {
|
|
done();
|
|
}
|
|
});
|
|
}
|
|
|
|
function printCapturedLogs() {
|
|
var logs = browser.manage().logs();
|
|
|
|
return logs.get('browser')
|
|
.then(function (entries) {
|
|
if (entries && entries.length) {
|
|
console.log(entries);
|
|
}
|
|
});
|
|
}
|
|
|
|
function closeBrowser(done) {
|
|
return browser
|
|
.quit()
|
|
.then(function () {
|
|
if (done instanceof Function) { done(); }
|
|
});
|
|
}
|
|
|
|
if (speedMode) {
|
|
test.before(launchBrowser);
|
|
test.after(closeBrowser);
|
|
test.afterEach(function (done) {
|
|
return browser.executeScript('window.localStorage && localStorage.clear(); location.reload(true);')
|
|
.then(function () { done(); });
|
|
});
|
|
} else {
|
|
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 (done) {
|
|
testOps.assertNewInputFocused()
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
});
|
|
|
|
test.describe('No Todos', function () {
|
|
|
|
test.it('should hide #main and #footer', function (done) {
|
|
testOps.assertItemCount(0);
|
|
testOps.assertMainSectionVisibility(false);
|
|
testOps.assertFooterVisibility(false)
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
});
|
|
|
|
test.describe('New Todo', 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])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
test.it('should clear text input field when an item is added', function (done) {
|
|
page.enterItem(TODO_ITEM_ONE);
|
|
testOps.assertNewItemInputFieldText('')
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
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)
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
test.it('should trim text input', function (done) {
|
|
page.enterItem(' ' + TODO_ITEM_ONE + ' ');
|
|
testOps.assertItemText(0, TODO_ITEM_ONE)
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
test.it('should show #main and #footer when items added', function (done) {
|
|
page.enterItem(TODO_ITEM_ONE);
|
|
testOps.assertMainSectionVisibility(true);
|
|
testOps.assertFooterVisibility(true)
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
});
|
|
|
|
test.describe('Mark all as completed', function () {
|
|
|
|
test.beforeEach(createStandardItems);
|
|
|
|
test.it('should allow me to mark all items as completed', function (done) {
|
|
page.clickMarkAllCompletedCheckBox();
|
|
testOps.assertItemCompletedStates([true, true, true])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
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.assertCompleteAllCheckedStatus(true)
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
test.it('should allow me to clear the completion state of all items', function (done) {
|
|
page.clickMarkAllCompletedCheckBox();
|
|
page.clickMarkAllCompletedCheckBox();
|
|
|
|
testOps.assertItemCompletedStates([false, false, false])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
test.it('complete all checkbox should update state when items are completed / cleared', function (done) {
|
|
page.clickMarkAllCompletedCheckBox();
|
|
testOps.assertCompleteAllCheckedStatus(true);
|
|
|
|
// all items are complete, now mark one as not-complete
|
|
page.toggleItemAtIndex(0);
|
|
testOps.assertCompleteAllCheckedStatus(false);
|
|
|
|
// now mark as complete, so that once again all items are completed
|
|
page.toggleItemAtIndex(0);
|
|
testOps.assertCompleteAllCheckedStatus(true)
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
});
|
|
|
|
test.describe('Item', function () {
|
|
|
|
test.it('should allow me to mark items as complete', function (done) {
|
|
page.enterItem(TODO_ITEM_ONE);
|
|
page.enterItem(TODO_ITEM_TWO);
|
|
|
|
page.toggleItemAtIndex(0);
|
|
testOps.assertItemCompletedStates([true, false]);
|
|
|
|
page.toggleItemAtIndex(1);
|
|
testOps.assertItemCompletedStates([true, true])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
test.it('should allow me to un-mark items as complete', function (done) {
|
|
page.enterItem(TODO_ITEM_ONE);
|
|
page.enterItem(TODO_ITEM_TWO);
|
|
|
|
page.toggleItemAtIndex(0);
|
|
testOps.assertItemCompletedStates([true, false]);
|
|
|
|
page.toggleItemAtIndex(0);
|
|
testOps.assertItemCompletedStates([false, false])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
});
|
|
|
|
test.describe('Editing', function () {
|
|
|
|
test.beforeEach(function (done) {
|
|
createStandardItems();
|
|
page.doubleClickItemAtIndex(1)
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
test.it('should focus the input', function (done) {
|
|
testOps.assertItemInputFocused();
|
|
testOps.assertNewInputBlurred() // Unnecessary? The HTML spec dictates that only one element can be focused.
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
test.it('should hide other controls when editing', function (done) {
|
|
testOps.assertItemToggleIsHidden(1);
|
|
testOps.assertItemLabelIsHidden(1)
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
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])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
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])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
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])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
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])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
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])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
});
|
|
|
|
test.describe('Counter', 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')
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
});
|
|
|
|
test.describe('Clear completed button', function () {
|
|
|
|
test.beforeEach(createStandardItems);
|
|
|
|
test.it('should display the correct text', function (done) {
|
|
page.toggleItemAtIndex(1);
|
|
testOps.assertClearCompleteButtonText('Clear completed')
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
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])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
test.it('should be hidden when there are no items that are completed', function (done) {
|
|
page.toggleItemAtIndex(1);
|
|
testOps.assertClearCompleteButtonVisibility(true);
|
|
page.clickClearCompleteButton();
|
|
testOps.assertClearCompleteButtonVisibility(false)
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
});
|
|
|
|
test.describe('Persistence', function () {
|
|
|
|
test.it('should persist its data', function (done) {
|
|
function stateTest() {
|
|
testOps.assertItemCount(2);
|
|
testOps.assertItems([TODO_ITEM_ONE, TODO_ITEM_TWO]);
|
|
return testOps.assertItemCompletedStates([false, true]);
|
|
}
|
|
|
|
// set up state
|
|
page.enterItem(TODO_ITEM_ONE);
|
|
page.enterItem(TODO_ITEM_TWO);
|
|
page.toggleItemAtIndex(1);
|
|
stateTest();
|
|
|
|
// navigate away and back again
|
|
browser.get('about:blank');
|
|
browser.get(baseUrl);
|
|
|
|
// repeat the state test
|
|
stateTest()
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
});
|
|
|
|
test.describe('Routing', 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, page.ITEM_HIDDEN_OR_REMOVED, TODO_ITEM_THREE])
|
|
.then(function () { return done(); });
|
|
});
|
|
|
|
test.it('should respect the back button', function (done) {
|
|
page.toggleItemAtIndex(1);
|
|
page.filterByActiveItems();
|
|
page.filterByCompletedItems();
|
|
testOps.assertItems([page.ITEM_HIDDEN_OR_REMOVED, TODO_ITEM_TWO]); // should show completed items
|
|
page.back(); // then active items
|
|
testOps.assertItems([TODO_ITEM_ONE, page.ITEM_HIDDEN_OR_REMOVED, 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 (done) {
|
|
page.toggleItemAtIndex(1);
|
|
page.filterByCompletedItems();
|
|
testOps.assertItems([page.ITEM_HIDDEN_OR_REMOVED, TODO_ITEM_TWO]);
|
|
page.filterByAllItems() // TODO: why
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
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])
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
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)
|
|
.then(function () { done(); });
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
};
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* Init test
|
|
*/
|
|
todoMVCTest(
|
|
'http://localhost:8000/index.html',
|
|
argv.speedMode,
|
|
argv.laxMode,
|
|
argv.browser
|
|
);
|