@browserstack/testcafe
Version:
Automated browser testing for the modern web development stack.
1,013 lines (994 loc) • 71.9 kB
JavaScript
// NOTE: We should have the capability to initialize scripts with different contexts.
// This is required for iframes without the src attribute because Hammerhead does not
// inject scripts into such iframes. So, we wrap all scripts in initialization functions.
(function () {
function initTestCafeUI(window) {
var document = window.document;
(function (hammerhead, testCafeCore) {
var hammerhead__default = 'default' in hammerhead ? hammerhead['default'] : hammerhead;
var testCafeCore__default = 'default' in testCafeCore ? testCafeCore['default'] : testCafeCore;
var uiRoot = {
uiRoot: null,
element: function () {
if (!this.uiRoot) {
this.uiRoot = document.createElement('div');
hammerhead.shadowUI.getRoot().appendChild(this.uiRoot);
}
return this.uiRoot;
},
hide: function () {
if (!this.uiRoot)
return;
this.uiRoot.style.visibility = 'hidden';
},
show: function () {
if (!this.uiRoot)
return;
this.uiRoot.style.visibility = '';
},
remove: function () {
var shadowRoot = hammerhead.shadowUI.getRoot();
var parent = hammerhead.nativeMethods.nodeParentNodeGetter.call(shadowRoot);
parent.removeChild(shadowRoot);
}
};
//NOTE: we can't manipulate (open/close option list) with a native select element during test running, so we
var shadowUI = hammerhead__default.shadowUI;
var browserUtils = hammerhead__default.utils.browser;
var featureDetection = hammerhead__default.utils.featureDetection;
var nativeMethods = hammerhead__default.nativeMethods;
var eventSimulator = hammerhead__default.eventSandbox.eventSimulator;
var listeners = hammerhead__default.eventSandbox.listeners;
var positionUtils = testCafeCore__default.positionUtils;
var domUtils = testCafeCore__default.domUtils;
var styleUtils = testCafeCore__default.styleUtils;
var eventUtils = testCafeCore__default.eventUtils;
var arrayUtils = testCafeCore__default.arrayUtils;
var OPTION_LIST_CLASS = 'tcOptionList';
var OPTION_GROUP_CLASS = 'tcOptionGroup';
var OPTION_CLASS = 'tcOption';
var DISABLED_CLASS = 'disabled';
var MAX_OPTION_LIST_LENGTH = browserUtils.isIE ? 30 : 20;
var curSelectEl = null;
var optionList = null;
var groups = [];
var options = [];
function onDocumentMouseDown(e) {
//NOTE: only in Mozilla 'mousedown' raises for option
if ((e.target || e.srcElement) !== curSelectEl && !domUtils.containsElement(curSelectEl, e.target) &&
!domUtils.containsElement(optionList, e.target))
collapseOptionList();
}
function onWindowClick(e, dispatched, preventDefault) {
var optionIndex = arrayUtils.indexOf(options, e.target);
if (optionIndex < 0)
return;
preventDefault();
var isDisabled = e.target.className.indexOf(DISABLED_CLASS) > -1;
if (isDisabled && browserUtils.isWebKit)
return;
clickOnOption(optionIndex, isDisabled);
}
function clickOnOption(optionIndex, isOptionDisabled) {
var curSelectIndex = curSelectEl.selectedIndex;
var realOption = curSelectEl.getElementsByTagName('option')[optionIndex];
var clickLeadChanges = !isOptionDisabled && optionIndex !== curSelectIndex;
if (clickLeadChanges && !browserUtils.isIE)
curSelectEl.selectedIndex = optionIndex;
if (!browserUtils.isFirefox && !browserUtils.isIE && clickLeadChanges) {
eventSimulator.input(curSelectEl);
eventSimulator.change(curSelectEl);
}
if (browserUtils.isFirefox || browserUtils.isIE)
eventSimulator.mousedown(browserUtils.isFirefox ? realOption : curSelectEl);
if (!featureDetection.isTouchDevice)
eventSimulator.mouseup(browserUtils.isFirefox ? realOption : curSelectEl);
if ((browserUtils.isFirefox || browserUtils.isIE) && clickLeadChanges) {
if (browserUtils.isIE)
curSelectEl.selectedIndex = optionIndex;
if (!browserUtils.isIE)
eventSimulator.input(curSelectEl);
eventSimulator.change(curSelectEl);
}
if (!featureDetection.isTouchDevice)
eventSimulator.click(browserUtils.isFirefox || browserUtils.isIE ? realOption : curSelectEl);
if (!isOptionDisabled)
collapseOptionList();
}
function createOption(realOption, parent) {
var option = document.createElement('div');
var isOptionDisabled = realOption.disabled || domUtils.getTagName(realOption.parentElement) === 'optgroup' &&
realOption.parentElement.disabled;
// eslint-disable-next-line no-restricted-properties
nativeMethods.nodeTextContentSetter.call(option, realOption.text);
parent.appendChild(option);
shadowUI.addClass(option, OPTION_CLASS);
if (isOptionDisabled) {
shadowUI.addClass(option, DISABLED_CLASS);
styleUtils.set(option, 'color', styleUtils.get(realOption, 'color'));
}
options.push(option);
}
function createGroup(realGroup, parent) {
var group = document.createElement('div');
nativeMethods.nodeTextContentSetter.call(group, realGroup.label || ' ');
parent.appendChild(group);
shadowUI.addClass(group, OPTION_GROUP_CLASS);
if (group.disabled) {
shadowUI.addClass(group, DISABLED_CLASS);
styleUtils.set(group, 'color', styleUtils.get(realGroup, 'color'));
}
createChildren(realGroup.children, group);
groups.push(group);
}
function createChildren(children, parent) {
var childrenLength = domUtils.getChildrenLength(children);
for (var i = 0; i < childrenLength; i++) {
if (domUtils.isOptionElement(children[i]))
createOption(children[i], parent);
else if (domUtils.getTagName(children[i]) === 'optgroup')
createGroup(children[i], parent);
}
}
function expandOptionList(select) {
var selectChildren = select.children;
if (!selectChildren.length)
return;
//NOTE: check is option list expanded
if (curSelectEl) {
var isSelectExpanded = select === curSelectEl;
collapseOptionList();
if (isSelectExpanded)
return;
}
curSelectEl = select;
optionList = document.createElement('div');
uiRoot.element().appendChild(optionList);
shadowUI.addClass(optionList, OPTION_LIST_CLASS);
createChildren(selectChildren, optionList);
listeners.addInternalEventListener(window, ['click'], onWindowClick);
nativeMethods.setTimeout.call(window, function () {
eventUtils.bind(document, 'mousedown', onDocumentMouseDown);
}, 0);
styleUtils.set(optionList, {
position: 'absolute',
fontSize: styleUtils.get(curSelectEl, 'fontSize'),
fontFamily: styleUtils.get(curSelectEl, 'fontFamily'),
minWidth: styleUtils.getWidth(curSelectEl) + 'px',
left: positionUtils.getOffsetPosition(curSelectEl).left + 'px',
height: domUtils.getSelectVisibleChildren(select).length > MAX_OPTION_LIST_LENGTH ?
styleUtils.getOptionHeight(select) * MAX_OPTION_LIST_LENGTH : ''
});
var selectTopPosition = positionUtils.getOffsetPosition(curSelectEl).top;
var optionListHeight = styleUtils.getHeight(optionList);
var optionListTopPosition = selectTopPosition + styleUtils.getHeight(curSelectEl) + 2;
if (optionListTopPosition + optionListHeight > styleUtils.getScrollTop(window) + styleUtils.getHeight(window)) {
var topPositionAboveSelect = selectTopPosition - 3 - optionListHeight;
if (topPositionAboveSelect >= styleUtils.getScrollTop(window))
optionListTopPosition = topPositionAboveSelect;
}
styleUtils.set(optionList, 'top', optionListTopPosition + 'px');
}
function collapseOptionList() {
domUtils.remove(optionList);
eventUtils.unbind(document, 'mousedown', onDocumentMouseDown);
optionList = null;
curSelectEl = null;
options = [];
groups = [];
}
function isOptionListExpanded(select) {
return select ? select === curSelectEl : !!curSelectEl;
}
function getEmulatedChildElement(element) {
var isGroup = domUtils.getTagName(element) === 'optgroup';
var elementIndex = isGroup ? domUtils.getElementIndexInParent(curSelectEl, element) :
domUtils.getElementIndexInParent(curSelectEl, element);
if (!isGroup)
return options[elementIndex];
return groups[elementIndex];
}
function scrollOptionListByChild(child) {
var select = domUtils.getSelectParent(child);
if (!select)
return;
var realSizeValue = styleUtils.getSelectElementSize(select);
var optionHeight = styleUtils.getOptionHeight(select);
var scrollIndent = 0;
var topVisibleIndex = Math.max(styleUtils.getScrollTop(select) / optionHeight, 0);
var bottomVisibleIndex = topVisibleIndex + realSizeValue - 1;
var childIndex = domUtils.getChildVisibleIndex(select, child);
if (childIndex < topVisibleIndex) {
scrollIndent = optionHeight * (topVisibleIndex - childIndex);
styleUtils.setScrollTop(select, Math.max(styleUtils.getScrollTop(select) - scrollIndent, 0));
}
else if (childIndex > bottomVisibleIndex) {
scrollIndent = optionHeight * (childIndex - bottomVisibleIndex);
styleUtils.setScrollTop(select, styleUtils.getScrollTop(select) + scrollIndent);
}
}
function getSelectChildCenter(child) {
var select = domUtils.getSelectParent(child);
if (!select) {
return {
x: 0,
y: 0
};
}
var optionHeight = styleUtils.getOptionHeight(select);
var childRectangle = positionUtils.getElementRectangle(child);
return {
x: Math.round(childRectangle.left + childRectangle.width / 2),
y: Math.round(childRectangle.top + optionHeight / 2)
};
}
function switchOptionsByKeys(element, command) {
var selectSize = styleUtils.getSelectElementSize(element);
var optionListHidden = !styleUtils.hasDimensions(shadowUI.select('.' + OPTION_LIST_CLASS)[0]);
if (/down|up/.test(command) ||
!browserUtils.isIE && (selectSize <= 1 || browserUtils.isFirefox) &&
(optionListHidden || browserUtils.isFirefox) && /left|right/.test(command)) {
var realOptions = element.querySelectorAll('option');
var enabledOptions = [];
for (var i = 0; i < realOptions.length; i++) {
var parent_1 = realOptions[i].parentElement;
if (!realOptions[i].disabled && !(domUtils.getTagName(parent_1) === 'optgroup' && parent_1.disabled))
enabledOptions.push(realOptions[i]);
}
var curSelectedOptionIndex = arrayUtils.indexOf(enabledOptions, realOptions[element.selectedIndex]);
var nextIndex = curSelectedOptionIndex + (/down|right/.test(command) ? 1 : -1);
if (nextIndex >= 0 && nextIndex < enabledOptions.length) {
element.selectedIndex = arrayUtils.indexOf(realOptions, enabledOptions[nextIndex]);
if (!browserUtils.isIE)
eventSimulator.input(element);
eventSimulator.change(element);
}
}
}
function isOptionElementVisible(el) {
var parentSelect = domUtils.getSelectParent(el);
if (!parentSelect)
return true;
var expanded = isOptionListExpanded(parentSelect);
var selectSizeValue = styleUtils.getSelectElementSize(parentSelect);
return expanded || selectSizeValue > 1;
}
var selectElement = /*#__PURE__*/Object.freeze({
__proto__: null,
expandOptionList: expandOptionList,
collapseOptionList: collapseOptionList,
isOptionListExpanded: isOptionListExpanded,
getEmulatedChildElement: getEmulatedChildElement,
scrollOptionListByChild: scrollOptionListByChild,
getSelectChildCenter: getSelectChildCenter,
switchOptionsByKeys: switchOptionsByKeys,
isOptionElementVisible: isOptionElementVisible
});
//Const
var LOADING_TEXT = 'Loading page...';
var BACKGROUND_CLASS = 'modal-background';
var LOADING_TEXT_CLASS = 'loading-text';
var BACKGROUND_OPACITY = 0.7;
var BACKGROUND_OPACITY_WITH_LOADING_TEXT = 0.8;
var LOADING_ICON_CLASS = 'loading-icon';
//Globals
var backgroundDiv = null;
var loadingTextDiv = null;
var loadingIconDiv = null;
var initialized = false;
//Markup
function createBackground() {
var root = uiRoot.element();
backgroundDiv = document.createElement('div');
root.appendChild(backgroundDiv);
hammerhead.shadowUI.addClass(backgroundDiv, BACKGROUND_CLASS);
loadingTextDiv = document.createElement('div');
hammerhead.nativeMethods.nodeTextContentSetter.call(loadingTextDiv, LOADING_TEXT);
root.appendChild(loadingTextDiv);
hammerhead.shadowUI.addClass(loadingTextDiv, LOADING_TEXT_CLASS);
loadingIconDiv = document.createElement('div');
testCafeCore.styleUtils.set(loadingIconDiv, 'visibility', 'hidden');
root.appendChild(loadingIconDiv);
hammerhead.shadowUI.addClass(loadingIconDiv, LOADING_ICON_CLASS);
}
//Behavior
function adjustLoadingTextPos() {
var wHeight = testCafeCore.styleUtils.getHeight(window);
var wWidth = testCafeCore.styleUtils.getWidth(window);
var loadingTextHidden = !testCafeCore.styleUtils.hasDimensions(loadingTextDiv);
if (loadingTextHidden) {
testCafeCore.styleUtils.set(loadingTextDiv, 'visibility', 'hidden');
testCafeCore.styleUtils.set(loadingTextDiv, 'display', 'block');
}
testCafeCore.styleUtils.set(loadingTextDiv, {
left: Math.max((wWidth - testCafeCore.styleUtils.getWidth(loadingTextDiv)) / 2, 0) + 'px',
top: Math.max((wHeight - testCafeCore.styleUtils.getHeight(loadingTextDiv)) / 2, 0) + 'px'
});
if (loadingTextHidden) {
testCafeCore.styleUtils.set(loadingTextDiv, 'display', 'none');
testCafeCore.styleUtils.set(loadingTextDiv, 'visibility', '');
}
}
function initSizeAdjustments() {
var adjust = function () {
var wHeight = testCafeCore.styleUtils.getHeight(window);
var wWidth = testCafeCore.styleUtils.getWidth(window);
testCafeCore.styleUtils.set(backgroundDiv, 'width', wWidth + 'px');
testCafeCore.styleUtils.set(backgroundDiv, 'height', wHeight + 'px');
testCafeCore.styleUtils.set(loadingIconDiv, {
left: Math.round((wWidth - testCafeCore.styleUtils.getWidth(loadingIconDiv)) / 2) + 'px',
top: Math.round((wHeight - testCafeCore.styleUtils.getHeight(loadingIconDiv)) / 2) + 'px'
});
};
adjust();
testCafeCore.eventUtils.bind(window, 'resize', adjust);
}
function init() {
createBackground();
initSizeAdjustments();
adjustLoadingTextPos();
initialized = true;
}
function initAndShowLoadingText() {
var shown = false;
//NOTE: init and show modal background as soon as possible
var initAndShow = function () {
init();
testCafeCore.styleUtils.set(backgroundDiv, 'opacity', BACKGROUND_OPACITY_WITH_LOADING_TEXT);
testCafeCore.styleUtils.set(backgroundDiv, 'display', 'block');
testCafeCore.styleUtils.set(loadingTextDiv, 'display', 'block');
shown = true;
};
var tryShowBeforeReady = function () {
if (!shown) {
if (document.body)
initAndShow();
else
hammerhead.nativeMethods.setTimeout.call(window, tryShowBeforeReady, 0);
}
};
tryShowBeforeReady();
//NOTE: ensure that background was shown on ready
testCafeCore.eventUtils
.documentReady()
.then(function () {
if (!shown)
initAndShow();
});
}
function show(transparent) {
if (!initialized)
init();
testCafeCore.styleUtils.set(backgroundDiv, 'opacity', transparent ? 0 : BACKGROUND_OPACITY);
testCafeCore.styleUtils.set(backgroundDiv, 'display', 'block');
}
function hide() {
if (!initialized)
return;
testCafeCore.styleUtils.set(loadingTextDiv, 'display', 'none');
testCafeCore.styleUtils.set(backgroundDiv, 'display', 'none');
}
function showLoadingIcon() {
testCafeCore.styleUtils.set(loadingIconDiv, 'visibility', 'visible');
}
function hideLoadingIcon() {
testCafeCore.styleUtils.set(loadingIconDiv, 'visibility', 'hidden');
}
var modalBackground = /*#__PURE__*/Object.freeze({
__proto__: null,
initAndShowLoadingText: initAndShowLoadingText,
show: show,
hide: hide,
showLoadingIcon: showLoadingIcon,
hideLoadingIcon: hideLoadingIcon
});
var shadowUI$1 = hammerhead__default.shadowUI;
var styleUtils$1 = testCafeCore__default.styleUtils;
var CONTAINER_CLASS = 'progress-bar';
var VALUE_CLASS = 'value';
var SUCCESS_CLASS = 'success';
var ProgressBar = /** @class */ (function () {
function ProgressBar(containerElement) {
this.containerElement = document.createElement('div');
this.valueElement = document.createElement('div');
containerElement.appendChild(this.containerElement);
this.containerElement.appendChild(this.valueElement);
shadowUI$1.addClass(this.containerElement, CONTAINER_CLASS);
shadowUI$1.addClass(this.valueElement, VALUE_CLASS);
}
ProgressBar.prototype.setValue = function (value) {
value = typeof value !== 'number' ? 0 : Math.min(Math.max(value, 0), 100);
styleUtils$1.set(this.valueElement, 'width', value + '%');
};
ProgressBar.prototype.setSuccess = function (value) {
if (value)
shadowUI$1.addClass(this.containerElement, SUCCESS_CLASS);
else
shadowUI$1.removeClass(this.containerElement, SUCCESS_CLASS);
};
return ProgressBar;
}());
var shadowUI$2 = hammerhead__default.shadowUI;
var nativeMethods$1 = hammerhead__default.nativeMethods;
var eventUtils$1 = testCafeCore__default.eventUtils;
var styleUtils$2 = testCafeCore__default.styleUtils;
var PANEL_CLASS = 'progress-panel';
var TITLE_CLASS = 'title';
var CONTENT_CLASS = 'content';
var UPDATE_INTERVAL = 100;
var ANIMATION_UPDATE_INTERVAL = 10;
var OPENING_DELAY = 300;
var SHOWING_DELAY = 200;
var HIDING_DELAY = 600;
var MIN_SHOWING_TIME = 1000;
var ProgressPanel = /** @class */ (function () {
function ProgressPanel() {
var _this = this;
this.startTime = null;
this.openingTimeout = null;
this.updateInterval = null;
this.animationInterval = null;
this.panelDiv = document.createElement('div');
uiRoot.element().appendChild(this.panelDiv);
this.titleDiv = document.createElement('div');
this.panelDiv.appendChild(this.titleDiv);
this.contentDiv = document.createElement('div');
this.panelDiv.appendChild(this.contentDiv);
shadowUI$2.addClass(this.panelDiv, PANEL_CLASS);
shadowUI$2.addClass(this.titleDiv, TITLE_CLASS);
shadowUI$2.addClass(this.contentDiv, CONTENT_CLASS);
ProgressPanel._showAtWindowCenter(this.panelDiv);
this.progressBar = new ProgressBar(this.contentDiv);
this.disposePanel = function () { return ProgressPanel._showAtWindowCenter(_this.panelDiv); };
}
ProgressPanel._getInvisibleElementProperty = function (element, property) {
var needShowElement = styleUtils$2.get(element, 'display') === 'none';
if (needShowElement)
styleUtils$2.set(element, 'display', 'block');
var value = element[property];
if (needShowElement)
styleUtils$2.set(element, 'display', 'none');
return value;
};
ProgressPanel._showAtWindowCenter = function (element) {
var elementHeight = ProgressPanel._getInvisibleElementProperty(element, 'offsetHeight');
var elementWidth = ProgressPanel._getInvisibleElementProperty(element, 'offsetWidth');
var top = Math.round(styleUtils$2.getHeight(window) / 2 - elementHeight / 2);
var left = Math.round(styleUtils$2.getWidth(window) / 2 - elementWidth / 2);
styleUtils$2.set(element, {
left: left + 'px',
top: top + 'px'
});
};
ProgressPanel.prototype._setCurrentProgress = function () {
var progress = Math.round((Date.now() - this.startTime) / this.maxTimeout * 100);
this.progressBar.setValue(progress);
};
ProgressPanel.prototype._setSuccess = function (value) {
this.progressBar.setSuccess(value);
};
ProgressPanel.prototype._stopAnimation = function () {
nativeMethods$1.clearInterval.call(window, this.animationInterval);
};
ProgressPanel.prototype._animate = function (el, duration, show, complete) {
var _this = this;
var startTime = Date.now();
var startOpacityValue = show ? 0 : 1;
var passedTime = 0;
var progress = 0;
var delta = 0;
if (show) {
styleUtils$2.set(el, 'opacity', startOpacityValue);
styleUtils$2.set(el, 'display', 'block');
}
this._stopAnimation();
this.animationInterval = nativeMethods$1.setInterval.call(window, function () {
passedTime = Date.now() - startTime;
progress = Math.min(passedTime / duration, 1);
delta = 0.5 - Math.cos(progress * Math.PI) / 2;
styleUtils$2.set(el, 'opacity', startOpacityValue + (show ? delta : -delta));
if (progress === 1) {
_this._stopAnimation();
if (complete)
complete();
}
}, ANIMATION_UPDATE_INTERVAL);
};
ProgressPanel.prototype._showPanel = function () {
eventUtils$1.bind(window, 'resize', this.disposePanel);
this._animate(this.panelDiv, SHOWING_DELAY, true);
};
ProgressPanel.prototype._hidePanel = function (force) {
var _this = this;
this.startTime = null;
eventUtils$1.unbind(window, 'resize', this.disposePanel);
this._animate(this.panelDiv, force ? 0 : HIDING_DELAY, false, function () { return styleUtils$2.set(_this.panelDiv, 'display', 'none'); });
};
ProgressPanel.prototype.show = function (text, timeout) {
var _this = this;
this.startTime = Date.now();
this.maxTimeout = timeout;
nativeMethods$1.nodeTextContentSetter.call(this.titleDiv, text);
this._setSuccess(false);
this.openingTimeout = nativeMethods$1.setTimeout.call(window, function () {
_this.openingTimeout = null;
_this._setCurrentProgress();
_this._showPanel();
_this.updateInterval = nativeMethods$1.setInterval.call(window, function () { return _this._setCurrentProgress(); }, UPDATE_INTERVAL);
}, OPENING_DELAY);
};
ProgressPanel.prototype.close = function (success) {
var _this = this;
if (success)
this._setSuccess(true);
if (this.openingTimeout) {
nativeMethods$1.clearTimeout.call(window, this.openingTimeout);
this.openingTimeout = null;
}
if (this.updateInterval) {
nativeMethods$1.clearInterval.call(window, this.updateInterval);
this.updateInterval = null;
}
if (success) {
if (this.startTime && Date.now() - this.startTime < MIN_SHOWING_TIME) {
nativeMethods$1.setTimeout.call(window, function () {
nativeMethods$1.setTimeout.call(window, function () { return _this._hidePanel(false); }, SHOWING_DELAY);
}, UPDATE_INTERVAL);
}
else
nativeMethods$1.setTimeout.call(window, function () { return _this._hidePanel(false); }, SHOWING_DELAY);
}
else
this._hidePanel(true);
};
return ProgressPanel;
}());
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var shadowUI$3 = hammerhead__default.shadowUI;
var nativeMethods$2 = hammerhead__default.nativeMethods;
var styleUtils$3 = testCafeCore__default.styleUtils;
var DETERMINATE_STYLE_CLASS = 'determinate';
var ANIMATION_UPDATE_INTERVAL$1 = 10;
var DeterminateIndicator = /** @class */ (function () {
function DeterminateIndicator(progressBar, firstValue) {
this.progressBar = progressBar;
this.firstValueElement = firstValue;
this.maxTimeout = null;
this.startTime = null;
this.animationInterval = null;
}
DeterminateIndicator.prototype._setCurrentProgress = function () {
var progress = (Date.now() - this.startTime) / this.maxTimeout;
var percent = Math.min(Math.max(progress, 0), 1);
var progressBarWidth = styleUtils$3.getWidth(this.progressBar);
var newWidth = Math.round(progressBarWidth * percent);
styleUtils$3.set(this.firstValueElement, 'width', newWidth + 'px');
};
DeterminateIndicator.prototype.start = function (maxTimeout, startTime) {
var _this = this;
shadowUI$3.addClass(this.progressBar, DETERMINATE_STYLE_CLASS);
this.maxTimeout = maxTimeout;
this.startTime = startTime || Date.now();
this._setCurrentProgress();
this.animationInterval = nativeMethods$2.setInterval.call(window, function () { return _this._setCurrentProgress(); }, ANIMATION_UPDATE_INTERVAL$1);
};
DeterminateIndicator.prototype.stop = function () {
if (this.animationInterval) {
nativeMethods$2.clearInterval.call(window, this.animationInterval);
this.animationInterval = null;
}
};
DeterminateIndicator.prototype.reset = function () {
styleUtils$3.set(this.firstValueElement, 'width', 0);
shadowUI$3.removeClass(this.progressBar, DETERMINATE_STYLE_CLASS);
};
return DeterminateIndicator;
}());
var shadowUI$4 = hammerhead__default.shadowUI;
var nativeMethods$3 = hammerhead__default.nativeMethods;
var styleUtils$4 = testCafeCore__default.styleUtils;
var positionUtils$1 = testCafeCore__default.positionUtils;
var FIRST_VALUE_ANIMATION_OPTIONS = {
time: 2800,
points: [0.815, 0.395],
positionByCompletePercent: {
0: { left: -35, right: 100 },
0.6: { left: 100, right: -90 },
1: { left: 100, right: -90 }
}
};
var SECOND_VALUE_ANIMATION_OPTIONS = {
time: 3000,
points: [0.84, 1],
positionByCompletePercent: {
0: { left: -200, right: 100 },
0.6: { left: 107, right: -8 },
1: { left: 107, right: -8 }
}
};
var SECOND_VALUE_ELEMENT_ANIMATION_DELAY = 1000;
var ANIMATION_UPDATE_INTERVAL$2 = 10;
var ANIMATION_RESTART_INTERVAL = 1950;
var ANIMATION_PERCENTS = {
start: 0,
middle: 0.6,
end: 1
};
var INDETERMINATE_STYLE_CLASS = 'indeterminate';
//Utils
// NOTE: we use Bezier curves to establish a correspondence between
// time and the animation percent. The curve we build by two point.
function getCompletePercent(time, y1, y2) {
return 3 * Math.pow(1 - time, 2) * time * y1 + 3 * (1 - time) * time * time * y2 + time * time * time;
}
function getNewPosition(completePercent, positions) {
var isFirstAnimationPart = completePercent < ANIMATION_PERCENTS.middle;
var startPercent = isFirstAnimationPart ? ANIMATION_PERCENTS.start : ANIMATION_PERCENTS.middle;
var endPercent = isFirstAnimationPart ? ANIMATION_PERCENTS.middle : ANIMATION_PERCENTS.end;
var startPosition = positions[startPercent];
var endPosition = positions[endPercent];
var startPoint = { x: startPercent, y: startPosition.left };
var endPoint = { x: endPercent, y: endPosition.left };
var left = positionUtils$1.getLineYByXCoord(startPoint, endPoint, completePercent);
startPoint = { x: startPercent, y: startPosition.right };
endPoint = { x: endPercent, y: endPosition.right };
var right = positionUtils$1.getLineYByXCoord(startPoint, endPoint, completePercent);
return { left: left, right: right };
}
var IndeterminateIndicator = /** @class */ (function () {
function IndeterminateIndicator(progressBar, firstValue, secondValue) {
this.progressBar = progressBar;
this.firstValue = firstValue;
this.secondValue = secondValue;
this.animationInterval = null;
this.secondValueAnimationInterval = null;
this.secondValueAnimationTimeout = null;
this.restartAnimationTimeout = null;
}
IndeterminateIndicator._updateValueAnimation = function (startTime, valueElement, animationOptions) {
var animationTime = animationOptions.time;
var animationPoints = animationOptions.points;
var positions = animationOptions.positionByCompletePercent;
var currentTime = Date.now() - startTime;
var timePercent = currentTime / animationTime;
var completePercent = getCompletePercent(timePercent, animationPoints[0], animationPoints[1]);
var _a = getNewPosition(completePercent, positions), left = _a.left, right = _a.right;
styleUtils$4.set(valueElement, 'left', Math.round(left) + '%');
styleUtils$4.set(valueElement, 'right', Math.round(right) + '%');
};
IndeterminateIndicator.prototype._clearFirstValueAnimation = function () {
if (this.animationInterval) {
nativeMethods$3.clearInterval.call(window, this.animationInterval);
this.animationInterval = null;
}
styleUtils$4.set(this.firstValue, 'left', '-35%');
styleUtils$4.set(this.firstValue, 'right', '100%');
};
IndeterminateIndicator.prototype._clearSecondValueAnimation = function () {
if (this.secondValueAnimationInterval) {
nativeMethods$3.clearInterval.call(window, this.secondValueAnimationInterval);
this.secondValueAnimationInterval = null;
}
styleUtils$4.set(this.secondValue, 'left', '-200%');
styleUtils$4.set(this.secondValue, 'right', '100%');
};
IndeterminateIndicator.prototype._startFirstValueAnimation = function () {
var _this = this;
this._clearFirstValueAnimation();
var startTime = Date.now();
this.animationInterval = nativeMethods$3.setInterval.call(window, function () {
IndeterminateIndicator._updateValueAnimation(startTime, _this.firstValue, FIRST_VALUE_ANIMATION_OPTIONS);
}, ANIMATION_UPDATE_INTERVAL$2);
};
IndeterminateIndicator.prototype._startSecondValueAnimation = function () {
var _this = this;
this._clearSecondValueAnimation();
var startTime = Date.now();
this.secondValueAnimationInterval = nativeMethods$3.setInterval.call(window, function () {
IndeterminateIndicator._updateValueAnimation(startTime, _this.secondValue, SECOND_VALUE_ANIMATION_OPTIONS);
}, ANIMATION_UPDATE_INTERVAL$2);
};
IndeterminateIndicator.prototype._startAnimation = function () {
var _this = this;
this._startFirstValueAnimation();
this.secondValueAnimationTimeout = nativeMethods$3.setTimeout.call(window, function () { return _this._startSecondValueAnimation(); }, SECOND_VALUE_ELEMENT_ANIMATION_DELAY);
this.restartAnimationTimeout = nativeMethods$3.setTimeout.call(window, function () { return _this._startAnimation(); }, ANIMATION_RESTART_INTERVAL);
};
IndeterminateIndicator.prototype._stopAnimation = function () {
this._clearFirstValueAnimation();
this._clearSecondValueAnimation();
if (this.secondValueAnimationTimeout) {
nativeMethods$3.clearInterval.call(window, this.secondValueAnimationTimeout);
this.secondValueAnimationTimeout = null;
}
if (this.restartAnimationTimeout) {
nativeMethods$3.clearInterval.call(window, this.restartAnimationTimeout);
this.restartAnimationTimeout = null;
}
};
IndeterminateIndicator.prototype.start = function () {
shadowUI$4.addClass(this.progressBar, INDETERMINATE_STYLE_CLASS);
this._startAnimation();
};
IndeterminateIndicator.prototype.stop = function () {
shadowUI$4.removeClass(this.progressBar, INDETERMINATE_STYLE_CLASS);
this._stopAnimation();
};
return IndeterminateIndicator;
}());
var shadowUI$5 = hammerhead__default.shadowUI;
var styleUtils$5 = testCafeCore__default.styleUtils;
var PROGRESS_BAR_CLASS = 'progress-bar';
var CONTAINER_CLASS$1 = 'value-container';
var VALUE_CLASS$1 = 'value';
var ProgressBar$1 = /** @class */ (function () {
function ProgressBar(containerElement) {
this.progressBar = null;
this.firstValueElement = null;
this.secondValueElement = null;
this._create(containerElement);
this.determinateIndicator = new DeterminateIndicator(this.progressBar, this.firstValueElement);
this.indeterminateIndicator = new IndeterminateIndicator(this.progressBar, this.firstValueElement, this.secondValueElement);
}
ProgressBar.prototype._create = function (containerElement) {
this.progressBar = document.createElement('div');
shadowUI$5.addClass(this.progressBar, PROGRESS_BAR_CLASS);
containerElement.appendChild(this.progressBar);
var container = document.createElement('div');
shadowUI$5.addClass(container, CONTAINER_CLASS$1);
this.progressBar.appendChild(container);
this.firstValueElement = document.createElement('div');
shadowUI$5.addClass(this.firstValueElement, VALUE_CLASS$1);
container.appendChild(this.firstValueElement);
this.secondValueElement = document.createElement('div');
shadowUI$5.addClass(this.secondValueElement, VALUE_CLASS$1);
container.appendChild(this.secondValueElement);
};
ProgressBar.prototype.show = function () {
styleUtils$5.set(this.progressBar, 'visibility', 'visible');
};
ProgressBar.prototype.hide = function () {
styleUtils$5.set(this.progressBar, 'visibility', 'hidden');
};
return ProgressBar;
}());
var MESSAGES = {
startWaitingElement: 'start-waiting-element',
endWaitingElementRequest: 'end-waiting-element-request',
endWaitingElementResponse: 'end-waiting-element-response',
startWaitingAssertionRetries: 'start-waiting-assertion-retries',
endWaitingAssertionRetriesRequest: 'end-waiting-assertion-retries-request',
endWaitingAssertionRetriesResponse: 'end-waiting-assertion-retries-response'
};
var Promise = hammerhead__default.Promise;
var shadowUI$6 = hammerhead__default.shadowUI;
var nativeMethods$4 = hammerhead__default.nativeMethods;
var messageSandbox = hammerhead__default.eventSandbox.message;
var browserUtils$1 = hammerhead__default.utils.browser;
var featureDetection$1 = hammerhead__default.utils.featureDetection;
var listeners$1 = hammerhead__default.eventSandbox.listeners;
var styleUtils$6 = testCafeCore__default.styleUtils;
var eventUtils$2 = testCafeCore__default.eventUtils;
var domUtils$1 = testCafeCore__default.domUtils;
var serviceUtils = testCafeCore__default.serviceUtils;
var arrayUtils$1 = testCafeCore__default.arrayUtils;
var STATUS_BAR_CLASS = 'status-bar';
var ICON_CLASS = 'icon';
var INFO_CONTAINER_CLASS = 'info-container';
var INFO_TEXT_CONTAINER_CLASS = 'info-text-container';
var ACTIONS_CONTAINER_CLASS = 'actions-container';
var FIXTURE_DIV_CLASS = 'fixture';
var STATUS_CONTAINER_CLASS = 'status-container';
var INFO_CLASS = 'info';
var STATUS_DIV_CLASS = 'status';
var USER_AGENT_DIV_CLASS = 'user-agent';
var BUTTONS_CLASS = 'buttons';
var BUTTON_CLASS = 'button';
var BUTTON_ICON_CLASS = 'button-icon';
var LOCKED_BUTTON_CLASS = 'locked';
var UNLOCKED_BUTTON_CLASS = 'unlocked';
var RESUME_BUTTON_CLASS = 'resume';
var STEP_BUTTON_CLASS = 'step';
var FINISH_BUTTON_CLASS = 'finish';
var WAITING_FAILED_CLASS = 'waiting-element-failed';
var WAITING_SUCCESS_CLASS = 'waiting-element-success';
var LOADING_PAGE_TEXT = 'Loading Web Page...';
var WAITING_FOR_ELEMENT_TEXT = 'Waiting for element to appear...';
var WAITING_FOR_ASSERTION_EXECUTION_TEXT = 'Waiting for assertion execution...';
var DEBUGGING_TEXT = 'Debugging test...';
var TEST_FAILED_TEXT = 'Test failed';
var UNLOCK_PAGE_TEXT = 'Unlock Page';
var PAGE_UNLOCKED_TEXT = 'Page unlocked';
var SHOWING_DELAY$1 = 300;
var ANIMATION_DELAY = 500;
var ANIMATION_UPDATE_INTERVAL$3 = 10;
var LOCAL_STORAGE_STATUS_PREFIX_ITEM = '%testCafeStatusPrefix%';
var StatusBar = /** @class */ (function (_super) {
__extends(StatusBar, _super);
function StatusBar(userAgent, fixtureName, testName, contextStorage) {
var _this = _super.call(this) || this;
_this.UNLOCK_PAGE_BTN_CLICK = 'testcafe|ui|status-bar|unlock-page-btn-click';
_this.userAgent = userAgent;
_this.fixtureName = fixtureName;
_this.testName = testName;
_this.contextStorage = contextStorage;
_this.statusBar = null;
_this.infoContainer = null;
_this.actionsContainer = null;
_this.icon = null;
_this.resumeButton = null;
_this.finishButton = null;
_this.nextButton = null;
_this.statusDiv = null;
_this.buttons = null;
_this.progressBar = null;
_this.animationInterval = null;
_this.showingTimeout = null;
_this.windowHeight = document.documentElement ? styleUtils$6.getHeight(window) : window.innerHeight;
_this.state = {
created: false,
showing: false,
hiding: false,
debugging: false,
waiting: false,
assertionRetries: false,
hidden: false
};
_this.currentView = null;
_this._createBeforeReady();
_this._initChildListening();
return _this;
}
StatusBar.prototype._createButton = function (text, className) {
var button = document.createElement('div');
var icon = document.createElement('div');
var span = document.createElement('span');
nativeMethods$4.nodeTextContentSetter.call(span, text);
shadowUI$6.addClass(button, BUTTON_CLASS);
shadowUI$6.addClass(button, className);
shadowUI$6.addClass(icon, BUTTON_ICON_CLASS);
if (browserUtils$1.isSafari) {
span.style.position = 'relative';
span.style.top = '1px';
}
button.appendChild(icon);
button.appendChild(span);
return button;
};
StatusBar.prototype._createIconArea = function () {
this.icon = document.createElement('div');
shadowUI$6.addClass(this.icon, ICON_CLASS);
this.statusBar.appendChild(this.icon);
};
StatusBar.prototype._createInformationArea = function () {
this.infoContainer = document.createElement('div');
shadowUI$6.addClass(this.infoContainer, INFO_CONTAINER_CLASS);
this.statusBar.appendChild(this.infoContainer);
var infoTextContainer = document.createElement('div');
shadowUI$6.addClass(infoTextContainer, INFO_TEXT_CONTAINER_CLASS);
this.infoContainer.appendChild(infoTextContainer);
var statusContainer = document.createElement('div');
shadowUI$6.addClass(statusContainer, STATUS_CONTAINER_CLASS);
infoTextContainer.appendChild(statusContainer);
this.statusDiv = document.createElement('div');
this.statusDiv = document.createElement('div');
nativeMethods$4.nodeTextContentSetter.call(this.statusDiv, this._getFullStatusText(LOADING_PAGE_TEXT));
shadowUI$6.addClass(this.statusDiv, STATUS_DIV_CLASS);
shadowUI$6.addClass(this.statusDiv, INFO_CLASS);
statusContainer.appendChild(this.statusDiv);
var fixtureDiv = document.createElement('div');
nativeMethods$4.nodeTextContentSetter.call(fixtureDiv, this.fixtureName + " - " + this.testName);
shadowUI$6.addClass(fixtureDiv, FIXTURE_DIV_CLASS);
shadowUI$6.addClass(fixtureDiv, INFO_CLASS);
statusContainer.appendChild(fixtureDiv);
var userAgentDiv = document.createElement('div');
nativeMethods$4.nodeTextContentSetter.call(userAgentDiv, this.userAgent);
shadowUI$6.addClass(userAgentDiv, USER_AGENT_DIV_CLASS);
infoTextContainer.appendChild(userAgentDiv);
};
StatusBar.prototype._createActionsArea = function () {
var _this = this;
this.actionsContainer = document.createElement('div');
shadowUI$6.addClass(this.actionsContainer, ACTIONS_CONTAINER_CLASS);
this.statusBar.appendChild(this.actionsContainer);
this.buttons = document.createElement('div');
shadowUI$6.addClass(this.buttons, BUTTONS_CLASS);
this.actionsContainer.appendChild(this.buttons);
this.unlockButton = this._createButton(UNLOCK_PAGE_TEXT, LOCKED_BUTTON_CLASS);
this.resumeButton = this._createButton('Resume', RESUME_BUTTON_CLASS);
this.nextButton = this._createButton('Next Action', STEP_BUTTON_CLASS);
this.finishButton = this._createButton('Finish', FINISH_BUTTON_CLASS);
this.buttons.appendChild(this.unlockButton);
this.buttons.appendChild(this.resumeButton);
this.buttons.appendChild(this.nextButton);
this.actionsContainer.style.display = 'none';
this._bindClickOnce([this.unlockButton], function () {
shadowUI$6.removeClass(_this.unlockButton, LOCKED_BUTTON_CLASS);
shadowUI$6.addClass(_this.unlockButton, UNLOCKED_BUTTON_CLASS);
nativeMethods$4.nodeTextContentSetter.call(_this.unlockButton.querySelector('span'), PAGE_UNLOCKED_TEXT);
_this.state.locked = false;
_this.emit(_this.UNLOCK_PAGE_BTN_CLICK, {});
});
this.unlockButton.style.display = 'none';
};
StatusBar.prototype._create = function () {
this.statusBar = document.createElement('div');
shadowUI$6.addClass(this.statusBar, STATUS_BAR_CLASS);
this._createIconArea();
this._createInformationArea();
this._createActionsArea();
this.progressBar = new ProgressBar$1(this.infoContainer);
this.progressBar.indeterminateIndicator.start();
this.progressBar.show();
uiRoot.element().appendChild(this.statusBar);
this._bindHandlers();
this.state.created = true;
};
StatusBar.prototype._createBeforeReady = function () {
var _this = this;
if (this.state.created || window !== window.top)
return;
if (document.body)
this._create();
else
nativeMethods$4.setTimeout.call(window, function () { return _this._createBeforeReady(); }, 0);
};
StatusBar.prototype._animate = function (show) {
var _this = this;
var startTime = Date.now();
var startOpacityValue = parseInt(styleUtils$6.get(this.statusBar, 'opacity'), 10) || 0;
var passedTime = 0;
var progress = 0;
var delta = 0;
this._stopAnimation();
if (show) {
styleUtils$6.set(this.statusBar, 'visibility', '');
this.state.hidden = false;
}
this.animationInterval = nativeMethods$4.setInterval.call(window, function () {
passedTime = Date.now() - startTime;
progress = Math.min(passedTime / ANIMATION_DELAY, 1);
delta = 0.5 - Math.cos(progress * Math.PI) / 2;
styleUtils$6.set(_this.statusBar, 'opacity', startOpacityValue + (show ? delta : -delta));
if (progress === 1) {
_this._stopAnimation();
if (!show) {
styleUtils$6.set(_this.statusBar, 'visibility', 'hidden');
_this.state.hidden = true;
}
_this.state.showing = false;
_this.state.hiding = false;
}
}, ANIMATION_UPDATE_INTERVAL$3);
};
StatusBar.prototype._stopAnimation = function () {
if (this.animationInterval) {
nativeMethods$4.clearInterval.call(window, this.animationInterval);
this.animationInterval = null;
}
};
StatusBar.prototype._fadeOut = function () {
if (this.state.hiding || this.state.debugging)