'use strict'; var webdriver = require('selenium-webdriver'); var test = require('selenium-webdriver/testing'); var Page = require('./page'); var PageLaxMode = require('./pageLaxMode'); var TestOperations = require('./testOperations'); module.exports.todoMVCTest = function (frameworkName, baseUrl, speedMode, laxMode) { test.describe('TodoMVC - ' + frameworkName, function () { var otherUrl = 'http://localhost:8000/'; 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() { page.enterItem(TODO_ITEM_ONE); page.enterItem(TODO_ITEM_TWO); page.enterItem(TODO_ITEM_THREE); } function launchBrowser() { browser = new webdriver.Builder() .withCapabilities({browserName : 'chrome' }) .build(); browser.get(baseUrl); 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); } function closeBrowser() { browser.quit(); } if (speedMode) { test.before(function () { launchBrowser(); }); test.after(function () { closeBrowser(); }); test.beforeEach(function () { page.getItemElements().then(function (items) { if (items.length > 0) { // find any items that are not complete page.getNonCompletedItemElements().then(function (nonCompleteItems) { if (nonCompleteItems.length > 0) { page.clickMarkAllCompletedCheckBox(); } page.clickClearCompleteButton(); }); } }); }); } else { test.beforeEach(function () { launchBrowser(); }); test.afterEach(function () { closeBrowser(); }); } test.describe('No Todos', function () { test.it('should hide #main and #footer', function () { testOps.assertItemCount(0); testOps.assertMainSectionIsHidden(); testOps.assertFooterIsHidden(); }); }); test.describe('New Todo', function () { test.it('should allow me to add todo items', function () { page.enterItem(TODO_ITEM_ONE); testOps.assertItemCount(1); testOps.assertItemText(0, TODO_ITEM_ONE); page.enterItem(TODO_ITEM_TWO); testOps.assertItemCount(2); testOps.assertItemText(1, TODO_ITEM_TWO); testOps.assertItemText(0, TODO_ITEM_ONE); }); test.it('should clear text input field when an item is added', function () { page.enterItem(TODO_ITEM_ONE); testOps.assertItemInputFieldText(''); }); test.it('should trim text input', function () { page.enterItem(' ' + TODO_ITEM_ONE + ' '); testOps.assertItemText(0, TODO_ITEM_ONE); }); test.it('should show #main and #footer when items added', function () { page.enterItem(TODO_ITEM_ONE); testOps.assertMainSectionIsVisible(); testOps.assertFooterIsVisible(); }); }); test.describe('Mark all as completed', function () { test.it('should allow me to mark all items as completed', function () { createStandardItems(); page.clickMarkAllCompletedCheckBox(); testOps.assertItemAtIndexIsCompleted(0); testOps.assertItemAtIndexIsCompleted(1); testOps.assertItemAtIndexIsCompleted(2); }); test.it('should allow me to clear the completion state of all items', function () { createStandardItems(); page.clickMarkAllCompletedCheckBox(); page.clickMarkAllCompletedCheckBox(); testOps.assertItemAtIndexIsNotCompleted(0); testOps.assertItemAtIndexIsNotCompleted(1); testOps.assertItemAtIndexIsNotCompleted(2); }); test.it('complete all checkbox should update state when items are completed / cleared', function () { createStandardItems(); page.clickMarkAllCompletedCheckBox(); testOps.assertCompleteAllIsChecked(); // all items are complete, now mark one as not-complete page.toggleItemAtIndex(0); testOps.assertCompleteAllIsClear(); // now mark as complete, so that once again all items are completed page.toggleItemAtIndex(0); testOps.assertCompleteAllIsChecked(); }); }); test.describe('Item', function () { test.it('should allow me to mark items as complete', function () { page.enterItem(TODO_ITEM_ONE); page.enterItem(TODO_ITEM_TWO); page.toggleItemAtIndex(0); testOps.assertItemAtIndexIsCompleted(0); testOps.assertItemAtIndexIsNotCompleted(1); page.toggleItemAtIndex(1); testOps.assertItemAtIndexIsCompleted(0); testOps.assertItemAtIndexIsCompleted(1); }); test.it('should allow me to un-mark items as complete', function () { page.enterItem(TODO_ITEM_ONE); page.enterItem(TODO_ITEM_TWO); page.toggleItemAtIndex(0); testOps.assertItemAtIndexIsCompleted(0); testOps.assertItemAtIndexIsNotCompleted(1); page.toggleItemAtIndex(0); testOps.assertItemAtIndexIsNotCompleted(0); testOps.assertItemAtIndexIsNotCompleted(1); }); test.it('should allow me to edit an item', function () { createStandardItems(); page.doubleClickItemAtIndex(1); page.editItemAtIndex(1, 'buy some sausages' + webdriver.Key.ENTER); testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemText(1, 'buy some sausages'); testOps.assertItemText(2, TODO_ITEM_THREE); }); test.it('should show the remove button on hover', function () { // assert(false); }); }); test.describe('Editing', function () { test.it('should hide other controls when editing', function () { createStandardItems(); page.doubleClickItemAtIndex(1); testOps.assertItemToggleIsHidden(); testOps.assertItemLabelIsHidden(); }); test.it('should save edits on enter', function () { createStandardItems(); page.doubleClickItemAtIndex(1); page.editItemAtIndex(1, 'buy some sausages' + webdriver.Key.ENTER); testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemText(1, 'buy some sausages'); testOps.assertItemText(2, TODO_ITEM_THREE); }); test.it('should save edits on blur', function () { createStandardItems(); page.doubleClickItemAtIndex(1); page.editItemAtIndex(1, 'buy some sausages'); // click a toggle button so that the blur() event is fired page.toggleItemAtIndex(0); testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemText(1, 'buy some sausages'); testOps.assertItemText(2, TODO_ITEM_THREE); }); test.it('should trim entered text', function () { createStandardItems(); page.doubleClickItemAtIndex(1); page.editItemAtIndex(1, ' buy some sausages ' + webdriver.Key.ENTER); testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemText(1, 'buy some sausages'); testOps.assertItemText(2, TODO_ITEM_THREE); }); test.it('should remove the item if an empty text string was entered', function () { createStandardItems(); page.doubleClickItemAtIndex(1); page.editItemAtIndex(1, webdriver.Key.ENTER); testOps.assertItemCount(2); testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemText(1, TODO_ITEM_THREE); }); test.it('should cancel edits on escape', function () { createStandardItems(); page.doubleClickItemAtIndex(1); page.editItemAtIndex(1, 'foo' + webdriver.Key.ESCAPE); testOps.assertItemCount(3); testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemText(1, TODO_ITEM_TWO); testOps.assertItemText(2, TODO_ITEM_THREE); }); }); test.describe('Counter', function () { test.it('should display the current number of todo items', function () { page.enterItem(TODO_ITEM_ONE); testOps.assertItemCountText('1 item left'); page.enterItem(TODO_ITEM_TWO); testOps.assertItemCountText('2 items left'); }); }); test.describe('Clear completed button', function () { test.it('should display the number of completed items', function () { createStandardItems(); page.toggleItemAtIndex(1); testOps.assertClearCompleteButtonText('Clear completed (1)'); page.toggleItemAtIndex(2); testOps.assertClearCompleteButtonText('Clear completed (2)'); }); test.it('should remove completed items when clicked', function () { createStandardItems(); page.toggleItemAtIndex(1); page.clickClearCompleteButton(); testOps.assertItemCount(2); testOps.assertItemText(1, TODO_ITEM_THREE); testOps.assertItemText(0, TODO_ITEM_ONE); }); test.it('should be hidden when there are no items that are completed', function () { createStandardItems(); page.toggleItemAtIndex(1); testOps.assertClearCompleteButtonIsVisible(); page.clickClearCompleteButton(); testOps.assertClearCompleteButtonIsHidden(); }); }); 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); function stateTest() { testOps.assertItemCount(2); testOps.assertItemText(1, TODO_ITEM_TWO); testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemAtIndexIsCompleted(1); testOps.assertItemAtIndexIsNotCompleted(0); } // test it stateTest(); // navigate away and back again browser.get(otherUrl); browser.get(baseUrl); // repeat the state test stateTest(); }); }); test.describe('Routing', function () { test.it('should allow me to display active items', function () { createStandardItems(); page.toggleItemAtIndex(1); page.filterByActiveItems(); testOps.assertItemCount(2); testOps.assertItemText(1, TODO_ITEM_THREE); testOps.assertItemText(0, TODO_ITEM_ONE); }); test.it('should allow me to display completed items', function () { createStandardItems(); page.toggleItemAtIndex(1); page.filterByCompletedItems(); testOps.assertItemCount(1); testOps.assertItemText(0, TODO_ITEM_TWO); }); test.it('should allow me to display all items', function () { createStandardItems(); page.toggleItemAtIndex(1); // apply the other filters first, before returning to the 'all' state page.filterByActiveItems(); page.filterByCompletedItems(); page.filterByAllItems(); testOps.assertItemCount(3); testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemText(1, TODO_ITEM_TWO); testOps.assertItemText(2, TODO_ITEM_THREE); }); test.it('should highlight the currently applied filter', function () { createStandardItems(); // initially 'all' should be selected testOps.assertFilterAtIndexIsSelected(0); page.filterByActiveItems(); testOps.assertFilterAtIndexIsSelected(1); page.filterByCompletedItems(); testOps.assertFilterAtIndexIsSelected(2); }); }); }); };