UNPKG

@applitools/eyes.selenium

Version:

Applitools Eyes SDK for Selenium WebDriver

176 lines (150 loc) 4.18 kB
'use strict'; const { ArgumentGuard, Location } = require('@applitools/eyes.sdk.core'); const { Frame } = require('./Frame'); const { NoFramesError } = require('../errors/NoFramesError'); /** * @class FrameChain * @extends {Iterable<Frame>} */ class FrameChain { /** * Creates a new frame chain. * * @param {Logger} logger A Logger instance. * @param {FrameChain} [other] A frame chain from which the current frame chain will be created. */ constructor(logger, other) { ArgumentGuard.notNull(logger, 'logger'); this._logger = logger; this._frames = []; if (other) { this._logger.verbose(`Frame chain copy constructor (size ${other.size()})`); other.getFrames().forEach(otherFrame => { this._frames.push(new Frame( logger, otherFrame.getReference(), otherFrame.getLocation(), otherFrame.getSize(), otherFrame.getInnerSize(), otherFrame.getOriginalLocation(), otherFrame.getOriginalOverflow() )); }); this._logger.verbose('Done!'); } } /** * Compares two frame chains. * * @param {FrameChain} c1 Frame chain to be compared against c2. * @param {FrameChain} c2 Frame chain to be compared against c1. * @return {boolean} True if both frame chains represent the same frame, false otherwise. */ static isSameFrameChain(c1, c2) { const lc1 = c1.size(); const lc2 = c2.size(); // different chains size means different frames if (lc1 !== lc2) { return false; } for (let i = 0; i < lc1; i += 1) { if (c1.getFrame(i).getReference() !== c2.getFrame(i).getReference()) { return false; } } return true; } /** * @return {number} The number of frames in the chain. */ size() { return this._frames.length; } /** * Removes all current frames in the frame chain. */ clear() { this._frames = []; } /** * Removes the last inserted frame element. Practically means we switched back to the parent of the current frame * * @return {Frame} */ pop() { return this._frames.pop(); } /** * @return {Frame} Returns the top frame in the chain. */ peek() { return this._frames[this._frames.length - 1]; } /** * Appends a frame to the frame chain. * * @param {Frame} frame The frame to be added. */ push(frame) { return this._frames.push(frame); } /** * @return {Location} The location of the current frame in the page. */ getCurrentFrameOffset() { let result = new Location(0, 0); this._frames.forEach(frame => { result = result.offsetByLocation(frame.getLocation()); }); return result; } /** * @return {Location} The outermost frame's location, or NoFramesException. */ getDefaultContentScrollPosition() { if (this._frames.length === 0) { throw new NoFramesError('No frames in frame chain'); } return new Location(this._frames[0].getOriginalLocation()); } // noinspection JSUnusedGlobalSymbols /** * @return {RectangleSize} The size of the current frame. */ getCurrentFrameSize() { this._logger.verbose('getCurrentFrameSize()'); const result = this._frames[this._frames.length - 1].getSize(); this._logger.verbose('Done!'); return result; } /** * @return {RectangleSize} The inner size of the current frame. */ getCurrentFrameInnerSize() { this._logger.verbose('getCurrentFrameInnerSize()'); const result = this._frames[this._frames.length - 1].getInnerSize(); this._logger.verbose('Done!'); return result; } /** * @return Iterator<Frame> iterator to go over the frames in the chain. */ [Symbol.iterator]() { return this._frames.values(); } /** * @return {Frame[]} All frames stored in chain */ getFrames() { return this._frames; } /** * @param {number} index Index of needed frame * @return {Frame} Frame by index in array */ getFrame(index) { if (this._frames.length > index) { return this._frames[index]; } throw new Error('No frames for given index'); } } exports.FrameChain = FrameChain;