Add inferno in todoapp benchmark

This commit is contained in:
Roman Vishnevskii 2017-04-24 17:10:12 +07:00
commit d571dd2e56
26 changed files with 8148 additions and 5 deletions

View 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());
};
};