eyes.selenium.v68patch
Version:
Applitools Eyes SDK For Selenium JavaScript WebDriver
890 lines (798 loc) • 38.1 kB
JavaScript
/*
---
name: Eyes
description: The main type - to be used by the users of the library to access all functionality.
provides: [Eyes]
requires: [eyes.sdk, EyesWebDriver, ViewportSize, selenium-webdriver]
---
*/
(function () {
'use strict';
var promise = require('q'),
webdriver = require('selenium-webdriver'),
EyesSDK = require('eyes.sdk'),
EyesUtils = require('eyes.utils'),
EyesWebDriver = require('./EyesWebDriver'),
EyesSeleniumUtils = require('./EyesSeleniumUtils'),
EyesRemoteWebElement = require('./EyesRemoteWebElement'),
EyesWebDriverScreenshot = require('./EyesWebDriverScreenshot'),
ElementFinderWrapper = require('./ElementFinderWrappers').ElementFinderWrapper,
ElementArrayFinderWrapper = require('./ElementFinderWrappers').ElementArrayFinderWrapper,
ScrollPositionProvider = require('./ScrollPositionProvider'),
CssTranslatePositionProvider = require('./CssTranslatePositionProvider'),
ElementPositionProvider = require('./ElementPositionProvider'),
EyesRegionProvider = require('./EyesRegionProvider'),
Target = require('./Target');
var EyesBase = EyesSDK.EyesBase,
FixedScaleProvider = EyesSDK.FixedScaleProvider,
ContextBasedScaleProviderFactory = EyesSDK.ContextBasedScaleProviderFactory,
FixedScaleProviderFactory = EyesSDK.FixedScaleProviderFactory,
NullScaleProvider = EyesSDK.NullScaleProvider,
Logger = EyesSDK.Logger,
CoordinatesType = EyesSDK.CoordinatesType,
MutableImage = EyesSDK.MutableImage,
ScaleProviderIdentityFactory = EyesSDK.ScaleProviderIdentityFactory,
PromiseFactory = EyesUtils.PromiseFactory,
ArgumentGuard = EyesUtils.ArgumentGuard,
SimplePropertyHandler = EyesUtils.SimplePropertyHandler,
GeometryUtils = EyesUtils.GeometryUtils;
var VERSION = require('../package.json').version;
var DEFAULT_WAIT_BEFORE_SCREENSHOTS = 100, // ms
UNKNOWN_DEVICE_PIXEL_RATIO = 0,
DEFAULT_DEVICE_PIXEL_RATIO = 1;
/**
* @readonly
* @enum {string}
*/
var StitchMode = {
// Uses scrolling to get to the different parts of the page.
Scroll: 'Scroll',
// Uses CSS transitions to get to the different parts of the page.
CSS: 'CSS'
};
/**
* Initializes an Eyes instance.
* @param {String} [serverUrl] - The Eyes server URL.
* @param {Boolean} [isDisabled] - set to true to disable Applitools Eyes and use the webdriver directly.
* @augments EyesBase
* @constructor
**/
function Eyes(serverUrl, isDisabled) {
this._forceFullPage = false;
this._imageRotationDegrees = 0;
this._automaticRotation = true;
this._isLandscape = false;
this._hideScrollbars = null;
this._checkFrameOrElement = false;
this._stitchMode = StitchMode.Scroll;
this._promiseFactory = new PromiseFactory();
this._waitBeforeScreenshots = DEFAULT_WAIT_BEFORE_SCREENSHOTS;
EyesBase.call(this, this._promiseFactory, serverUrl || EyesBase.DEFAULT_EYES_SERVER, isDisabled);
}
Eyes.prototype = new EyesBase();
Eyes.prototype.constructor = Eyes;
//noinspection JSUnusedGlobalSymbols
Eyes.prototype._getBaseAgentId = function () {
return 'eyes.selenium.v68patch/' + VERSION;
};
function _init(that, flow) {
// Set PromiseFactory to work with the protractor control flow and promises
that._promiseFactory.setFactoryMethods(function (asyncAction) {
return flow.execute(function () {
var deferred = promise.defer();
asyncAction(deferred.fulfill, deferred.reject);
return deferred.promise;
});
}, function () {
return promise.defer();
});
}
//noinspection JSUnusedGlobalSymbols
/**
* Starts a test.
* @param {WebDriver} driver - The web driver that controls the browser hosting the application under test.
* @param {string} appName - The name of the application under test.
* @param {string} testName - The test name.
* @param {{width: number, height: number}} viewportSize - The required browser's
* viewport size (i.e., the visible part of the document's body) or to use the current window's viewport.
* @return {Promise<WebDriver>} A wrapped WebDriver which enables Eyes trigger recording and
* frame handling.
*/
Eyes.prototype.open = function (driver, appName, testName, viewportSize) {
var that = this;
if (typeof protractor !== 'undefined') {
that._isProtractorLoaded = true;
that._logger.verbose("Running using Protractor module");
} else {
that._isProtractorLoaded = false;
that._logger.verbose("Running using Selenium module");
}
that._flow = driver.controlFlow();
_init(that, that._flow);
if (this._isDisabled) {
return that._flow.execute(function () {
return driver;
});
}
return that._flow.execute(function () {
return driver.getCapabilities()
.then(function (capabilities) {
var platformName, platformVersion, orientation;
if (capabilities.caps_) {
platformName = capabilities.caps_.platformName;
platformVersion = capabilities.caps_.platformVersion;
orientation = capabilities.caps_.orientation || capabilities.caps_.deviceOrientation;
} else {
platformName = capabilities.get('platform');
platformVersion = capabilities.get('version');
orientation = capabilities.get('orientation') || capabilities.get('deviceOrientation');
}
var majorVersion;
if (!platformVersion || platformVersion.length < 1) {
return;
}
majorVersion = platformVersion.split('.', 2)[0];
if (platformName.toUpperCase() === 'ANDROID') {
// We only automatically set the OS, if the user hadn't manually set it previously.
if (!that.getHostOS()) {
that.setHostOS('Android ' + majorVersion);
}
} else if (platformName.toUpperCase() === 'IOS') {
if (!that.getHostOS()) {
that.setHostOS('iOS ' + majorVersion);
}
} else {
return;
}
if (orientation && orientation.toUpperCase() === 'LANDSCAPE') {
that._isLandscape = true;
}
}).then(function () {
return EyesBase.prototype.open.call(that, appName, testName, viewportSize);
}).then(function () {
that._devicePixelRatio = UNKNOWN_DEVICE_PIXEL_RATIO;
that._driver = new EyesWebDriver(driver, that, that._logger, that._promiseFactory);
// extend protractor element to return ours
if (that._isProtractorLoaded) {
var originalElementFn = global.element;
global.element = function (locator) {
return new ElementFinderWrapper(originalElementFn(locator), that._driver, that._logger);
};
global.element.all = function (locator) {
return new ElementArrayFinderWrapper(originalElementFn.all(locator), that._driver, that._logger);
};
}
that.setStitchMode(that._stitchMode);
return that._driver;
});
});
};
//noinspection JSUnusedGlobalSymbols
/**
* Ends the test.
* @param throwEx - If true, an exception will be thrown for failed/new tests.
* @returns {*} The test results.
*/
Eyes.prototype.close = function (throwEx) {
var that = this;
if (this._isDisabled) {
return that._flow.execute(function () {
});
}
if (throwEx === undefined) {
throwEx = true;
}
return that._flow.execute(function () {
return EyesBase.prototype.close.call(that, throwEx)
.then(function (results) {
return results;
}, function (err) {
throw err;
});
});
};
//noinspection JSUnusedGlobalSymbols
/**
* Preform visual validation
* @param {string} name - A name to be associated with the match
* @param {Target} target - Target instance which describes whether we want a window/region/frame
* @return {ManagedPromise} A promise which is resolved when the validation is finished.
*/
Eyes.prototype.check = function (name, target) {
ArgumentGuard.notNullOrEmpty(name, "Name");
ArgumentGuard.notNull(target, "Target");
var that = this;
var promise = that._promiseFactory.makePromise(function (resolve) {
resolve();
});
if (that._isDisabled) {
that._logger.verbose("match ignored - ", name);
return promise;
}
if (target.getIgnoreObjects().length) {
target.getIgnoreObjects().forEach(function (obj) {
var ignoreObject = obj.element;
if (ignoreObject instanceof EyesRemoteWebElement || ignoreObject instanceof webdriver.WebElement || ignoreObject instanceof webdriver.By) {
promise = promise.then(function () {
// if ignoreObject is 'By' locator we need to findElement first
if (ignoreObject instanceof webdriver.By) {
that._logger.verbose("Trying to find element...", ignoreObject);
return that._driver.findElement(ignoreObject);
}
return ignoreObject;
}).then(function (element) {
return getRegionFromWebElement(element);
}).then(function (region) {
target.ignore(region);
});
} else {
throw new Error("Unsupported ignore region type: " + typeof ignoreObject);
}
});
}
if (target.getFloatingObjects().length) {
target.getFloatingObjects().forEach(function (obj) {
var floatingObject = obj.element;
if (floatingObject instanceof EyesRemoteWebElement || floatingObject instanceof webdriver.WebElement || floatingObject instanceof webdriver.By) {
promise = promise.then(function () {
// if floatingObject is 'By' locator we need to findElement first
if (floatingObject instanceof webdriver.By) {
that._logger.verbose("Trying to find element...", floatingObject);
return that._driver.findElement(floatingObject);
}
return floatingObject;
}).then(function (element) {
return getRegionFromWebElement(element);
}).then(function (region) {
region.maxLeftOffset = obj.maxLeftOffset;
region.maxRightOffset = obj.maxRightOffset;
region.maxUpOffset = obj.maxUpOffset;
region.maxDownOffset = obj.maxDownOffset;
target.floating(region);
});
} else {
throw new Error("Unsupported floating region type: " + typeof floatingObject);
}
});
}
that._logger.verbose("match starting with params", name, target.getStitchContent(), target.getTimeout());
var frameObject, regionObject,
regionProvider,
isFrameSwitched = false, // if we will switch frame then we need to restore parent
originalOverflow, originalPositionProvider, originalHideScrollBars;
// If frame specified
if (target.isUsingFrame()) {
frameObject = target.getFrame();
promise = promise.then(function () {
that._logger.verbose("Switching to frame...");
return that._driver.switchTo().frame(frameObject);
}).then(function () {
isFrameSwitched = true;
that._logger.verbose("Done!");
// if we need to check entire frame, we need to update region provider
if (!target.isUsingRegion()) {
that._checkFrameOrElement = true;
originalHideScrollBars = that._hideScrollbars;
that._hideScrollbars = true;
return getRegionProviderForCurrentFrame(that).then(function (regionProvider) {
that._regionToCheck = regionProvider;
});
}
});
}
// if region specified
if (target.isUsingRegion()) {
regionObject = target.getRegion();
if (regionObject instanceof EyesRemoteWebElement || regionObject instanceof webdriver.WebElement || regionObject instanceof webdriver.By) {
promise = promise.then(function () {
// if regionObject is 'By' locator we need to findElement first
if (regionObject instanceof webdriver.By) {
that._logger.verbose("Trying to find element...", regionObject);
return that._driver.findElement(regionObject);
}
return regionObject;
}).then(function (element) {
regionObject = element;
if (target.getStitchContent()) {
that._checkFrameOrElement = true;
originalPositionProvider = that.getPositionProvider();
that.setPositionProvider(new ElementPositionProvider(that._logger, that._driver, element, that._promiseFactory));
// Set overflow to "hidden".
return element.getOverflow().then(function (value) {
originalOverflow = value;
return element.setOverflow("hidden");
}).then(function () {
return getRegionProviderForElement(that, element);
}).then(function (regionProvider) {
that._regionToCheck = regionProvider;
});
}
return getRegionFromWebElement(element);
}).then(function (region) {
regionProvider = new EyesRegionProvider(that._logger, that._driver, region, CoordinatesType.CONTEXT_RELATIVE);
});
} else if (GeometryUtils.isRegion(regionObject)) {
// if regionObject is simple region
regionProvider = new EyesRegionProvider(that._logger, that._driver, regionObject, CoordinatesType.CONTEXT_AS_IS);
} else {
throw new Error("Unsupported region type: " + typeof regionObject);
}
}
return promise.then(function () {
that._logger.verbose("Call to checkWindowBase...");
var imageMatchSettings = {
matchLevel: target.getMatchLevel(),
ignoreCaret: target.getIgnoreCaret(),
ignore: target.getIgnoreRegions(),
floating: target.getFloatingRegions(),
exact: null
};
return EyesBase.prototype.checkWindow.call(that, name, target.getIgnoreMismatch(), target.getTimeout(), regionProvider, imageMatchSettings);
}).then(function (result) {
that._logger.verbose("Processing results...");
if (result.asExpected || !that._failureReportOverridden) {
return result;
} else {
throw EyesBase.buildTestError(result, that._sessionStartInfo.scenarioIdOrName, that._sessionStartInfo.appIdOrName);
}
}).then(function () {
that._logger.verbose("Done!");
that._logger.verbose("Restoring temporal variables...");
if (that._regionToCheck) {
that._regionToCheck = null;
}
if (that._checkFrameOrElement) {
that._checkFrameOrElement = false;
}
// restore initial values
if (originalHideScrollBars !== undefined) {
that._hideScrollbars = originalHideScrollBars;
}
if (originalPositionProvider !== undefined) {
that.setPositionProvider(originalPositionProvider);
}
if (originalOverflow !== undefined) {
return regionObject.setOverflow(originalOverflow);
}
}).then(function () {
that._logger.verbose("Done!");
// restore parent frame, if another frame was selected
if (isFrameSwitched) {
that._logger.verbose("Switching back to parent frame...");
return that._driver.switchTo().parentFrame().then(function () {
that._logger.verbose("Done!");
});
}
});
};
/**
* Get the region provider for a certain element.
* @param {Eyes} eyes - The eyes instance.
* @param {EyesRemoteWebElement|webdriver.WebElement} element - The element to get a region for.
* @return {Promise<EyesRegionProvider>} The region for a certain element.
*/
var getRegionProviderForElement = function (eyes, element) {
var elementLocation, elementSize,
borderLeftWidth, borderRightWidth, borderTopWidth;
eyes._logger.verbose("getRegionProviderForElement");
return element.getLocation().then(function (value) {
elementLocation = value;
return element.getSize();
}).then(function (value) {
elementSize = value;
return element.getBorderLeftWidth();
}).then(function (value) {
borderLeftWidth = value;
return element.getBorderRightWidth();
}).then(function (value) {
borderRightWidth = value;
return element.getBorderTopWidth();
}).then(function (value) {
borderTopWidth = value;
return element.getBorderBottomWidth();
}).then(function (value) { // borderBottomWidth
var elementRegion = GeometryUtils.createRegion(
elementLocation.x + borderLeftWidth,
elementLocation.y + borderTopWidth,
elementSize.width - borderLeftWidth - borderRightWidth,
elementSize.height - borderTopWidth - value
);
eyes._logger.verbose("Done! Element region", elementRegion);
return new EyesRegionProvider(eyes._logger, eyes._driver, elementRegion, CoordinatesType.CONTEXT_RELATIVE);
});
};
/**
* Get region provider for the current frame.
* @param {Eyes} eyes - The eyes instance.
* @return {Promise<EyesRegionProvider>} The region provider for the certain frame.
*/
var getRegionProviderForCurrentFrame = function (eyes) {
var screenshot, scaleProviderFactory, mutableImage;
eyes._logger.verbose("getRegionProviderForCurrentFrame");
return eyes.updateScalingParams().then(function (factory) {
scaleProviderFactory = factory;
eyes._logger.verbose("Getting screenshot as base64...");
return eyes._driver.takeScreenshot();
}).then(function (image64) {
return MutableImage.fromBase64(image64, eyes._promiseFactory);
}).then(function (image) {
mutableImage = image;
return mutableImage.getSize();
}).then(function (imageSize) {
eyes._logger.verbose("Scaling image...");
var scaleProvider = scaleProviderFactory.getScaleProvider(imageSize.width);
return mutableImage.scaleImage(scaleProvider.getScaleRatio());
}).then(function (scaledImage) {
eyes._logger.verbose("Done! Building required object...");
screenshot = new EyesWebDriverScreenshot(eyes._logger, eyes._driver, scaledImage, eyes._promiseFactory);
return screenshot.buildScreenshot();
}).then(function () {
var frameRegion = screenshot.getFrameWindow();
eyes._logger.verbose("Done! Frame region", frameRegion);
return new EyesRegionProvider(eyes._logger, eyes._driver, frameRegion, CoordinatesType.SCREENSHOT_AS_IS);
})
};
/**
* Get the region for a certain web element.
* @param {EyesRemoteWebElement|webdriver.WebElement} element - The web element to get the region from.
* @return {Promise<{left: number, top: number, width: number, height: number}>} The region.
*/
var getRegionFromWebElement = function (element) {
var elementSize;
return element.getSize().then(function (size) {
elementSize = size;
return element.getLocation();
}).then(function (point) {
return GeometryUtils.createRegionFromLocationAndSize(point, elementSize);
});
};
//noinspection JSUnusedGlobalSymbols
/**
* Takes a snapshot of the application under test and matches it with
* the expected output.
* @param {string} tag - An optional tag to be associated with the snapshot.
* @param {int} matchTimeout - The amount of time to retry matching (Milliseconds).
* @return {ManagedPromise} A promise which is resolved when the validation is finished.
*/
Eyes.prototype.checkWindow = function (tag, matchTimeout) {
return this.check(tag, Target.window().timeout(matchTimeout));
};
//noinspection JSUnusedGlobalSymbols
/**
* Matches the frame given as parameter, by switching into the frame and
* using stitching to get an image of the frame.
* @param {EyesRemoteWebElement} - element The element which is the frame to switch to. (as
* would be used in a call to driver.switchTo().frame() ).
* @param {int} matchTimeout - The amount of time to retry matching (milliseconds).
* @param {string} tag - An optional tag to be associated with the match.
* @return {ManagedPromise} A promise which is resolved when the validation is finished.
*/
Eyes.prototype.checkFrame = function (element, matchTimeout, tag) {
return this.check(tag, Target.frame(element).timeout(matchTimeout));
};
//noinspection JSUnusedGlobalSymbols
/**
* Takes a snapshot of the application under test and matches a specific
* element with the expected region output.
* @param {webdriver.WebElement|EyesRemoteWebElement} element - The element to check.
* @param {int|null} matchTimeout - The amount of time to retry matching (milliseconds).
* @param {string} tag - An optional tag to be associated with the match.
* @return {ManagedPromise} A promise which is resolved when the validation is finished.
*/
Eyes.prototype.checkElement = function (element, matchTimeout, tag) {
return this.check(tag, Target.region(element).timeout(matchTimeout).fully());
};
//noinspection JSUnusedGlobalSymbols
/**
* Takes a snapshot of the application under test and matches a specific
* element with the expected region output.
* @param {webdriver.By} locator - The element to check.
* @param {int|null} matchTimeout - The amount of time to retry matching (milliseconds).
* @param {string} tag - An optional tag to be associated with the match.
* @return {ManagedPromise} A promise which is resolved when the validation is finished.
*/
Eyes.prototype.checkElementBy = function (locator, matchTimeout, tag) {
return this.check(tag, Target.region(locator).timeout(matchTimeout).fully());
};
//noinspection JSUnusedGlobalSymbols
/**
* Visually validates a region in the screenshot.
* @param {{left: number, top: number, width: number, height: number}} region - The region to
* validate (in screenshot coordinates).
* @param {string} tag - An optional tag to be associated with the screenshot.
* @param {int} matchTimeout - The amount of time to retry matching.
* @return {ManagedPromise} A promise which is resolved when the validation is finished.
*/
Eyes.prototype.checkRegion = function (region, tag, matchTimeout) {
return this.check(tag, Target.region(region).timeout(matchTimeout));
};
//noinspection JSUnusedGlobalSymbols
/**
* Visually validates a region in the screenshot.
* @param {webdriver.WebElement|EyesRemoteWebElement} element - The element defining the region to validate.
* @param {string} tag - An optional tag to be associated with the screenshot.
* @param {int} matchTimeout - The amount of time to retry matching.
* @return {ManagedPromise} A promise which is resolved when the validation is finished.
*/
Eyes.prototype.checkRegionByElement = function (element, tag, matchTimeout) {
return this.check(tag, Target.region(element).timeout(matchTimeout));
};
//noinspection JSUnusedGlobalSymbols
/**
* Visually validates a region in the screenshot.
* @param {webdriver.By} by - The WebDriver selector used for finding the region to validate.
* @param {string} tag - An optional tag to be associated with the screenshot.
* @param {int} matchTimeout - The amount of time to retry matching.
* @return {ManagedPromise} A promise which is resolved when the validation is finished.
*/
Eyes.prototype.checkRegionBy = function (by, tag, matchTimeout) {
return this.check(tag, Target.region(by).timeout(matchTimeout));
};
//noinspection JSUnusedGlobalSymbols
/**
* Switches into the given frame, takes a snapshot of the application under
* test and matches a region specified by the given selector.
* @param {string} frameNameOrId - The name or id of the frame to switch to. (as would be used in a call to driver.switchTo().frame()).
* @param {webdriver.By} locator - A Selector specifying the region to check.
* @param {int|null} matchTimeout - The amount of time to retry matching. (Milliseconds)
* @param {string} tag - An optional tag to be associated with the snapshot.
* @param {boolean} stitchContent - If {@code true}, stitch the internal content of the region (i.e., perform
* {@link #checkElement(By, int, String)} on the region.
* @return {ManagedPromise} A promise which is resolved when the validation is finished.
*/
Eyes.prototype.checkRegionInFrame = function (frameNameOrId, locator, matchTimeout, tag, stitchContent) {
return this.check(tag, Target.region(locator, frameNameOrId).timeout(matchTimeout).fully(stitchContent));
};
/**
* @protected
* @returns {ScaleProviderFactory}
*/
Eyes.prototype.updateScalingParams = function () {
var that = this;
return that._promiseFactory.makePromise(function (resolve) {
if (that._devicePixelRatio === UNKNOWN_DEVICE_PIXEL_RATIO && that._scaleProviderHandler.get() instanceof NullScaleProvider) {
var factory, enSize, vpSize;
that._logger.verbose("Trying to extract device pixel ratio...");
return EyesSeleniumUtils.getDevicePixelRatio(that._driver, that._promiseFactory).then(function (ratio) {
that._devicePixelRatio = ratio;
}, function (err) {
that._logger.verbose("Failed to extract device pixel ratio! Using default.", err);
that._devicePixelRatio = DEFAULT_DEVICE_PIXEL_RATIO;
}).then(function () {
that._logger.verbose("Device pixel ratio: " + that._devicePixelRatio);
that._logger.verbose("Setting scale provider..");
return that._positionProvider.getEntireSize();
}).then(function (entireSize) {
enSize = entireSize;
return that.getViewportSize();
}).then(function (viewportSize) {
vpSize = viewportSize;
factory = new ContextBasedScaleProviderFactory(enSize, vpSize, that._devicePixelRatio, that._scaleProviderHandler);
}, function (err) {
// This can happen in Appium for example.
that._logger.verbose("Failed to set ContextBasedScaleProvider.", err);
that._logger.verbose("Using FixedScaleProvider instead...");
factory = new FixedScaleProviderFactory(1/that._devicePixelRatio, that._scaleProviderHandler);
}).then(function () {
that._logger.verbose("Done!");
resolve(factory);
});
}
// If we already have a scale provider set, we'll just use it, and pass a mock as provider handler.
resolve(new ScaleProviderIdentityFactory(that._scaleProviderHandler.get(), new SimplePropertyHandler()));
});
};
//noinspection JSUnusedGlobalSymbols
/**
* Get an updated screenshot.
* @returns {Promise.<MutableImage>} - The image of the new screenshot.
*/
Eyes.prototype.getScreenShot = function () {
var that = this;
return that.updateScalingParams().then(function (scaleProviderFactory) {
return EyesSeleniumUtils.getScreenshot(
that._driver,
that._promiseFactory,
that._viewportSize,
that._positionProvider,
scaleProviderFactory,
that._cutProviderHandler.get(),
that._forceFullPage,
that._hideScrollbars,
that._stitchMode === StitchMode.CSS,
that._imageRotationDegrees,
that._automaticRotation,
that._os === 'Android' ? 90 : 270,
that._isLandscape,
that._waitBeforeScreenshots,
that._checkFrameOrElement,
that._regionToCheck,
that._saveDebugScreenshots,
that._debugScreenshotsPath
);
});
};
//noinspection JSUnusedGlobalSymbols
Eyes.prototype.getTitle = function () {
return this._driver.getTitle();
};
//noinspection JSUnusedGlobalSymbols
Eyes.prototype._waitTimeout = function (ms) {
return this._flow.timeout(ms);
};
//noinspection JSUnusedGlobalSymbols
Eyes.prototype.getInferredEnvironment = function () {
var res = 'useragent:';
return this._driver.executeScript('return navigator.userAgent')
.then(function (userAgent) {
return res + userAgent;
}, function () {
return res;
});
};
//noinspection JSUnusedGlobalSymbols
/**
* Set the failure report.
* @param mode - Use one of the values in EyesBase.FailureReport.
*/
Eyes.prototype.setFailureReport = function (mode) {
if (mode === EyesBase.FailureReport.Immediate) {
this._failureReportOverridden = true;
mode = EyesBase.FailureReport.OnClose;
}
EyesBase.prototype.setFailureReport.call(this, mode);
};
//noinspection JSUnusedGlobalSymbols
/**
* Get the viewport size.
* @returns {*} The viewport size.
*/
Eyes.prototype.getViewportSize = function () {
return EyesSeleniumUtils.getViewportSizeOrDisplaySize(this._logger, this._driver, this._promiseFactory);
};
//noinspection JSUnusedGlobalSymbols
Eyes.prototype.setViewportSize = function (size) {
return EyesSeleniumUtils.setViewportSize(this._logger, this._driver, size, this._promiseFactory);
};
//noinspection JSUnusedGlobalSymbols
/**
* Set the viewport size using the driver. Call this method if for some reason
* you don't want to call {@link #open(WebDriver, String, String)} (or one of its variants) yet.
* @param {WebDriver} driver - The driver to use for setting the viewport.
* @param {{width: number, height: number}} size - The required viewport size.
* @return {Promise<void>} The viewport size of the browser.
*/
Eyes.setViewportSize = function (driver, size) {
var promiseFactory = new PromiseFactory();
promiseFactory.setFactoryMethods(function (asyncAction) {
var deferred = promise.defer();
asyncAction(deferred.fulfill, deferred.reject);
return deferred.promise;
}, function () {
return promise.defer();
});
return EyesSeleniumUtils.setViewportSize(new Logger(), driver, size, promiseFactory);
};
//noinspection JSUnusedGlobalSymbols
/**
* Set the full page screenshot option.
* @param {boolean} force - Whether to force a full page screenshot or not.
* @return {void}
*/
Eyes.prototype.setForceFullPageScreenshot = function (force) {
this._forceFullPage = force;
};
//noinspection JSUnusedGlobalSymbols
/**
* Get whether to force a full page screenshot or not.
* @return {boolean} true if the option is on, otherwise false.
*/
Eyes.prototype.getForceFullPageScreenshot = function () {
return this._forceFullPage;
};
//noinspection JSUnusedGlobalSymbols
/**
* Set the image rotation degrees.
* @param degrees - The amount of degrees to set the rotation to.
*/
Eyes.prototype.setForcedImageRotation = function (degrees) {
if (typeof degrees !== 'number') {
throw new TypeError('degrees must be a number! set to 0 to clear');
}
this._imageRotationDegrees = degrees;
this._automaticRotation = false;
};
//noinspection JSUnusedGlobalSymbols
/**
* Get the rotation degrees.
* @returns {*|number} - The rotation degrees.
*/
Eyes.prototype.getForcedImageRotation = function () {
return this._imageRotationDegrees || 0;
};
//noinspection JSUnusedGlobalSymbols
/**
* Hide the scrollbars when taking screenshots.
* @param {boolean} hide - Whether to hide the scrollbars or not.
*/
Eyes.prototype.setHideScrollbars = function (hide) {
this._hideScrollbars = hide;
};
//noinspection JSUnusedGlobalSymbols
/**
* Hide the scrollbars when taking screenshots.
* @return {boolean|null} - true if the hide scrollbars option is on, otherwise false.
*/
Eyes.prototype.getHideScrollbars = function () {
return this._hideScrollbars;
};
//noinspection JSUnusedGlobalSymbols
/**
* Set the stitch mode.
* @param {StitchMode} mode - The desired stitch mode settings.
*/
Eyes.prototype.setStitchMode = function (mode) {
this._stitchMode = mode;
if (this._driver) {
switch (mode) {
case StitchMode.CSS:
this.setPositionProvider(new CssTranslatePositionProvider(this._logger, this._driver, this._promiseFactory));
break;
default:
this.setPositionProvider(new ScrollPositionProvider(this._logger, this._driver, this._promiseFactory));
}
}
};
//noinspection JSUnusedGlobalSymbols
/**
* Get the stitch mode.
* @return {StitchMode} The currently set StitchMode.
*/
Eyes.prototype.getStitchMode = function () {
return this._stitchMode;
};
//noinspection JSUnusedGlobalSymbols
/**
* Sets the wait time between before each screen capture, including between
* screen parts of a full page screenshot.
* @param waitBeforeScreenshots - The wait time in milliseconds.
*/
Eyes.prototype.setWaitBeforeScreenshots = function (waitBeforeScreenshots) {
if (waitBeforeScreenshots <= 0) {
this._waitBeforeScreenshots = DEFAULT_WAIT_BEFORE_SCREENSHOTS;
} else {
this._waitBeforeScreenshots = waitBeforeScreenshots;
}
};
//noinspection JSUnusedGlobalSymbols
/**
* Get the wait time before each screenshot.
* @returns {number|*} the wait time between before each screen capture, in milliseconds.
*/
Eyes.prototype.getWaitBeforeScreenshots = function () {
return this._waitBeforeScreenshots;
};
//noinspection JSUnusedGlobalSymbols
/**
* Get the session id.
* @returns {Promise} A promise which resolves to the webdriver's session ID.
*/
Eyes.prototype.getAUTSessionId = function () {
return this._promiseFactory.makePromise(function (resolve) {
if (!this._driver) {
resolve(undefined);
return;
}
this._driver.getSession()
.then(function (session) {
resolve(session.getId());
});
}.bind(this));
};
/**
* @readonly
* @enum {string}
*/
Eyes.StitchMode = Object.freeze(StitchMode);
module.exports = Eyes;
}());