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) {
grunt.loadNpmTasks('grunt-simple-mocha');
'use strict';
grunt.loadNpmTasks('grunt-simple-mocha');
var gruntConfig = {
simplemocha: {
options: {
reporter: 'mocha-known-issues-reporter'
},
files: {
src: 'allTests.js'
}
}
};
grunt.initConfig(gruntConfig);
grunt.initConfig({
simplemocha: {
options: {
reporter: 'mocha-known-issues-reporter'
},
files: {
src: 'allTests.js'
}
}
});
// build tasks
grunt.registerTask('test', ['simplemocha']);
// build tasks
grunt.registerTask('test', ['simplemocha']);
};
var testSuite = require('./test.js'),
fs = require('fs'),
argv = require('optimist').default('laxMode', false).argv,
rootUrl = "http://localhost:8000/",
frameworkNamePattern = /^[a-z-_]+$/;
'use strict';
// collect together the framework names from each of the subfolders
var list = fs.readdirSync("../architecture-examples/")
.map(function(folderName) { return { name : folderName, path : "architecture-examples/" + folderName} });
list = list.concat(fs.readdirSync("../labs/architecture-examples/")
.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} }));
var testSuite = require('./test.js');
var fs = require('fs');
var argv = require('optimist').default('laxMode', false).argv;
var rootUrl = 'http://localhost:8000/';
var frameworkNamePattern = /^[a-z-_]+$/;
list = list.concat(fs.readdirSync("../dependency-examples/")
.map(function(folderName) { return { name : folderName, path: "dependency-examples/" + folderName} }));
// collect together the framework names from each of the subfolders
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
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});
return exception.length > 0 ? exception[0] : framework;
list = list.map(function (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)
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 (argv.framework) {
list = list.filter(function(framework) { return framework.name === argv.framework});
if (argv.framework) {
list = list.filter(function (framework) {
return framework.name === argv.framework;
});
}
// run the tests for each framework
var testIndex = 1;
list.forEach(function(framework) {
testSuite.todoMVCTest(framework.name,
rootUrl + framework.path + "/index.html", argv.speedMode, argv.laxMode);
list.forEach(function (framework) {
testSuite.todoMVCTest(
framework.name,
rootUrl + framework.path + '/index.html', argv.speedMode,
argv.laxMode
);
});
module.exports = [
// the following are covered by the following issue:
// https://github.com/tastejs/todomvc/issues/789
"TodoMVC - agilityjs, Editing, should cancel edits on escape",
"TodoMVC - angularjs-perf, Editing, should cancel edits on escape",
"TodoMVC - closure, Editing, should cancel edits on escape",
"TodoMVC - jquery, Editing, should cancel edits on escape",
"TodoMVC - knockback, Editing, should cancel edits on escape",
"TodoMVC - spine, Editing, should cancel edits on escape",
"TodoMVC - yui, Editing, should cancel edits on escape",
// the following are covered by the following issue:
// https://github.com/tastejs/todomvc/issues/789
'TodoMVC - agilityjs, Editing, should cancel edits on escape',
'TodoMVC - angularjs-perf, Editing, should cancel edits on escape',
'TodoMVC - closure, Editing, should cancel edits on escape',
'TodoMVC - jquery, Editing, should cancel edits on escape',
'TodoMVC - knockback, Editing, should cancel edits on escape',
'TodoMVC - spine, Editing, should cancel edits on escape',
'TodoMVC - yui, Editing, should cancel edits on escape',
// all the following are covered by this issue:
// https://github.com/tastejs/todomvc/issues/790
// 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 completed items",
"TodoMVC - backbone, Routing, should allow me to display active 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 completed items",
"TodoMVC - dojo, Routing, should allow me to display active items",
"TodoMVC - dojo, Routing, should allow me to display completed items",
// all the following are covered by this issue:
// https://github.com/tastejs/todomvc/issues/790
// 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 completed items',
'TodoMVC - backbone, Routing, should allow me to display active 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 completed items',
'TodoMVC - dojo, Routing, should allow me to display active items',
'TodoMVC - dojo, Routing, should allow me to display completed items',
// the following are covered by this issue:
// 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 - angularjs-perf, Mark all as completed, complete all checkbox should update state when items are completed / cleared",
// the following are covered by this issue:
// 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 - angularjs-perf, Mark all as completed, complete all checkbox should update state when items are completed / cleared',
// 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 completed items",
"TodoMVC - jquery, Routing, should allow me to display all items",
"TodoMVC - jquery, Routing, should highlight the currently applied filter",
// 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 completed items',
'TodoMVC - jquery, Routing, should allow me to display all items',
'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
// just fine. Perhaps there is something asynchronous going on that is causing the assert
// to be executed early?
"TodoMVC - knockoutjs, Persistence, should persist its data",
// 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
// to be executed early?
'TodoMVC - knockoutjs, Persistence, should persist its data',
// ----------------- Unsupported implementations!! -----------
// ----------------- Unsupported implementations!! -----------
// the following are TodoMVC implementations that are not supported by the autoated UI
// tests, and as a result have numerous failures.
// the following are TodoMVC implementations that are not supported by the autoated UI
// tests, and as a result have numerous failures.
// polymer - does not follow the HTML spec
"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 trim text input",
"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 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, 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 edit an item",
"TodoMVC - polymer, Editing, should hide other controls when editing",
"TodoMVC - polymer, Editing, should save edits on enter",
"TodoMVC - polymer, Editing, should save edits on blur",
"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 cancel edits on escape",
"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 remove completed items when clicked",
"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, 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 all items",
"TodoMVC - polymer, Routing, should highlight the currently applied filter",
// polymer - does not follow the HTML spec
'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 trim text input',
'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 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, 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 edit an item',
'TodoMVC - polymer, Editing, should hide other controls when editing',
'TodoMVC - polymer, Editing, should save edits on enter',
'TodoMVC - polymer, Editing, should save edits on blur',
'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 cancel edits on escape',
'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 remove completed items when clicked',
'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, 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 all items',
'TodoMVC - polymer, Routing, should highlight the currently applied filter',
// 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 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 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, 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 edit an item",
"TodoMVC - gwt, Editing, should hide other controls when editing",
"TodoMVC - gwt, Editing, should save edits on enter",
"TodoMVC - gwt, Editing, should save edits on blur",
"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 cancel edits on escape",
"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 be hidden when there are no items that are completed",
"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 completed items",
"TodoMVC - gwt, Routing, should allow me to display all items",
"TodoMVC - gwt, Routing, should highlight the currently applied filter",
];
\ No newline at end of file
// 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 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 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, 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 edit an item',
'TodoMVC - gwt, Editing, should hide other controls when editing',
'TodoMVC - gwt, Editing, should save edits on enter',
'TodoMVC - gwt, Editing, should save edits on blur',
'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 cancel edits on escape',
'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 be hidden when there are no items that are completed',
'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 completed items',
'TodoMVC - gwt, Routing, should allow me to display all items',
'TodoMVC - gwt, Routing, should highlight the currently applied filter',
];
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) {
// 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
// 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
// elements which *might* be present in the DOM, hence the try/get name.
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.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.tryGetItemLabelAtIndex = function(index) {
return browser.findElements(webdriver.By.xpath(this.xPathForItemAtIndex(index) + "//label"));
}
// ----------------- DOM element access methods
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.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.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.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"));
}
// ----------------- page actions
this.clickMarkAllCompletedCheckBox = function() {
return this.getMarkAllCompletedCheckBox().then(function(checkbox){
checkbox.click();
});
}
this.clickClearCompleteButton = function() {
return this.tryGetClearCompleteButton().then(function(elements) {
var button = elements[0];
button.click();
});
}
this.enterItem = function(itemText) {
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];
toggleElement.click();
});
}
this.editItemAtIndex = function(index, itemText) {
return this.getEditInputForItemAtIndex(index)
.then(function(itemEditField) {
// send 50 delete keypresses, just to be sure the item text is deleted
var deleteKeyPresses = "";
for (var i=0;i<50;i++) {
deleteKeyPresses += webdriver.Key.BACK_SPACE
}
itemEditField.sendKeys(deleteKeyPresses);
// 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
// see: 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.filterByCompletedItems = function(index) {
return this.getFilterElements().then(function(filters) {
filters[2].click();
});
}
this.filterByAllItems = function(index) {
return this.getFilterElements().then(function(filters) {
filters[0].click();
});
}
}
module.exports = Page;
\ No newline at end of file
// ----------------- utility methods
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
// 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
// elements which *might* be present in the DOM, hence the try/get name.
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.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.tryGetItemLabelAtIndex = function (index) {
return browser.findElements(webdriver.By.xpath(this.xPathForItemAtIndex(index) + '//label'));
};
// ----------------- DOM element access methods
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.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.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.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'));
};
// ----------------- page actions
this.clickMarkAllCompletedCheckBox = function () {
return this.getMarkAllCompletedCheckBox().then(function (checkbox) {
checkbox.click();
});
};
this.clickClearCompleteButton = function () {
return this.tryGetClearCompleteButton().then(function (elements) {
var button = elements[0];
button.click();
});
};
this.enterItem = function (itemText) {
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];
toggleElement.click();
});
};
this.editItemAtIndex = function (index, itemText) {
return this.getEditInputForItemAtIndex(index)
.then(function (itemEditField) {
// send 50 delete keypresses, just to be sure the item text is deleted
var deleteKeyPresses = '';
for (var i = 0; i < 50; i++) {
deleteKeyPresses += webdriver.Key.BACK_SPACE;
}
itemEditField.sendKeys(deleteKeyPresses);
// 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 see:
// 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 () {
return this.getFilterElements().then(function (filters) {
filters[1].click();
});
};
this.filterByCompletedItems = function () {
return this.getFilterElements().then(function (filters) {
filters[2].click();
});
};
this.filterByAllItems = function () {
return this.getFilterElements().then(function (filters) {
filters[0].click();
});
};
};
var webdriver = require('selenium-webdriver'),
Page = require("./page");
'use strict';
function PageLaxMode(browser) {
Page.apply(this, [browser]);
var webdriver = require('selenium-webdriver');
var Page = require('./page');
this.tryGetToggleForItemAtIndex = function(index) {
// the specification dictates that the checkbox should have the 'toggle' CSS class. Some implementations deviate from
// 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));
}
module.exports = function PageLaxMode(browser) {
Page.apply(this, [browser]);
this.getEditInputForItemAtIndex = function(index) {
// the specification dictates that the input element that allows the user to edit a todo item should have a CSS
// class of 'edit'. In lax mode, we also look for an input of type 'text'.
this.tryGetToggleForItemAtIndex = function (index) {
// the specification dictates that the checkbox should have the 'toggle' CSS class. Some implementations deviate from
// 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.xPathForItemAtIndex(index) + "//input[contains(@class,'edit')]" + ")";
return browser.findElement(webdriver.By.xpath(xpath));
}
}
this.getEditInputForItemAtIndex = function (index) {
// the specification dictates that the input element that allows the user to edit a todo item should have a CSS
// class of 'edit'. In lax mode, we also look for an input of type 'text'.
module.exports = PageLaxMode;
\ No newline at end of file
var xpath = '(' + this.xPathForItemAtIndex(index) + '//input[@type="text"]' + '|' +
this.xPathForItemAtIndex(index) + '//input[contains(@class,"edit")]' + ')';
return browser.findElement(webdriver.By.xpath(xpath));
};
};
var webdriver = require('selenium-webdriver'),
test = require('selenium-webdriver/testing'),
assert = require("assert"),
Page = require("./page"),
PageLaxMode = require("./pageLaxMode"),
TestOperations = require("./testOperations");
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);
});
});
});
}
'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);
});
});
});
};
var assert = require("assert");
'use strict';
var assert = require('assert');
function TestOperations(page) {
// unfortunately webdriver does not have a decent API for determining if an
// 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
// it is either not in the DOM, or is in the DOM but not visible.
function testIsHidden(elements) {
if (elements.length === 1) {
elements[0].isDisplayed().then(function(isDisplayed) {
assert(!isDisplayed);
})
}
}
function testIsVisible(elements) {
assert.equal(1, elements.length);
elements[0].isDisplayed().then(function(isDisplayed) {
assert(isDisplayed);
});
}
this.assertClearCompleteButtonIsHidden = function() {
page.tryGetClearCompleteButton().then(function(element) {
testIsHidden(element);
});
}
this.assertClearCompleteButtonIsVisible = function() {
page.tryGetClearCompleteButton().then(function(element) {
testIsVisible(element);
});
}
this.assertItemCount = function(itemCount) {
page.getItemElements().then(function(toDoItems){
assert.equal(itemCount, toDoItems.length);
});
}
this.assertClearCompleteButtonText = function(buttonText) {
page.tryGetClearCompleteButton().then(function(elements) {
var button = elements[0];
button.getText().then(function(text) {
assert.equal(buttonText, text);
});
});
}
this.assertMainSectionIsHidden = function() {
page.tryGetMainSectionElement().then(function(mainSection) {
testIsHidden(mainSection);
});
}
this.assertFooterIsHidden = function() {
page.tryGetFooterElement().then(function(footer) {
testIsHidden(footer);
});
}
this.assertMainSectionIsVisible = function() {
page.tryGetMainSectionElement().then(function(mainSection) {
testIsVisible(mainSection);
});
}
this.assertItemToggleIsHidden = function() {
page.tryGetToggleForItemAtIndex().then(function(toggleItem) {
testIsHidden(toggleItem);
});
}
this.assertItemLabelIsHidden = function() {
page.tryGetItemLabelAtIndex().then(function(toggleItem) {
testIsHidden(toggleItem);
});
}
this.assertFooterIsVisible = function() {
page.tryGetFooterElement().then(function(footer) {
testIsVisible(footer);
});
}
this.assertItemInputFieldText = function(text) {
page.getItemInputField().getText().then(function(inputFieldText) {
assert.equal(text, inputFieldText);
});
}
this.assertItemText = function(itemIndex, textToAssert) {
page.getItemLabelAtIndex(itemIndex).getText().then(function(text) {
assert.equal(textToAssert, text.trim());
});
}
this.assertItemCountText = function(textToAssert) {
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) {
page.getItemElements().then(function(toDoItems) {
toDoItems[index].getAttribute("class").then(function(cssClass) {
assert(cssClass.indexOf("completed") !== -1);
});
});
}
this.assertItemAtIndexIsNotCompleted = function(index) {
page.getItemElements().then(function(toDoItems) {
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);
});
});
}
function isSelected(cssClass) {
return cssClass.indexOf("selected") !== -1;
}
this.assertFilterAtIndexIsSelected = function(index) {
page.getFilterElements().then(function(filterElements) {
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[2].getAttribute("class").then(function(cssClass) {
assert(index == 2 ? isSelected(cssClass) : !isSelected(cssClass));
});
});
}
this.assertCompleteAllIsClear = function() {
page.getMarkAllCompletedCheckBox().then(function(markAllCompleted) {
markAllCompleted.isSelected().then(function(isSelected){
assert(!isSelected);
})
});
}
this.assertCompleteAllIsChecked = function() {
page.getMarkAllCompletedCheckBox().then(function(markAllCompleted) {
markAllCompleted.isSelected().then(function(isSelected){
assert(isSelected);
})
});
}
// unfortunately webdriver does not have a decent API for determining if an
// 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
// it is either not in the DOM, or is in the DOM but not visible.
function testIsHidden(elements) {
if (elements.length === 1) {
elements[0].isDisplayed().then(function (isDisplayed) {
assert(!isDisplayed);
});
}
}
function testIsVisible(elements) {
assert.equal(1, elements.length);
elements[0].isDisplayed().then(function (isDisplayed) {
assert(isDisplayed);
});
}
this.assertClearCompleteButtonIsHidden = function () {
page.tryGetClearCompleteButton().then(function (element) {
testIsHidden(element);
});
};
this.assertClearCompleteButtonIsVisible = function () {
page.tryGetClearCompleteButton().then(function (element) {
testIsVisible(element);
});
};
this.assertItemCount = function (itemCount) {
page.getItemElements().then(function (toDoItems) {
assert.equal(itemCount, toDoItems.length);
});
};
this.assertClearCompleteButtonText = function (buttonText) {
page.tryGetClearCompleteButton().then(function (elements) {
var button = elements[0];
button.getText().then(function (text) {
assert.equal(buttonText, text);
});
});
};
this.assertMainSectionIsHidden = function () {
page.tryGetMainSectionElement().then(function (mainSection) {
testIsHidden(mainSection);
});
};
this.assertFooterIsHidden = function () {
page.tryGetFooterElement().then(function (footer) {
testIsHidden(footer);
});
};
this.assertMainSectionIsVisible = function () {
page.tryGetMainSectionElement().then(function (mainSection) {
testIsVisible(mainSection);
});
};
this.assertItemToggleIsHidden = function () {
page.tryGetToggleForItemAtIndex().then(function (toggleItem) {
testIsHidden(toggleItem);
});
};
this.assertItemLabelIsHidden = function () {
page.tryGetItemLabelAtIndex().then(function (toggleItem) {
testIsHidden(toggleItem);
});
};
this.assertFooterIsVisible = function () {
page.tryGetFooterElement().then(function (footer) {
testIsVisible(footer);
});
};
this.assertItemInputFieldText = function (text) {
page.getItemInputField().getText().then(function (inputFieldText) {
assert.equal(text, inputFieldText);
});
};
this.assertItemText = function (itemIndex, textToAssert) {
page.getItemLabelAtIndex(itemIndex).getText().then(function (text) {
assert.equal(textToAssert, text.trim());
});
};
this.assertItemCountText = function (textToAssert) {
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) {
page.getItemElements().then(function (toDoItems) {
toDoItems[index].getAttribute('class').then(function (cssClass) {
assert(cssClass.indexOf('completed') !== -1);
});
});
};
this.assertItemAtIndexIsNotCompleted = function (index) {
page.getItemElements().then(function (toDoItems) {
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);
});
});
};
function isSelected(cssClass) {
return cssClass.indexOf('selected') !== -1;
}
this.assertFilterAtIndexIsSelected = function (index) {
page.getFilterElements().then(function (filterElements) {
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[2].getAttribute('class').then(function (cssClass) {
assert(index === 2 ? isSelected(cssClass) : !isSelected(cssClass));
});
});
};
this.assertCompleteAllIsClear = function () {
page.getMarkAllCompletedCheckBox().then(function (markAllCompleted) {
markAllCompleted.isSelected().then(function (isSelected) {
assert(!isSelected);
});
});
};
this.assertCompleteAllIsChecked = function () {
page.getMarkAllCompletedCheckBox().then(function (markAllCompleted) {
markAllCompleted.isSelected().then(function (isSelected) {
assert(isSelected);
});
});
};
}
module.exports = TestOperations;
\ No newline at end of file
module.exports = TestOperations;
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