Commit e36fff78 authored by ColinEberhardt's avatar ColinEberhardt

Merge pull request #801 from passy/browser-tests-style

Update browser-tests JS style
parents bacfede5 4a4016ff
module.exports = function (grunt) { module.exports = function (grunt) {
'use strict';
grunt.loadNpmTasks('grunt-simple-mocha'); grunt.loadNpmTasks('grunt-simple-mocha');
var gruntConfig = { grunt.initConfig({
simplemocha: { simplemocha: {
options: { options: {
reporter: 'mocha-known-issues-reporter' reporter: 'mocha-known-issues-reporter'
}, },
files: { files: {
src: 'allTests.js' src: 'allTests.js'
} }
} }
}; });
grunt.initConfig(gruntConfig);
// build tasks // build tasks
grunt.registerTask('test', ['simplemocha']); grunt.registerTask('test', ['simplemocha']);
}; };
var testSuite = require('./test.js'), 'use strict';
fs = require('fs'),
argv = require('optimist').default('laxMode', false).argv,
rootUrl = "http://localhost:8000/",
frameworkNamePattern = /^[a-z-_]+$/;
// collect together the framework names from each of the subfolders var testSuite = require('./test.js');
var list = fs.readdirSync("../architecture-examples/") var fs = require('fs');
.map(function(folderName) { return { name : folderName, path : "architecture-examples/" + folderName} }); var argv = require('optimist').default('laxMode', false).argv;
var rootUrl = 'http://localhost:8000/';
list = list.concat(fs.readdirSync("../labs/architecture-examples/") var frameworkNamePattern = /^[a-z-_]+$/;
.map(function(folderName) { return { name : folderName, path: "labs/architecture-examples/" + folderName} }));
list = list.concat(fs.readdirSync("../labs/dependency-examples/")
.map(function(folderName) { return { name : folderName, path: "labs/dependency-examples/" + folderName} }));
list = list.concat(fs.readdirSync("../dependency-examples/") // collect together the framework names from each of the subfolders
.map(function(folderName) { return { name : folderName, path: "dependency-examples/" + folderName} })); var list = fs.readdirSync('../architecture-examples/')
.map(function (folderName) {
return { name: folderName, path: 'architecture-examples/' + folderName };
})
.concat(fs.readdirSync('../labs/architecture-examples/')
.map(function (folderName) {
return { name: folderName, path: 'labs/architecture-examples/' + folderName };
})
)
.concat(fs.readdirSync('../labs/dependency-examples/')
.map(function (folderName) {
return { name: folderName, path: 'labs/dependency-examples/' + folderName };
})
)
.concat(fs.readdirSync('../dependency-examples/')
.map(function (folderName) {
return { name: folderName, path: 'dependency-examples/' + folderName };
})
);
// apps that are not hosted at the root of their folder need to be handled explicitly // apps that are not hosted at the root of their folder need to be handled explicitly
var exceptions = [ var exceptions = [
{ name : "chaplin-brunch", path : "labs/dependency-examples/chaplin-brunch/public" } { name: 'chaplin-brunch', path: 'labs/dependency-examples/chaplin-brunch/public' }
]; ];
list = list.map(function(framework) {
var exception = exceptions.filter(function(exFramework) { return exFramework.name === framework.name}); list = list.map(function (framework) {
return exception.length > 0 ? exception[0] : framework; var exception = exceptions.filter(function (exFramework) {
return exFramework.name === framework.name;
});
return exception.length > 0 ? exception[0] : framework;
}); });
// filter out any folders that are not frameworks (.e.g hidden files) // filter out any folders that are not frameworks (.e.g hidden files)
list = list.filter(function(framework) { return frameworkNamePattern.test(framework.name); }); list = list.filter(function (framework) {
return frameworkNamePattern.test(framework.name);
});
// if a specific framework has been named, just run this one // if a specific framework has been named, just run this one
if (argv.framework) { if (argv.framework) {
list = list.filter(function(framework) { return framework.name === argv.framework}); list = list.filter(function (framework) {
return framework.name === argv.framework;
});
} }
// run the tests for each framework // run the tests for each framework
var testIndex = 1; list.forEach(function (framework) {
list.forEach(function(framework) { testSuite.todoMVCTest(
testSuite.todoMVCTest(framework.name, framework.name,
rootUrl + framework.path + "/index.html", argv.speedMode, argv.laxMode); rootUrl + framework.path + '/index.html', argv.speedMode,
argv.laxMode
);
}); });
module.exports = [ module.exports = [
// the following are covered by the following issue: // the following are covered by the following issue:
// https://github.com/tastejs/todomvc/issues/789 // https://github.com/tastejs/todomvc/issues/789
"TodoMVC - agilityjs, Editing, should cancel edits on escape", 'TodoMVC - agilityjs, Editing, should cancel edits on escape',
"TodoMVC - angularjs-perf, Editing, should cancel edits on escape", 'TodoMVC - angularjs-perf, Editing, should cancel edits on escape',
"TodoMVC - closure, Editing, should cancel edits on escape", 'TodoMVC - closure, Editing, should cancel edits on escape',
"TodoMVC - jquery, Editing, should cancel edits on escape", 'TodoMVC - jquery, Editing, should cancel edits on escape',
"TodoMVC - knockback, Editing, should cancel edits on escape", 'TodoMVC - knockback, Editing, should cancel edits on escape',
"TodoMVC - spine, Editing, should cancel edits on escape", 'TodoMVC - spine, Editing, should cancel edits on escape',
"TodoMVC - yui, Editing, should cancel edits on escape", 'TodoMVC - yui, Editing, should cancel edits on escape',
// all the following are covered by this issue: // all the following are covered by this issue:
// https://github.com/tastejs/todomvc/issues/790 // https://github.com/tastejs/todomvc/issues/790
// these implementations filter the view rather than the model when routing // these implementations filter the view rather than the model when routing
"TodoMVC - agilityjs, Routing, should allow me to display active items", 'TodoMVC - agilityjs, Routing, should allow me to display active items',
"TodoMVC - agilityjs, Routing, should allow me to display completed items", 'TodoMVC - agilityjs, Routing, should allow me to display completed items',
"TodoMVC - backbone, Routing, should allow me to display active items", 'TodoMVC - backbone, Routing, should allow me to display active items',
"TodoMVC - backbone, Routing, should allow me to display completed items", 'TodoMVC - backbone, Routing, should allow me to display completed items',
"TodoMVC - maria, Routing, should allow me to display active items", 'TodoMVC - maria, Routing, should allow me to display active items',
"TodoMVC - maria, Routing, should allow me to display completed items", 'TodoMVC - maria, Routing, should allow me to display completed items',
"TodoMVC - dojo, Routing, should allow me to display active items", 'TodoMVC - dojo, Routing, should allow me to display active items',
"TodoMVC - dojo, Routing, should allow me to display completed items", 'TodoMVC - dojo, Routing, should allow me to display completed items',
// the following are covered by this issue: // the following are covered by this issue:
// https://github.com/tastejs/todomvc/issues/795 // https://github.com/tastejs/todomvc/issues/795
"TodoMVC - spine, Mark all as completed, complete all checkbox should update state when items are completed / cleared", 'TodoMVC - spine, Mark all as completed, complete all checkbox should update state when items are completed / cleared',
"TodoMVC - angularjs-perf, Mark all as completed, complete all checkbox should update state when items are completed / cleared", 'TodoMVC - angularjs-perf, Mark all as completed, complete all checkbox should update state when items are completed / cleared',
// the following implementations do not support routing // the following implementations do not support routing
"TodoMVC - jquery, Routing, should allow me to display active items", 'TodoMVC - jquery, Routing, should allow me to display active items',
"TodoMVC - jquery, Routing, should allow me to display completed items", 'TodoMVC - jquery, Routing, should allow me to display completed items',
"TodoMVC - jquery, Routing, should allow me to display all items", 'TodoMVC - jquery, Routing, should allow me to display all items',
"TodoMVC - jquery, Routing, should highlight the currently applied filter", 'TodoMVC - jquery, Routing, should highlight the currently applied filter',
// ----------------- Test framework issues ----------- // ----------------- Test framework issues -----------
// for some reason the persistence test fails for knockout, even though persistence is working // for some reason the persistence test fails for knockout, even though persistence is working
// just fine. Perhaps there is something asynchronous going on that is causing the assert // just fine. Perhaps there is something asynchronous going on that is causing the assert
// to be executed early? // to be executed early?
"TodoMVC - knockoutjs, Persistence, should persist its data", 'TodoMVC - knockoutjs, Persistence, should persist its data',
// ----------------- Unsupported implementations!! ----------- // ----------------- Unsupported implementations!! -----------
// the following are TodoMVC implementations that are not supported by the autoated UI // the following are TodoMVC implementations that are not supported by the autoated UI
// tests, and as a result have numerous failures. // tests, and as a result have numerous failures.
// polymer - does not follow the HTML spec // polymer - does not follow the HTML spec
"TodoMVC - polymer, New Todo, should allow me to add todo items", 'TodoMVC - polymer, New Todo, should allow me to add todo items',
"TodoMVC - polymer, New Todo, should clear text input field when an item is added", 'TodoMVC - polymer, New Todo, should clear text input field when an item is added',
"TodoMVC - polymer, New Todo, should trim text input", 'TodoMVC - polymer, New Todo, should trim text input',
"TodoMVC - polymer, New Todo, should show #main and #footer when items added", 'TodoMVC - polymer, New Todo, should show #main and #footer when items added',
"TodoMVC - polymer, Mark all as completed, should allow me to mark all items as completed", 'TodoMVC - polymer, Mark all as completed, should allow me to mark all items as completed',
"TodoMVC - polymer, Mark all as completed, should allow me to clear the completion state of all items", 'TodoMVC - polymer, Mark all as completed, should allow me to clear the completion state of all items',
"TodoMVC - polymer, Mark all as completed, complete all checkbox should update state when items are completed / cleared", 'TodoMVC - polymer, Mark all as completed, complete all checkbox should update state when items are completed / cleared',
"TodoMVC - polymer, Item, should allow me to mark items as complete", 'TodoMVC - polymer, Item, should allow me to mark items as complete',
"TodoMVC - polymer, Item, should allow me to un-mark items as complete", 'TodoMVC - polymer, Item, should allow me to un-mark items as complete',
"TodoMVC - polymer, Item, should allow me to edit an item", 'TodoMVC - polymer, Item, should allow me to edit an item',
"TodoMVC - polymer, Editing, should hide other controls when editing", 'TodoMVC - polymer, Editing, should hide other controls when editing',
"TodoMVC - polymer, Editing, should save edits on enter", 'TodoMVC - polymer, Editing, should save edits on enter',
"TodoMVC - polymer, Editing, should save edits on blur", 'TodoMVC - polymer, Editing, should save edits on blur',
"TodoMVC - polymer, Editing, should trim entered text", 'TodoMVC - polymer, Editing, should trim entered text',
"TodoMVC - polymer, Editing, should remove the item if an empty text string was entered", 'TodoMVC - polymer, Editing, should remove the item if an empty text string was entered',
"TodoMVC - polymer, Editing, should cancel edits on escape", 'TodoMVC - polymer, Editing, should cancel edits on escape',
"TodoMVC - polymer, Counter, should display the current number of todo items", 'TodoMVC - polymer, Counter, should display the current number of todo items',
"TodoMVC - polymer, Clear completed button, should display the number of completed items", 'TodoMVC - polymer, Clear completed button, should display the number of completed items',
"TodoMVC - polymer, Clear completed button, should remove completed items when clicked", 'TodoMVC - polymer, Clear completed button, should remove completed items when clicked',
"TodoMVC - polymer, Clear completed button, should be hidden when there are no items that are completed", 'TodoMVC - polymer, Clear completed button, should be hidden when there are no items that are completed',
"TodoMVC - polymer, Persistence, should persist its data", 'TodoMVC - polymer, Persistence, should persist its data',
"TodoMVC - polymer, Routing, should allow me to display active items", 'TodoMVC - polymer, Routing, should allow me to display active items',
"TodoMVC - polymer, Routing, should allow me to display completed items", 'TodoMVC - polymer, Routing, should allow me to display completed items',
"TodoMVC - polymer, Routing, should allow me to display all items", 'TodoMVC - polymer, Routing, should allow me to display all items',
"TodoMVC - polymer, Routing, should highlight the currently applied filter", 'TodoMVC - polymer, Routing, should highlight the currently applied filter',
// gwt - does not follow the HTML spec closely eough for testing // gwt - does not follow the HTML spec closely eough for testing
"TodoMVC - gwt, New Todo, should allow me to add todo items", 'TodoMVC - gwt, New Todo, should allow me to add todo items',
"TodoMVC - gwt, New Todo, should trim text input", 'TodoMVC - gwt, New Todo, should trim text input',
"TodoMVC - gwt, Mark all as completed, should allow me to mark all items as completed", 'TodoMVC - gwt, Mark all as completed, should allow me to mark all items as completed',
"TodoMVC - gwt, Mark all as completed, should allow me to clear the completion state of all items", 'TodoMVC - gwt, Mark all as completed, should allow me to clear the completion state of all items',
"TodoMVC - gwt, Mark all as completed, complete all checkbox should update state when items are completed / cleared", 'TodoMVC - gwt, Mark all as completed, complete all checkbox should update state when items are completed / cleared',
"TodoMVC - gwt, Item, should allow me to mark items as complete", 'TodoMVC - gwt, Item, should allow me to mark items as complete',
"TodoMVC - gwt, Item, should allow me to un-mark items as complete", 'TodoMVC - gwt, Item, should allow me to un-mark items as complete',
"TodoMVC - gwt, Item, should allow me to edit an item", 'TodoMVC - gwt, Item, should allow me to edit an item',
"TodoMVC - gwt, Editing, should hide other controls when editing", 'TodoMVC - gwt, Editing, should hide other controls when editing',
"TodoMVC - gwt, Editing, should save edits on enter", 'TodoMVC - gwt, Editing, should save edits on enter',
"TodoMVC - gwt, Editing, should save edits on blur", 'TodoMVC - gwt, Editing, should save edits on blur',
"TodoMVC - gwt, Editing, should trim entered text", 'TodoMVC - gwt, Editing, should trim entered text',
"TodoMVC - gwt, Editing, should remove the item if an empty text string was entered", 'TodoMVC - gwt, Editing, should remove the item if an empty text string was entered',
"TodoMVC - gwt, Editing, should cancel edits on escape", 'TodoMVC - gwt, Editing, should cancel edits on escape',
"TodoMVC - gwt, Clear completed button, should display the number of completed items", 'TodoMVC - gwt, Clear completed button, should display the number of completed items',
"TodoMVC - gwt, Clear completed button, should remove completed items when clicked", 'TodoMVC - gwt, Clear completed button, should remove completed items when clicked',
"TodoMVC - gwt, Clear completed button, should be hidden when there are no items that are completed", 'TodoMVC - gwt, Clear completed button, should be hidden when there are no items that are completed',
"TodoMVC - gwt, Persistence, should persist its data", 'TodoMVC - gwt, Persistence, should persist its data',
"TodoMVC - gwt, Routing, should allow me to display active items", 'TodoMVC - gwt, Routing, should allow me to display active items',
"TodoMVC - gwt, Routing, should allow me to display completed items", 'TodoMVC - gwt, Routing, should allow me to display completed items',
"TodoMVC - gwt, Routing, should allow me to display all items", 'TodoMVC - gwt, Routing, should allow me to display all items',
"TodoMVC - gwt, Routing, should highlight the currently applied filter", 'TodoMVC - gwt, Routing, should highlight the currently applied filter',
]; ];
\ No newline at end of file
var webdriver = require('selenium-webdriver'); 'use strict';
function Page(browser, laxMode) { var webdriver = require('selenium-webdriver');
// ----------------- utility methods module.exports = function Page(browser) {
this.xPathForItemAtIndex = function(index) { // ----------------- utility methods
// why is XPath the only language silly enough to be 1-indexed?
return "//ul[@id='todo-list']/li[" + (index + 1) + "]"; this.xPathForItemAtIndex = function (index) {
} // why is XPath the only language silly enough to be 1-indexed?
return '//ul[@id="todo-list"]/li[' + (index + 1) + ']';
// ----------------- try / get methods };
// unfortunately webdriver does not have a decent API for determining if an // ----------------- try / get methods
// element exists. The standard approach is to obtain an array of elements
// and test that the length is zero. These methods are used to obtain // unfortunately webdriver does not have a decent API for determining if an
// elements which *might* be present in the DOM, hence the try/get name. // element exists. The standard approach is to obtain an array of elements
// and test that the length is zero. These methods are used to obtain
this.tryGetMainSectionElement = function() { // elements which *might* be present in the DOM, hence the try/get name.
return browser.findElements(webdriver.By.xpath("//section[@id='main']"));
} this.tryGetMainSectionElement = function () {
return browser.findElements(webdriver.By.xpath('//section[@id="main"]'));
this.tryGetFooterElement = function() { };
return browser.findElements(webdriver.By.xpath("//footer[@id='footer']"));
} this.tryGetFooterElement = function () {
return browser.findElements(webdriver.By.xpath('//footer[@id="footer"]'));
this.tryGetClearCompleteButton = function() { };
return browser.findElements(webdriver.By.xpath("//button[@id='clear-completed']"));
} this.tryGetClearCompleteButton = function () {
return browser.findElements(webdriver.By.xpath('//button[@id="clear-completed"]'));
this.tryGetToggleForItemAtIndex = function(index) { };
var xpath = this.xPathForItemAtIndex(index) + "//input[contains(@class,'toggle')]";
return browser.findElements(webdriver.By.xpath(xpath)); this.tryGetToggleForItemAtIndex = function (index) {
} var xpath = this.xPathForItemAtIndex(index) + '//input[contains(@class,"toggle")]';
return browser.findElements(webdriver.By.xpath(xpath));
this.tryGetItemLabelAtIndex = function(index) { };
return browser.findElements(webdriver.By.xpath(this.xPathForItemAtIndex(index) + "//label"));
} this.tryGetItemLabelAtIndex = function (index) {
return browser.findElements(webdriver.By.xpath(this.xPathForItemAtIndex(index) + '//label'));
// ----------------- DOM element access methods };
this.getEditInputForItemAtIndex = function(index) { // ----------------- DOM element access methods
var xpath = this.xPathForItemAtIndex(index) + "//input[contains(@class,'edit')]";
return browser.findElement(webdriver.By.xpath(xpath)); this.getEditInputForItemAtIndex = function (index) {
} var xpath = this.xPathForItemAtIndex(index) + '//input[contains(@class,"edit")]';
return browser.findElement(webdriver.By.xpath(xpath));
this.getItemInputField = function() { };
return browser.findElement(webdriver.By.xpath("//input[@id='new-todo']"));
} this.getItemInputField = function () {
return browser.findElement(webdriver.By.xpath('//input[@id="new-todo"]'));
this.getMarkAllCompletedCheckBox = function() { };
return browser.findElement(webdriver.By.xpath("//input[@id='toggle-all']"));
} this.getMarkAllCompletedCheckBox = function () {
return browser.findElement(webdriver.By.xpath('//input[@id="toggle-all"]'));
this.getItemElements = function() { };
return browser.findElements(webdriver.By.xpath("//ul[@id='todo-list']/li"));
} this.getItemElements = function () {
return browser.findElements(webdriver.By.xpath('//ul[@id="todo-list"]/li'));
this.getNonCompletedItemElements = function() { };
return browser.findElements(webdriver.By.xpath("//ul[@id='todo-list']/li[not(contains(@class,'completed'))]"));
} this.getNonCompletedItemElements = function () {
return browser.findElements(webdriver.By.xpath('//ul[@id="todo-list"]/li[not(contains(@class,"completed"))]'));
this.getItemsCountElement = function() { };
return browser.findElement(webdriver.By.id("todo-count"));
} this.getItemsCountElement = function () {
return browser.findElement(webdriver.By.id('todo-count'));
this.getItemLabelAtIndex = function(index) { };
return browser.findElement(webdriver.By.xpath(this.xPathForItemAtIndex(index) + "//label"));
} this.getItemLabelAtIndex = function (index) {
return browser.findElement(webdriver.By.xpath(this.xPathForItemAtIndex(index) + '//label'));
this.getFilterElements = function() { };
return browser.findElements(webdriver.By.xpath("//ul[@id='filters']//a"));
} this.getFilterElements = function () {
return browser.findElements(webdriver.By.xpath('//ul[@id="filters"]//a'));
// ----------------- page actions };
this.clickMarkAllCompletedCheckBox = function() { // ----------------- page actions
return this.getMarkAllCompletedCheckBox().then(function(checkbox){
checkbox.click(); this.clickMarkAllCompletedCheckBox = function () {
}); return this.getMarkAllCompletedCheckBox().then(function (checkbox) {
} checkbox.click();
});
this.clickClearCompleteButton = function() { };
return this.tryGetClearCompleteButton().then(function(elements) {
var button = elements[0]; this.clickClearCompleteButton = function () {
button.click(); return this.tryGetClearCompleteButton().then(function (elements) {
}); var button = elements[0];
} button.click();
});
this.enterItem = function(itemText) { };
var textField = this.getItemInputField();
textField.sendKeys(itemText); this.enterItem = function (itemText) {
textField.sendKeys(webdriver.Key.ENTER); var textField = this.getItemInputField();
}; textField.sendKeys(itemText);
textField.sendKeys(webdriver.Key.ENTER);
this.toggleItemAtIndex = function(index) { };
return this.tryGetToggleForItemAtIndex(index).then(function(elements) {
var toggleElement = elements[0]; this.toggleItemAtIndex = function (index) {
toggleElement.click(); return this.tryGetToggleForItemAtIndex(index).then(function (elements) {
}); var toggleElement = elements[0];
} toggleElement.click();
});
this.editItemAtIndex = function(index, itemText) { };
return this.getEditInputForItemAtIndex(index)
.then(function(itemEditField) { this.editItemAtIndex = function (index, itemText) {
return this.getEditInputForItemAtIndex(index)
// send 50 delete keypresses, just to be sure the item text is deleted .then(function (itemEditField) {
var deleteKeyPresses = ""; // send 50 delete keypresses, just to be sure the item text is deleted
for (var i=0;i<50;i++) { var deleteKeyPresses = '';
deleteKeyPresses += webdriver.Key.BACK_SPACE for (var i = 0; i < 50; i++) {
} deleteKeyPresses += webdriver.Key.BACK_SPACE;
itemEditField.sendKeys(deleteKeyPresses); }
// update the item with the new text. itemEditField.sendKeys(deleteKeyPresses);
itemEditField.sendKeys(itemText);
}); // update the item with the new text.
}; itemEditField.sendKeys(itemText);
});
this.doubleClickItemAtIndex = function(index) { };
return this.getItemLabelAtIndex(index).then(function(itemLabel) {
// double click is not 'natively' supported, so we need to send the event direct to the element this.doubleClickItemAtIndex = function (index) {
// see: http://stackoverflow.com/questions/3982442/selenium-2-webdriver-how-to-double-click-a-table-row-which-opens-a-new-window return this.getItemLabelAtIndex(index).then(function (itemLabel) {
browser.executeScript("var evt = document.createEvent('MouseEvents');" + // double click is not 'natively' supported, so we need to send the
"evt.initMouseEvent('dblclick',true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0,null);" + // event direct to the element see:
"arguments[0].dispatchEvent(evt);", itemLabel); // http://stackoverflow.com/questions/3982442/selenium-2-webdriver-how-to-double-click-a-table-row-which-opens-a-new-window
browser.executeScript('var evt = document.createEvent("MouseEvents");' +
}); 'evt.initMouseEvent("dblclick",true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0,null);' +
} 'arguments[0].dispatchEvent(evt);', itemLabel);
});
this.filterByActiveItems = function(index) { };
return this.getFilterElements().then(function(filters) {
filters[1].click(); this.filterByActiveItems = function () {
}); return this.getFilterElements().then(function (filters) {
} filters[1].click();
});
this.filterByCompletedItems = function(index) { };
return this.getFilterElements().then(function(filters) {
filters[2].click(); this.filterByCompletedItems = function () {
}); return this.getFilterElements().then(function (filters) {
} filters[2].click();
});
this.filterByAllItems = function(index) { };
return this.getFilterElements().then(function(filters) {
filters[0].click(); this.filterByAllItems = function () {
}); return this.getFilterElements().then(function (filters) {
} filters[0].click();
} });
};
module.exports = Page; };
\ No newline at end of file
var webdriver = require('selenium-webdriver'), 'use strict';
Page = require("./page");
function PageLaxMode(browser) { var webdriver = require('selenium-webdriver');
Page.apply(this, [browser]); var Page = require('./page');
this.tryGetToggleForItemAtIndex = function(index) { module.exports = function PageLaxMode(browser) {
// the specification dictates that the checkbox should have the 'toggle' CSS class. Some implementations deviate from Page.apply(this, [browser]);
// this, hence in lax mode we simply look for any checkboxes within the specified 'li'.
var xpath = this.xPathForItemAtIndex(index) + "//input[@type='checkbox']";
return browser.findElements(webdriver.By.xpath(xpath));
}
this.getEditInputForItemAtIndex = function(index) { this.tryGetToggleForItemAtIndex = function (index) {
// the specification dictates that the input element that allows the user to edit a todo item should have a CSS // the specification dictates that the checkbox should have the 'toggle' CSS class. Some implementations deviate from
// class of 'edit'. In lax mode, we also look for an input of type 'text'. // this, hence in lax mode we simply look for any checkboxes within the specified 'li'.
var xpath = this.xPathForItemAtIndex(index) + '//input[@type="checkbox"]';
return browser.findElements(webdriver.By.xpath(xpath));
};
var xpath = "(" + this.xPathForItemAtIndex(index) + "//input[@type='text']" + "|" + this.getEditInputForItemAtIndex = function (index) {
this.xPathForItemAtIndex(index) + "//input[contains(@class,'edit')]" + ")"; // the specification dictates that the input element that allows the user to edit a todo item should have a CSS
return browser.findElement(webdriver.By.xpath(xpath)); // class of 'edit'. In lax mode, we also look for an input of type 'text'.
}
}
module.exports = PageLaxMode; var xpath = '(' + this.xPathForItemAtIndex(index) + '//input[@type="text"]' + '|' +
\ No newline at end of file this.xPathForItemAtIndex(index) + '//input[contains(@class,"edit")]' + ')';
return browser.findElement(webdriver.By.xpath(xpath));
};
};
var webdriver = require('selenium-webdriver'), 'use strict';
test = require('selenium-webdriver/testing'),
assert = require("assert"), var webdriver = require('selenium-webdriver');
Page = require("./page"), var test = require('selenium-webdriver/testing');
PageLaxMode = require("./pageLaxMode"), var Page = require('./page');
TestOperations = require("./testOperations"); var PageLaxMode = require('./pageLaxMode');
var TestOperations = require('./testOperations');
exports.todoMVCTest = function(frameworkName, baseUrl, speedMode, laxMode) {
test.describe('TodoMVC - ' + frameworkName, function () { module.exports.todoMVCTest = function (frameworkName, baseUrl, speedMode, laxMode) {
var otherUrl = "http://localhost:8000/"; test.describe('TodoMVC - ' + frameworkName, function () {
var TODO_ITEM_ONE = "buy some cheese"; var otherUrl = 'http://localhost:8000/';
var TODO_ITEM_TWO = "feed the cat"; var TODO_ITEM_ONE = 'buy some cheese';
var TODO_ITEM_THREE = "book a doctors appointment"; var TODO_ITEM_TWO = 'feed the cat';
var TODO_ITEM_THREE = 'book a doctors appointment';
var browser, testOps, page;
var browser, testOps, page;
// a number of tests use this set of ToDo items.
function createStandardItems() { // a number of tests use this set of ToDo items.
page.enterItem(TODO_ITEM_ONE); function createStandardItems() {
page.enterItem(TODO_ITEM_TWO); page.enterItem(TODO_ITEM_ONE);
page.enterItem(TODO_ITEM_THREE); page.enterItem(TODO_ITEM_TWO);
} page.enterItem(TODO_ITEM_THREE);
}
function launchBrowser() {
browser = new webdriver.Builder() function launchBrowser() {
.withCapabilities({browserName : "chrome" }) browser = new webdriver.Builder()
.build(); .withCapabilities({browserName : 'chrome' })
.build();
browser.get(baseUrl);
browser.get(baseUrl);
page = laxMode ? new PageLaxMode(browser) : new Page(browser);
testOps = new TestOperations(page); 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! // for apps that use require, we have to wait a while for the dependencies to
browser.sleep(200); // be loaded. There must be a more elegant solution than this!
} browser.sleep(200);
}
function closeBrowser() {
browser.quit(); function closeBrowser() {
} browser.quit();
}
if (speedMode) {
test.before(function () { if (speedMode) {
launchBrowser(); test.before(function () {
}); launchBrowser();
test.after(function () { });
closeBrowser(); test.after(function () {
}); closeBrowser();
test.beforeEach(function () { });
page.getItemElements().then(function (items) { test.beforeEach(function () {
if (items.length > 0) { page.getItemElements().then(function (items) {
// find any items that are not complete if (items.length > 0) {
page.getNonCompletedItemElements().then(function(nonCompleteItems) { // find any items that are not complete
if (nonCompleteItems.length > 0) { page.getNonCompletedItemElements().then(function (nonCompleteItems) {
page.clickMarkAllCompletedCheckBox(); if (nonCompleteItems.length > 0) {
} page.clickMarkAllCompletedCheckBox();
page.clickClearCompleteButton(); }
}); page.clickClearCompleteButton();
} });
}); }
}); });
} else { });
test.beforeEach(function () { } else {
launchBrowser(); test.beforeEach(function () {
}); launchBrowser();
test.afterEach(function () { });
closeBrowser(); test.afterEach(function () {
}); closeBrowser();
} });
}
test.describe('No Todos', function () {
test.it('should hide #main and #footer', function () { test.describe('No Todos', function () {
testOps.assertItemCount(0); test.it('should hide #main and #footer', function () {
testOps.assertMainSectionIsHidden(); testOps.assertItemCount(0);
testOps.assertFooterIsHidden(); testOps.assertMainSectionIsHidden();
}); testOps.assertFooterIsHidden();
}); });
});
test.describe('New Todo', function () {
test.it('should allow me to add todo items', function () { test.describe('New Todo', function () {
page.enterItem(TODO_ITEM_ONE); test.it('should allow me to add todo items', function () {
testOps.assertItemCount(1); page.enterItem(TODO_ITEM_ONE);
testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemCount(1);
testOps.assertItemText(0, TODO_ITEM_ONE);
page.enterItem(TODO_ITEM_TWO);
testOps.assertItemCount(2); page.enterItem(TODO_ITEM_TWO);
testOps.assertItemText(1, TODO_ITEM_TWO); testOps.assertItemCount(2);
testOps.assertItemText(0, TODO_ITEM_ONE); 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); test.it('should clear text input field when an item is added', function () {
testOps.assertItemInputFieldText(""); page.enterItem(TODO_ITEM_ONE);
}); testOps.assertItemInputFieldText('');
});
test.it('should trim text input', function () {
page.enterItem(" " + TODO_ITEM_ONE + " "); test.it('should trim text input', function () {
testOps.assertItemText(0, TODO_ITEM_ONE); 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); test.it('should show #main and #footer when items added', function () {
testOps.assertMainSectionIsVisible(); page.enterItem(TODO_ITEM_ONE);
testOps.assertFooterIsVisible(); testOps.assertMainSectionIsVisible();
}); testOps.assertFooterIsVisible();
}); });
});
test.describe('Mark all as completed', function () {
test.it('should allow me to mark all items as completed', function () { test.describe('Mark all as completed', function () {
createStandardItems(); test.it('should allow me to mark all items as completed', function () {
page.clickMarkAllCompletedCheckBox(); createStandardItems();
page.clickMarkAllCompletedCheckBox();
testOps.assertItemAtIndexIsCompleted(0);
testOps.assertItemAtIndexIsCompleted(1); testOps.assertItemAtIndexIsCompleted(0);
testOps.assertItemAtIndexIsCompleted(2); testOps.assertItemAtIndexIsCompleted(1);
}); testOps.assertItemAtIndexIsCompleted(2);
});
test.it('should allow me to clear the completion state of all items', function () {
createStandardItems(); test.it('should allow me to clear the completion state of all items', function () {
page.clickMarkAllCompletedCheckBox(); createStandardItems();
page.clickMarkAllCompletedCheckBox(); page.clickMarkAllCompletedCheckBox();
page.clickMarkAllCompletedCheckBox();
testOps.assertItemAtIndexIsNotCompleted(0);
testOps.assertItemAtIndexIsNotCompleted(1); testOps.assertItemAtIndexIsNotCompleted(0);
testOps.assertItemAtIndexIsNotCompleted(2); testOps.assertItemAtIndexIsNotCompleted(1);
}); testOps.assertItemAtIndexIsNotCompleted(2);
});
test.it('complete all checkbox should update state when items are completed / cleared', function () {
createStandardItems(); test.it('complete all checkbox should update state when items are completed / cleared', function () {
page.clickMarkAllCompletedCheckBox(); createStandardItems();
page.clickMarkAllCompletedCheckBox();
testOps.assertCompleteAllIsChecked();
testOps.assertCompleteAllIsChecked();
// all items are complete, now mark one as not-complete
page.toggleItemAtIndex(0); // all items are complete, now mark one as not-complete
testOps.assertCompleteAllIsClear(); page.toggleItemAtIndex(0);
testOps.assertCompleteAllIsClear();
// now mark as complete, so that once again all items are completed
page.toggleItemAtIndex(0); // now mark as complete, so that once again all items are completed
testOps.assertCompleteAllIsChecked(); page.toggleItemAtIndex(0);
}); testOps.assertCompleteAllIsChecked();
}); });
});
test.describe('Item', function () {
test.it('should allow me to mark items as complete', function () { test.describe('Item', function () {
page.enterItem(TODO_ITEM_ONE); test.it('should allow me to mark items as complete', function () {
page.enterItem(TODO_ITEM_TWO); page.enterItem(TODO_ITEM_ONE);
page.enterItem(TODO_ITEM_TWO);
page.toggleItemAtIndex(0);
testOps.assertItemAtIndexIsCompleted(0); page.toggleItemAtIndex(0);
testOps.assertItemAtIndexIsNotCompleted(1); testOps.assertItemAtIndexIsCompleted(0);
testOps.assertItemAtIndexIsNotCompleted(1);
page.toggleItemAtIndex(1);
testOps.assertItemAtIndexIsCompleted(0); page.toggleItemAtIndex(1);
testOps.assertItemAtIndexIsCompleted(1); testOps.assertItemAtIndexIsCompleted(0);
}); testOps.assertItemAtIndexIsCompleted(1);
});
test.it('should allow me to un-mark items as complete', function () {
page.enterItem(TODO_ITEM_ONE); test.it('should allow me to un-mark items as complete', function () {
page.enterItem(TODO_ITEM_TWO); page.enterItem(TODO_ITEM_ONE);
page.enterItem(TODO_ITEM_TWO);
page.toggleItemAtIndex(0);
testOps.assertItemAtIndexIsCompleted(0); page.toggleItemAtIndex(0);
testOps.assertItemAtIndexIsNotCompleted(1); testOps.assertItemAtIndexIsCompleted(0);
testOps.assertItemAtIndexIsNotCompleted(1);
page.toggleItemAtIndex(0);
testOps.assertItemAtIndexIsNotCompleted(0); page.toggleItemAtIndex(0);
testOps.assertItemAtIndexIsNotCompleted(1); testOps.assertItemAtIndexIsNotCompleted(0);
}); testOps.assertItemAtIndexIsNotCompleted(1);
});
test.it('should allow me to edit an item', function () {
createStandardItems(); test.it('should allow me to edit an item', function () {
page.doubleClickItemAtIndex(1); createStandardItems();
page.doubleClickItemAtIndex(1);
page.editItemAtIndex(1, "buy some sausages" + webdriver.Key.ENTER);
page.editItemAtIndex(1, 'buy some sausages' + webdriver.Key.ENTER);
testOps.assertItemText(0, TODO_ITEM_ONE);
testOps.assertItemText(1, "buy some sausages"); testOps.assertItemText(0, TODO_ITEM_ONE);
testOps.assertItemText(2, TODO_ITEM_THREE); 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.it('should show the remove button on hover', function () {
}); // assert(false);
}); });
});
test.describe('Editing', function () {
test.it('should hide other controls when editing', function () { test.describe('Editing', function () {
createStandardItems(); test.it('should hide other controls when editing', function () {
page.doubleClickItemAtIndex(1); createStandardItems();
page.doubleClickItemAtIndex(1);
testOps.assertItemToggleIsHidden();
testOps.assertItemLabelIsHidden(); testOps.assertItemToggleIsHidden();
}); testOps.assertItemLabelIsHidden();
});
test.it('should save edits on enter', function () {
createStandardItems(); test.it('should save edits on enter', function () {
page.doubleClickItemAtIndex(1); createStandardItems();
page.doubleClickItemAtIndex(1);
page.editItemAtIndex(1, "buy some sausages" + webdriver.Key.ENTER);
page.editItemAtIndex(1, 'buy some sausages' + webdriver.Key.ENTER);
testOps.assertItemText(0, TODO_ITEM_ONE);
testOps.assertItemText(1, "buy some sausages"); testOps.assertItemText(0, TODO_ITEM_ONE);
testOps.assertItemText(2, TODO_ITEM_THREE); testOps.assertItemText(1, 'buy some sausages');
}); testOps.assertItemText(2, TODO_ITEM_THREE);
});
test.it('should save edits on blur', function () {
createStandardItems(); test.it('should save edits on blur', function () {
page.doubleClickItemAtIndex(1); createStandardItems();
page.doubleClickItemAtIndex(1);
page.editItemAtIndex(1, "buy some sausages");
page.editItemAtIndex(1, 'buy some sausages');
// click a toggle button so that the blur() event is fired
page.toggleItemAtIndex(0); // 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(0, TODO_ITEM_ONE);
testOps.assertItemText(2, TODO_ITEM_THREE); testOps.assertItemText(1, 'buy some sausages');
}); testOps.assertItemText(2, TODO_ITEM_THREE);
});
test.it('should trim entered text', function () {
createStandardItems(); test.it('should trim entered text', function () {
page.doubleClickItemAtIndex(1); createStandardItems();
page.doubleClickItemAtIndex(1);
page.editItemAtIndex(1, " buy some sausages " + webdriver.Key.ENTER);
page.editItemAtIndex(1, ' buy some sausages ' + webdriver.Key.ENTER);
testOps.assertItemText(0, TODO_ITEM_ONE);
testOps.assertItemText(1, "buy some sausages"); testOps.assertItemText(0, TODO_ITEM_ONE);
testOps.assertItemText(2, TODO_ITEM_THREE); 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(); test.it('should remove the item if an empty text string was entered', function () {
page.doubleClickItemAtIndex(1); createStandardItems();
page.doubleClickItemAtIndex(1);
page.editItemAtIndex(1, webdriver.Key.ENTER);
page.editItemAtIndex(1, webdriver.Key.ENTER);
testOps.assertItemCount(2);
testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemCount(2);
testOps.assertItemText(1, TODO_ITEM_THREE); testOps.assertItemText(0, TODO_ITEM_ONE);
}); testOps.assertItemText(1, TODO_ITEM_THREE);
});
test.it('should cancel edits on escape', function () {
createStandardItems(); test.it('should cancel edits on escape', function () {
page.doubleClickItemAtIndex(1); createStandardItems();
page.doubleClickItemAtIndex(1);
page.editItemAtIndex(1, "foo" + webdriver.Key.ESCAPE);
page.editItemAtIndex(1, 'foo' + webdriver.Key.ESCAPE);
testOps.assertItemCount(3);
testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemCount(3);
testOps.assertItemText(1, TODO_ITEM_TWO); testOps.assertItemText(0, TODO_ITEM_ONE);
testOps.assertItemText(2, TODO_ITEM_THREE); 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 () { test.describe('Counter', function () {
page.enterItem(TODO_ITEM_ONE); test.it('should display the current number of todo items', function () {
testOps.assertItemCountText("1 item left"); page.enterItem(TODO_ITEM_ONE);
page.enterItem(TODO_ITEM_TWO); testOps.assertItemCountText('1 item left');
testOps.assertItemCountText("2 items 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 () { test.describe('Clear completed button', function () {
createStandardItems(); test.it('should display the number of completed items', function () {
page.toggleItemAtIndex(1); createStandardItems();
testOps.assertClearCompleteButtonText("Clear completed (1)"); page.toggleItemAtIndex(1);
page.toggleItemAtIndex(2); testOps.assertClearCompleteButtonText('Clear completed (1)');
testOps.assertClearCompleteButtonText("Clear completed (2)"); page.toggleItemAtIndex(2);
}); testOps.assertClearCompleteButtonText('Clear completed (2)');
});
test.it('should remove completed items when clicked', function () {
createStandardItems(); test.it('should remove completed items when clicked', function () {
page.toggleItemAtIndex(1); createStandardItems();
page.clickClearCompleteButton(); page.toggleItemAtIndex(1);
testOps.assertItemCount(2); page.clickClearCompleteButton();
testOps.assertItemText(1, TODO_ITEM_THREE); testOps.assertItemCount(2);
testOps.assertItemText(0, TODO_ITEM_ONE); 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(); test.it('should be hidden when there are no items that are completed', function () {
page.toggleItemAtIndex(1); createStandardItems();
testOps.assertClearCompleteButtonIsVisible(); page.toggleItemAtIndex(1);
page.clickClearCompleteButton(); testOps.assertClearCompleteButtonIsVisible();
testOps.assertClearCompleteButtonIsHidden(); page.clickClearCompleteButton();
}); testOps.assertClearCompleteButtonIsHidden();
}); });
});
test.describe('Persistence', function () {
test.it('should persist its data', function () { test.describe('Persistence', function () {
// set up state test.it('should persist its data', function () {
page.enterItem(TODO_ITEM_ONE); // set up state
page.enterItem(TODO_ITEM_TWO); page.enterItem(TODO_ITEM_ONE);
page.toggleItemAtIndex(1); page.enterItem(TODO_ITEM_TWO);
page.toggleItemAtIndex(1);
function stateTest() {
testOps.assertItemCount(2); function stateTest() {
testOps.assertItemText(1, TODO_ITEM_TWO); testOps.assertItemCount(2);
testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemText(1, TODO_ITEM_TWO);
testOps.assertItemAtIndexIsCompleted(1); testOps.assertItemText(0, TODO_ITEM_ONE);
testOps.assertItemAtIndexIsNotCompleted(0); testOps.assertItemAtIndexIsCompleted(1);
} testOps.assertItemAtIndexIsNotCompleted(0);
}
// test it
stateTest(); // test it
stateTest();
// navigate away and back again
browser.get(otherUrl); // navigate away and back again
browser.get(baseUrl); browser.get(otherUrl);
browser.get(baseUrl);
// repeat the state test
stateTest(); // repeat the state test
}); stateTest();
}); });
});
test.describe('Routing', function () {
test.it('should allow me to display active items', function () { test.describe('Routing', function () {
createStandardItems(); test.it('should allow me to display active items', function () {
page.toggleItemAtIndex(1); createStandardItems();
page.filterByActiveItems(); page.toggleItemAtIndex(1);
page.filterByActiveItems();
testOps.assertItemCount(2);
testOps.assertItemText(1, TODO_ITEM_THREE); testOps.assertItemCount(2);
testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemText(1, TODO_ITEM_THREE);
}); testOps.assertItemText(0, TODO_ITEM_ONE);
});
test.it('should allow me to display completed items', function () {
createStandardItems(); test.it('should allow me to display completed items', function () {
page.toggleItemAtIndex(1); createStandardItems();
page.filterByCompletedItems(); page.toggleItemAtIndex(1);
page.filterByCompletedItems();
testOps.assertItemCount(1);
testOps.assertItemText(0, TODO_ITEM_TWO); testOps.assertItemCount(1);
}); testOps.assertItemText(0, TODO_ITEM_TWO);
});
test.it('should allow me to display all items', function () {
createStandardItems(); test.it('should allow me to display all items', function () {
page.toggleItemAtIndex(1); createStandardItems();
page.toggleItemAtIndex(1);
// apply the other filters first, before returning to the 'all' state
page.filterByActiveItems(); // apply the other filters first, before returning to the 'all' state
page.filterByCompletedItems(); page.filterByActiveItems();
page.filterByAllItems(); page.filterByCompletedItems();
page.filterByAllItems();
testOps.assertItemCount(3);
testOps.assertItemText(0, TODO_ITEM_ONE); testOps.assertItemCount(3);
testOps.assertItemText(1, TODO_ITEM_TWO); testOps.assertItemText(0, TODO_ITEM_ONE);
testOps.assertItemText(2, TODO_ITEM_THREE); testOps.assertItemText(1, TODO_ITEM_TWO);
}); testOps.assertItemText(2, TODO_ITEM_THREE);
});
test.it('should highlight the currently applied filter', function() {
createStandardItems(); test.it('should highlight the currently applied filter', function () {
createStandardItems();
// initially 'all' should be selected
testOps.assertFilterAtIndexIsSelected(0); // initially 'all' should be selected
testOps.assertFilterAtIndexIsSelected(0);
page.filterByActiveItems();
testOps.assertFilterAtIndexIsSelected(1); page.filterByActiveItems();
testOps.assertFilterAtIndexIsSelected(1);
page.filterByCompletedItems();
testOps.assertFilterAtIndexIsSelected(2); page.filterByCompletedItems();
}); testOps.assertFilterAtIndexIsSelected(2);
}); });
}); });
} });
};
var assert = require("assert"); 'use strict';
var assert = require('assert');
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
// element exists. The standard approach is to obtain an array of elements // element exists. The standard approach is to obtain an array of elements
// and test that the length is zero. In this case the item is hidden if // and test that the length is zero. In this case the item is hidden if
// it is either not in the DOM, or is in the DOM but not visible. // it is either not in the DOM, or is in the DOM but not visible.
function testIsHidden(elements) { function testIsHidden(elements) {
if (elements.length === 1) { if (elements.length === 1) {
elements[0].isDisplayed().then(function(isDisplayed) { elements[0].isDisplayed().then(function (isDisplayed) {
assert(!isDisplayed); assert(!isDisplayed);
}) });
} }
} }
function testIsVisible(elements) {
assert.equal(1, elements.length); function testIsVisible(elements) {
elements[0].isDisplayed().then(function(isDisplayed) { assert.equal(1, elements.length);
assert(isDisplayed); elements[0].isDisplayed().then(function (isDisplayed) {
}); assert(isDisplayed);
} });
}
this.assertClearCompleteButtonIsHidden = function() {
page.tryGetClearCompleteButton().then(function(element) { this.assertClearCompleteButtonIsHidden = function () {
testIsHidden(element); page.tryGetClearCompleteButton().then(function (element) {
}); testIsHidden(element);
} });
};
this.assertClearCompleteButtonIsVisible = function() {
page.tryGetClearCompleteButton().then(function(element) { this.assertClearCompleteButtonIsVisible = function () {
testIsVisible(element); page.tryGetClearCompleteButton().then(function (element) {
}); testIsVisible(element);
} });
};
this.assertItemCount = function(itemCount) {
page.getItemElements().then(function(toDoItems){ this.assertItemCount = function (itemCount) {
assert.equal(itemCount, toDoItems.length); page.getItemElements().then(function (toDoItems) {
}); assert.equal(itemCount, toDoItems.length);
} });
};
this.assertClearCompleteButtonText = function(buttonText) {
page.tryGetClearCompleteButton().then(function(elements) { this.assertClearCompleteButtonText = function (buttonText) {
var button = elements[0]; page.tryGetClearCompleteButton().then(function (elements) {
button.getText().then(function(text) { var button = elements[0];
assert.equal(buttonText, text); button.getText().then(function (text) {
}); assert.equal(buttonText, text);
}); });
} });
};
this.assertMainSectionIsHidden = function() {
page.tryGetMainSectionElement().then(function(mainSection) { this.assertMainSectionIsHidden = function () {
testIsHidden(mainSection); page.tryGetMainSectionElement().then(function (mainSection) {
}); testIsHidden(mainSection);
} });
};
this.assertFooterIsHidden = function() {
page.tryGetFooterElement().then(function(footer) { this.assertFooterIsHidden = function () {
testIsHidden(footer); page.tryGetFooterElement().then(function (footer) {
}); testIsHidden(footer);
} });
};
this.assertMainSectionIsVisible = function() {
page.tryGetMainSectionElement().then(function(mainSection) { this.assertMainSectionIsVisible = function () {
testIsVisible(mainSection); page.tryGetMainSectionElement().then(function (mainSection) {
}); testIsVisible(mainSection);
} });
};
this.assertItemToggleIsHidden = function() {
page.tryGetToggleForItemAtIndex().then(function(toggleItem) { this.assertItemToggleIsHidden = function () {
testIsHidden(toggleItem); page.tryGetToggleForItemAtIndex().then(function (toggleItem) {
}); testIsHidden(toggleItem);
} });
};
this.assertItemLabelIsHidden = function() {
page.tryGetItemLabelAtIndex().then(function(toggleItem) { this.assertItemLabelIsHidden = function () {
testIsHidden(toggleItem); page.tryGetItemLabelAtIndex().then(function (toggleItem) {
}); testIsHidden(toggleItem);
} });
};
this.assertFooterIsVisible = function() {
page.tryGetFooterElement().then(function(footer) { this.assertFooterIsVisible = function () {
testIsVisible(footer); page.tryGetFooterElement().then(function (footer) {
}); testIsVisible(footer);
} });
};
this.assertItemInputFieldText = function(text) {
page.getItemInputField().getText().then(function(inputFieldText) { this.assertItemInputFieldText = function (text) {
assert.equal(text, inputFieldText); page.getItemInputField().getText().then(function (inputFieldText) {
}); assert.equal(text, inputFieldText);
} });
};
this.assertItemText = function(itemIndex, textToAssert) {
page.getItemLabelAtIndex(itemIndex).getText().then(function(text) { this.assertItemText = function (itemIndex, textToAssert) {
assert.equal(textToAssert, text.trim()); page.getItemLabelAtIndex(itemIndex).getText().then(function (text) {
}); assert.equal(textToAssert, text.trim());
} });
};
this.assertItemCountText = function(textToAssert) {
page.getItemsCountElement().getText().then(function(text) { this.assertItemCountText = function (textToAssert) {
assert.equal(textToAssert, text.trim()); page.getItemsCountElement().getText().then(function (text) {
}); assert.equal(textToAssert, text.trim());
} });
};
// tests for the presence of the 'completed' CSS class for the item at the given index
this.assertItemAtIndexIsCompleted = function(index) { // tests for the presence of the 'completed' CSS class for the item at the given index
page.getItemElements().then(function(toDoItems) { this.assertItemAtIndexIsCompleted = function (index) {
toDoItems[index].getAttribute("class").then(function(cssClass) { page.getItemElements().then(function (toDoItems) {
assert(cssClass.indexOf("completed") !== -1); toDoItems[index].getAttribute('class').then(function (cssClass) {
}); assert(cssClass.indexOf('completed') !== -1);
}); });
} });
};
this.assertItemAtIndexIsNotCompleted = function(index) {
page.getItemElements().then(function(toDoItems) { this.assertItemAtIndexIsNotCompleted = function (index) {
toDoItems[index].getAttribute("class").then(function(cssClass) { page.getItemElements().then(function (toDoItems) {
// the maria implementation uses an 'incompleted' CSS class which is redundant toDoItems[index].getAttribute('class').then(function (cssClass) {
// TODO: this should really be moved into the pageLaxMode // the maria implementation uses an 'incompleted' CSS class which is redundant
assert(cssClass.indexOf("completed") === -1 || cssClass.indexOf("incompleted") !== -1); // TODO: this should really be moved into the pageLaxMode
}); assert(cssClass.indexOf('completed') === -1 || cssClass.indexOf('incompleted') !== -1);
}); });
} });
};
function isSelected(cssClass) {
return cssClass.indexOf("selected") !== -1; function isSelected(cssClass) {
} return cssClass.indexOf('selected') !== -1;
}
this.assertFilterAtIndexIsSelected = function(index) {
page.getFilterElements().then(function(filterElements) { this.assertFilterAtIndexIsSelected = function (index) {
filterElements[0].getAttribute("class").then(function(cssClass) { page.getFilterElements().then(function (filterElements) {
assert(index == 0 ? isSelected(cssClass) : !isSelected(cssClass)); filterElements[0].getAttribute('class').then(function (cssClass) {
}); assert(index === 0 ? isSelected(cssClass) : !isSelected(cssClass));
});
filterElements[1].getAttribute("class").then(function(cssClass) {
assert(index == 1 ? isSelected(cssClass) : !isSelected(cssClass)); filterElements[1].getAttribute('class').then(function (cssClass) {
}); assert(index === 1 ? isSelected(cssClass) : !isSelected(cssClass));
});
filterElements[2].getAttribute("class").then(function(cssClass) {
assert(index == 2 ? isSelected(cssClass) : !isSelected(cssClass)); filterElements[2].getAttribute('class').then(function (cssClass) {
}); assert(index === 2 ? isSelected(cssClass) : !isSelected(cssClass));
}); });
} });
};
this.assertCompleteAllIsClear = function() {
page.getMarkAllCompletedCheckBox().then(function(markAllCompleted) { this.assertCompleteAllIsClear = function () {
markAllCompleted.isSelected().then(function(isSelected){ page.getMarkAllCompletedCheckBox().then(function (markAllCompleted) {
assert(!isSelected); markAllCompleted.isSelected().then(function (isSelected) {
}) assert(!isSelected);
}); });
} });
};
this.assertCompleteAllIsChecked = function() {
page.getMarkAllCompletedCheckBox().then(function(markAllCompleted) { this.assertCompleteAllIsChecked = function () {
markAllCompleted.isSelected().then(function(isSelected){ page.getMarkAllCompletedCheckBox().then(function (markAllCompleted) {
assert(isSelected); markAllCompleted.isSelected().then(function (isSelected) {
}) assert(isSelected);
}); });
} });
};
} }
module.exports = TestOperations; module.exports = TestOperations;
\ No newline at end of file
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