Add inferno in todoapp benchmark
This commit is contained in:
parent
02e7b40c07
commit
d571dd2e56
26 changed files with 8148 additions and 5 deletions
269
bench/implementations/inferno/test/page.js
Normal file
269
bench/implementations/inferno/test/page.js
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
'use strict';
|
||||
|
||||
var webdriver = require('selenium-webdriver');
|
||||
var until = require('selenium-webdriver/lib/until');
|
||||
|
||||
var idSelectors = true;
|
||||
var classOrId = idSelectors ? '#' : '.';
|
||||
|
||||
var DEFAULT_TIMEOUT = 3000;
|
||||
var REMOVED_TIMEOUT = 100;
|
||||
|
||||
var REMOVE_TEXT_KEY_SEQ = Array(51).join(webdriver.Key.BACK_SPACE + webdriver.Key.DELETE);
|
||||
|
||||
// Unique symbols
|
||||
var ELEMENT_MISSING = Object.freeze({});
|
||||
var ITEM_HIDDEN_OR_REMOVED = Object.freeze({});
|
||||
|
||||
module.exports = function Page(browser) {
|
||||
// CSS ELEMENT SELECTORS
|
||||
|
||||
this.getMainSectionCss = function () { return classOrId + 'main'; };
|
||||
|
||||
this.getFooterSectionCss = function () { return 'footer' + classOrId + 'footer'; };
|
||||
|
||||
this.getClearCompletedButtonCss = function () { return 'button' + classOrId + 'clear-completed'; };
|
||||
|
||||
this.getNewInputCss = function () { return 'input' + classOrId + 'new-todo'; };
|
||||
|
||||
this.getToggleAllCss = function () { return 'input' + classOrId + 'toggle-all'; };
|
||||
|
||||
this.getItemCountCss = function () { return 'span' + classOrId + 'todo-count'; };
|
||||
|
||||
this.getFilterCss = function (index) {
|
||||
return classOrId + 'filters li:nth-of-type(' + (index + 1) + ') a, ' +
|
||||
classOrId + 'filters a:nth-of-type(' + (index + 1) + ')';
|
||||
};
|
||||
|
||||
this.getSelectedFilterCss = function (index) { return this.getFilterCss(index) + '.selected'; };
|
||||
|
||||
this.getFilterAllCss = function () { return this.getFilterCss(0); };
|
||||
|
||||
this.getFilterActiveCss = function () { return this.getFilterCss(1); };
|
||||
|
||||
this.getFilterCompletedCss = function () { return this.getFilterCss(2); };
|
||||
|
||||
this.getListCss = function (suffixCss) { return 'ul' + classOrId + 'todo-list' + (suffixCss || ''); };
|
||||
|
||||
this.getListItemCss = function (index, suffixCss, excludeParentSelector) {
|
||||
suffixCss = (index === undefined ? '' : ':nth-of-type(' + (index + 1) + ')') + (suffixCss || '');
|
||||
return excludeParentSelector ? 'li' + suffixCss : this.getListCss(' li' + suffixCss);
|
||||
};
|
||||
|
||||
this.getListItemToggleCss = function (index) { return this.getListItemCss(index, ' input.toggle'); };
|
||||
|
||||
this.getListItemLabelCss = function (index) { return this.getListItemCss(index, ' label'); };
|
||||
|
||||
this.getLastListItemLabelCss = function (index) { return this.getListItemCss(index, ':last-of-type label'); };
|
||||
|
||||
this.getListItemInputCss = function (index) { return this.getListItemCss(index, ' input.edit'); };
|
||||
|
||||
this.getEditingListItemInputCss = function () { return this.getListItemCss(undefined, '.editing input.edit'); };
|
||||
|
||||
// This CSS selector returns the _last_ element of a list that exactly matches the provided list of completed states
|
||||
// It is used as a boolean test of the item states
|
||||
this.getListItemsWithCompletedStatesCss = function (completedStates) {
|
||||
var suffixCss = ' ' + completedStates.map(function (completed, i) {
|
||||
return this.getListItemCss(i, completed ? '.completed' : ':not(.completed)', true);
|
||||
}, this).join(' + ');
|
||||
return this.getListCss(suffixCss);
|
||||
};
|
||||
|
||||
// PUBLIC SYMBOLS
|
||||
|
||||
this.ITEM_HIDDEN_OR_REMOVED = ITEM_HIDDEN_OR_REMOVED;
|
||||
|
||||
// NAVIGATION
|
||||
|
||||
this.back = function () {
|
||||
return browser.navigate().back();
|
||||
};
|
||||
|
||||
// ELEMENT RETREIVAL
|
||||
// wait* methods guarantees to return an element, or throw an exception
|
||||
// get* methods may return nothing at all, or in the case of element lists, an older version of the list
|
||||
|
||||
this.getElements = function (css) {
|
||||
return browser.findElements(webdriver.By.css(css));
|
||||
};
|
||||
|
||||
this.waitForElement = function (css, failMsg, timeout) {
|
||||
return browser.wait(until.elementLocated(webdriver.By.css(css)), timeout || DEFAULT_TIMEOUT, failMsg);
|
||||
};
|
||||
|
||||
this.waitForFocusedElement = function (css, failMsg) {
|
||||
return this.waitForElement(css + ':focus', failMsg);
|
||||
};
|
||||
|
||||
this.waitForBlurredElement = function (css, failMsg) {
|
||||
return this.waitForElement(css + ':not(:focus)', failMsg);
|
||||
};
|
||||
|
||||
this.waitForListItemCount = function (count) {
|
||||
var self = this;
|
||||
return browser.wait(function () {
|
||||
return self.waitForElement(self.getListCss())
|
||||
.then(function (listElement) {
|
||||
return listElement.findElements(webdriver.By.css(self.getListItemCss(undefined, undefined, true)));
|
||||
})
|
||||
.then(function (listItems) {
|
||||
return listItems.length === count;
|
||||
});
|
||||
}, DEFAULT_TIMEOUT, 'Expected item list to contain ' + count + ' item' + (count === 1 ? '' : 's'));
|
||||
};
|
||||
|
||||
this.waitForClearCompleteButton = function () {
|
||||
return this.waitForElement(this.getClearCompletedButtonCss());
|
||||
};
|
||||
|
||||
this.waitForToggleForItem = function (index) {
|
||||
return this.waitForElement(this.getListItemToggleCss(index));
|
||||
};
|
||||
|
||||
this.waitForItemLabel = function (index) {
|
||||
return this.waitForElement(this.getListItemLabelCss(index));
|
||||
};
|
||||
|
||||
this.waitForNewItemInputField = function () {
|
||||
return this.waitForElement(this.getNewInputCss());
|
||||
};
|
||||
|
||||
this.waitForMarkAllCompletedCheckBox = function () {
|
||||
return this.waitForElement(this.getToggleAllCss());
|
||||
};
|
||||
|
||||
this.getListItems = function () {
|
||||
return this.getElements(this.getListItemCss());
|
||||
};
|
||||
|
||||
this.waitForVisibility = function (shouldBeVisible, css, failMsg) {
|
||||
if (shouldBeVisible) {
|
||||
return this.waitForElement(css, failMsg)
|
||||
.then(function (element) {
|
||||
return browser.wait(until.elementIsVisible(element), DEFAULT_TIMEOUT, failMsg);
|
||||
});
|
||||
} else {
|
||||
return this.waitForElement(css, undefined, REMOVED_TIMEOUT)
|
||||
.catch(function () { return ELEMENT_MISSING; })
|
||||
.then(function (elementOrError) {
|
||||
return elementOrError === ELEMENT_MISSING ?
|
||||
ELEMENT_MISSING : // Returning a value will resolve the promise
|
||||
browser.wait(until.elementIsNotVisible(elementOrError), DEFAULT_TIMEOUT, failMsg);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.waitForMainSectionRemovedOrEmpty = function () {
|
||||
return this.waitForElement(this.getMainSectionCss(), undefined, REMOVED_TIMEOUT)
|
||||
.catch(function () { return ELEMENT_MISSING; })
|
||||
.then(function (elementOrError) {
|
||||
return elementOrError === ELEMENT_MISSING ? ELEMENT_MISSING : this.waitForListItemCount(0);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
this.waitForCheckedStatus = function (shouldBeChecked, failMsg, element) {
|
||||
var condition = shouldBeChecked ? 'elementIsSelected' : 'elementIsNotSelected';
|
||||
return browser.wait(until[condition](element), DEFAULT_TIMEOUT, failMsg);
|
||||
};
|
||||
|
||||
this.waitForTextContent = function (text, failMsg, element) {
|
||||
return browser.wait(until.elementTextIs(element, text), DEFAULT_TIMEOUT, failMsg);
|
||||
};
|
||||
|
||||
// PAGE ACTIONS
|
||||
|
||||
this.ensureAppIsVisibleAndLoaded = function () {
|
||||
return this.waitForVisibility(false, this.getFooterSectionCss(), 'Footer is not hidden')
|
||||
.then(this.waitForElement.bind(
|
||||
this, '.new-todo, #new-todo', 'Could not find new todo input field', undefined))
|
||||
.then(function (newTodoElement) {
|
||||
return newTodoElement.getAttribute('id');
|
||||
})
|
||||
.then(function (newTodoElementId) {
|
||||
if (newTodoElementId === 'new-todo') { return; }
|
||||
idSelectors = false;
|
||||
classOrId = idSelectors ? '#' : '.';
|
||||
});
|
||||
};
|
||||
|
||||
this.clickMarkAllCompletedCheckBox = function () {
|
||||
return this.waitForMarkAllCompletedCheckBox().click();
|
||||
};
|
||||
|
||||
this.clickClearCompleteButton = function () {
|
||||
return this.waitForVisibility(true, this.getClearCompletedButtonCss(),
|
||||
'Expected clear completed items button to be visible')
|
||||
.then(function (clearCompleteButton) {
|
||||
clearCompleteButton.click();
|
||||
});
|
||||
};
|
||||
|
||||
this.enterItem = function (itemText) {
|
||||
var self = this;
|
||||
var nItems;
|
||||
return self.getListItems()
|
||||
.then(function (items) {
|
||||
nItems = items.length;
|
||||
})
|
||||
.then(this.waitForNewItemInputField.bind(this))
|
||||
.then(function (newItemInput) {
|
||||
return newItemInput.sendKeys(itemText).then(function () { return newItemInput; });
|
||||
})
|
||||
.then(function (newItemInput) {
|
||||
return browser.wait(function () {
|
||||
// Hit Enter repeatedly until the text goes away
|
||||
return newItemInput.sendKeys(webdriver.Key.ENTER)
|
||||
.then(newItemInput.getAttribute.bind(newItemInput, 'value'))
|
||||
.then(function (newItemInputValue) {
|
||||
return newItemInputValue.length === 0;
|
||||
});
|
||||
}, DEFAULT_TIMEOUT);
|
||||
})
|
||||
.then(function () {
|
||||
return self.waitForElement(self.getLastListItemLabelCss(nItems));
|
||||
})
|
||||
.then(this.waitForTextContent.bind(this, itemText.trim(),
|
||||
'Expected new item label to read ' + itemText.trim()));
|
||||
};
|
||||
|
||||
this.toggleItemAtIndex = function (index) {
|
||||
return this.waitForToggleForItem(index).click();
|
||||
};
|
||||
|
||||
this.editItemAtIndex = function (index, itemText) {
|
||||
return this.waitForElement(this.getListItemInputCss(index))
|
||||
.then(function (itemEditField) {
|
||||
return itemEditField.sendKeys(REMOVE_TEXT_KEY_SEQ, itemText);
|
||||
});
|
||||
};
|
||||
|
||||
this.doubleClickItemAtIndex = function (index) {
|
||||
return this.waitForItemLabel(index).then(function (itemLabel) {
|
||||
// double click is not 'natively' supported, so we need to send the event direct to the element, see:
|
||||
// jscs:disable
|
||||
// http://stackoverflow.com/questions/3982442/selenium-2-webdriver-how-to-double-click-a-table-row-which-opens-a-new-window
|
||||
// jscs:enable
|
||||
return 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.filterBy = function (filterCss) {
|
||||
return this.waitForElement(filterCss)
|
||||
.click()
|
||||
.then(this.waitForElement.bind(this, filterCss + '.selected', undefined, undefined));
|
||||
};
|
||||
|
||||
this.filterByActiveItems = function () {
|
||||
return this.filterBy(this.getFilterActiveCss());
|
||||
};
|
||||
|
||||
this.filterByCompletedItems = function () {
|
||||
return this.filterBy(this.getFilterCompletedCss());
|
||||
};
|
||||
|
||||
this.filterByAllItems = function () {
|
||||
return this.filterBy(this.getFilterAllCss());
|
||||
};
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue