From 9da1441855d1d363bdd2349b14492e3e54230051 Mon Sep 17 00:00:00 2001 From: Amit Singh Sansoya Date: Fri, 24 Nov 2023 17:17:46 +0530 Subject: [PATCH 1/2] Fixing FindRegion + Refactor (#1408) * Fixing FindRegion + Refactor * Adding More Tests * Making logic more functional for IOS * Refactoring code as per comments * Updating Comment for Info * Fixing ignore region * Fixing few stuff * Formatting the PR little bit * Updating Tests and Refactoring * Updating Specs and Handling Safari Specific cases * Adding Floor & Ceil to shifter variables * Handling Scrollbar transformation for ignore-region * Fixing lint issue --- packages/webdriver-utils/src/driver.js | 22 + .../src/providers/genericProvider.js | 148 ++++- packages/webdriver-utils/test/driver.test.js | 60 ++ .../test/providers/genericProvider.test.js | 567 ++++++++++++++++-- 4 files changed, 725 insertions(+), 72 deletions(-) diff --git a/packages/webdriver-utils/src/driver.js b/packages/webdriver-utils/src/driver.js index 87760778e..2bdd428e7 100644 --- a/packages/webdriver-utils/src/driver.js +++ b/packages/webdriver-utils/src/driver.js @@ -77,4 +77,26 @@ export default class Driver { const response = JSON.parse((await request(baseUrl, options)).body); return response.value; } + + async findElementBoundingBox(using, value) { + if (using === 'xpath') { + return await this.findElementXpath(value); + } else if (using === 'css selector') { + return await this.findElementSelector(value); + } + } + + async findElementXpath(xpath) { + xpath = xpath.replace(/'/g, '"'); + const command = { script: `return document.evaluate('${xpath}', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getBoundingClientRect();`, args: [] }; + const response = await this.executeScript(command); + return response.value; + } + + async findElementSelector(selector) { + selector = selector.replace('\\', '\\\\'); + const command = { script: `return document.querySelector('${selector}').getBoundingClientRect();`, args: [] }; + const response = await this.executeScript(command); + return response.value; + } } diff --git a/packages/webdriver-utils/src/providers/genericProvider.js b/packages/webdriver-utils/src/providers/genericProvider.js index 04ac51d1d..dbd548447 100644 --- a/packages/webdriver-utils/src/providers/genericProvider.js +++ b/packages/webdriver-utils/src/providers/genericProvider.js @@ -33,6 +33,12 @@ export default class GenericProvider { this.debugUrl = null; this.header = 0; this.footer = 0; + this.statusBarHeight = 0; + this.pageXShiftFactor = 0; + this.pageYShiftFactor = 0; + this.currentTag = null; + this.removeElementShiftFactor = 50000; + this.initialScrollFactor = { value: [0, 0] }; } addDefaultOptions() { @@ -63,6 +69,18 @@ export default class GenericProvider { } } + async getInitialPosition() { + if (this.currentTag.osName === 'iOS') { + this.initialScrollFactor = await this.driver.executeScript({ script: 'return [parseInt(window.scrollX), parseInt(window.scrollY)];', args: [] }); + } + } + + async scrollToInitialPosition(x, y) { + if (this.currentTag.osName === 'iOS') { + await this.driver.executeScript({ script: `window.scrollTo(${x}, ${y})`, args: [] }); + } + } + async screenshot(name, { ignoreRegionXpaths = [], ignoreRegionSelectors = [], @@ -86,6 +104,9 @@ export default class GenericProvider { const tiles = await this.getTiles(this.header, this.footer, fullscreen); log.debug(`[${name}] : Tiles ${JSON.stringify(tiles)}`); + this.currentTag = tag; + this.statusBarHeight = tiles.tiles[0].statusBarHeight; + const ignoreRegions = await this.findRegions( ignoreRegionXpaths, ignoreRegionSelectors, ignoreRegionElements, customIgnoreRegions ); @@ -172,30 +193,67 @@ export default class GenericProvider { this.debugUrl = 'https://localhost/v1'; } + async doTransformations() { + const hideScrollbarStyle = ` + /* Hide scrollbar for Chrome, Safari and Opera */ + ::-webkit-scrollbar { + display: none !important; + } + + /* Hide scrollbar for IE, Edge and Firefox */ + body, html { + -ms-overflow-style: none !important; /* IE and Edge */ + scrollbar-width: none !important; /* Firefox */ + }`.replace(/\n/g, ''); + const jsScript = ` + const e = document.createElement('style'); + e.setAttribute('class', 'poa-injected'); + e.innerHTML = '${hideScrollbarStyle}' + document.head.appendChild(e);`; + + await this.driver.executeScript({ script: jsScript, args: [] }); + } + + async undoTransformations(data) { + const jsScript = ` + const n = document.querySelectorAll('${data}'); + n.forEach((e) => {e.remove()});`; + + await this.driver.executeScript({ script: jsScript, args: [] }); + } + async findRegions(xpaths, selectors, elements, customLocations) { - const xpathRegions = await this.getSeleniumRegionsBy('xpath', xpaths); - const selectorRegions = await this.getSeleniumRegionsBy('css selector', selectors); - const elementRegions = await this.getSeleniumRegionsByElement(elements); - const customRegions = await this.getSeleniumRegionsByLocation(customLocations); - - return [ - ...xpathRegions, - ...selectorRegions, - ...elementRegions, - ...customRegions - ]; + let isRegionPassed = [xpaths, selectors, elements, customLocations].some(regions => regions.length > 0); + if (isRegionPassed) { + await this.doTransformations(); + const xpathRegions = await this.getSeleniumRegionsBy('xpath', xpaths); + const selectorRegions = await this.getSeleniumRegionsBy('css selector', selectors); + const elementRegions = await this.getSeleniumRegionsByElement(elements); + const customRegions = await this.getSeleniumRegionsByLocation(customLocations); + await this.undoTransformations('.poa-injected'); + + return [ + ...xpathRegions, + ...selectorRegions, + ...elementRegions, + ...customRegions + ]; + } else { + return []; + } } - async getRegionObject(selector, elementId) { - const scaleFactor = parseInt(await this.metaData.devicePixelRatio()); - const rect = await this.driver.rect(elementId); - const location = { x: rect.x, y: rect.y }; - const size = { height: rect.height, width: rect.width }; + async getRegionObjectFromBoundingBox(selector, element) { + const scaleFactor = await this.metaData.devicePixelRatio(); + let headerAdjustment = 0; + if (this.currentTag.osName === 'iOS') { + headerAdjustment = this.statusBarHeight; + } const coOrdinates = { - top: Math.floor(location.y * scaleFactor), - bottom: Math.ceil((location.y + size.height) * scaleFactor), - left: Math.floor(location.x * scaleFactor), - right: Math.ceil((location.x + size.width) * scaleFactor) + top: Math.floor(element.y * scaleFactor) + Math.floor(headerAdjustment), + bottom: Math.ceil((element.y + element.height) * scaleFactor) + Math.ceil(headerAdjustment), + left: Math.floor(element.x * scaleFactor), + right: Math.ceil((element.x + element.width) * scaleFactor) }; const jsonObject = { @@ -210,9 +268,9 @@ export default class GenericProvider { const regionsArray = []; for (const idx in elements) { try { - const element = await this.driver.findElement(findBy, elements[idx]); + const boundingBoxRegion = await this.driver.findElementBoundingBox(findBy, elements[idx]); const selector = `${findBy}: ${elements[idx]}`; - const region = await this.getRegionObject(selector, element[Object.keys(element)[0]]); + const region = await this.getRegionObjectFromBoundingBox(selector, boundingBoxRegion); regionsArray.push(region); } catch (e) { log.warn(`Selenium Element with ${findBy}: ${elements[idx]} not found. Ignoring this ${findBy}.`); @@ -222,12 +280,55 @@ export default class GenericProvider { return regionsArray; } + async updatePageShiftFactor(location, scaleFactor) { + const scrollFactors = await this.driver.executeScript({ script: 'return [parseInt(window.scrollX), parseInt(window.scrollY)];', args: [] }); + if (this.currentTag.osName === 'iOS' || (this.currentTag.osName === 'OS X' && parseInt(this.currentTag.browserVersion) > 13 && this.currentTag.browserName.toLowerCase() === 'safari')) { + this.pageYShiftFactor = this.statusBarHeight; + } else { + this.pageYShiftFactor = this.statusBarHeight - (scrollFactors.value[1] * scaleFactor); + } + this.pageXShiftFactor = this.currentTag.osName === 'iOS' ? 0 : (-(scrollFactors.value[0] * scaleFactor)); + if (this.currentTag.osName === 'iOS') { + if (scrollFactors.value[0] !== this.initialScrollFactor.value[0] || scrollFactors.value[1] !== this.initialScrollFactor.value[1]) { + this.pageXShiftFactor = (-1 * this.removeElementShiftFactor); + this.pageYShiftFactor = (-1 * this.removeElementShiftFactor); + } else if (location.y === 0) { + this.pageYShiftFactor += (-(scrollFactors.value[1] * scaleFactor)); + } + } + } + + async getRegionObject(selector, elementId) { + const scaleFactor = await this.metaData.devicePixelRatio(); + const rect = await this.driver.rect(elementId); + const location = { x: rect.x, y: rect.y }; + const size = { height: rect.height, width: rect.width }; + // Update pageShiftFactor Element is not visible in viewport + // In case of iOS if the element is not visible in viewport it gives 0 for x-y coordinate. + // In case of iOS if the element is partially visible it gives negative x-y coordinate. + // Subtracting ScrollY/ScrollX ensures if the element is visible in viewport or not. + await this.updatePageShiftFactor(location, scaleFactor); + const coOrdinates = { + top: Math.floor(location.y * scaleFactor) + Math.floor(this.pageYShiftFactor), + bottom: Math.ceil((location.y + size.height) * scaleFactor) + Math.ceil(this.pageYShiftFactor), + left: Math.floor(location.x * scaleFactor) + Math.floor(this.pageXShiftFactor), + right: Math.ceil((location.x + size.width) * scaleFactor) + Math.ceil(this.pageXShiftFactor) + }; + + const jsonObject = { + selector, + coOrdinates + }; + + return jsonObject; + } + async getSeleniumRegionsByElement(elements) { const regionsArray = []; + await this.getInitialPosition(); for (let index = 0; index < elements.length; index++) { try { const selector = `element: ${index}`; - const region = await this.getRegionObject(selector, elements[index]); regionsArray.push(region); } catch (e) { @@ -235,6 +336,7 @@ export default class GenericProvider { log.debug(e.toString()); } } + await this.scrollToInitialPosition(this.initialScrollFactor.value[0], this.initialScrollFactor.value[1]); return regionsArray; } diff --git a/packages/webdriver-utils/test/driver.test.js b/packages/webdriver-utils/test/driver.test.js index 74dc58b79..3b90da83c 100644 --- a/packages/webdriver-utils/test/driver.test.js +++ b/packages/webdriver-utils/test/driver.test.js @@ -151,6 +151,66 @@ describe('Driver', () => { }); }); + describe('findElementBoundingBox', () => { + let xpathFindElementSpy; + let cssSelectorFindElementSpy; + beforeEach(() => { + xpathFindElementSpy = spyOn(Driver.prototype, 'findElementXpath').and.returnValue(Promise.resolve({ x: 0, y: 10, height: 100, width: 100 })); + cssSelectorFindElementSpy = spyOn(Driver.prototype, 'findElementSelector').and.returnValue(Promise.resolve({ x: 0, y: 10, height: 100, width: 100 })); + }); + describe('when xpath is passed', () => { + it('calls the required function', async () => { + const res = await driver.findElementBoundingBox('xpath', '/xpath1'); + expect(cssSelectorFindElementSpy).toHaveBeenCalledTimes(0); + expect(xpathFindElementSpy).toHaveBeenCalledTimes(1); + expect(xpathFindElementSpy).toHaveBeenCalledWith('/xpath1'); + expect(res).toEqual({ x: 0, y: 10, height: 100, width: 100 }); + }); + }); + + describe('when selector is passed', () => { + it('calls the required function', async () => { + const res = await driver.findElementBoundingBox('css selector', '#id1'); + expect(xpathFindElementSpy).toHaveBeenCalledTimes(0); + expect(cssSelectorFindElementSpy).toHaveBeenCalledTimes(1); + expect(cssSelectorFindElementSpy).toHaveBeenCalledWith('#id1'); + expect(res).toEqual({ x: 0, y: 10, height: 100, width: 100 }); + }); + }); + + describe('when invalid is passed', () => { + it('calls nothing', async () => { + await driver.findElementBoundingBox('abc', '#id1'); + expect(xpathFindElementSpy).toHaveBeenCalledTimes(0); + expect(cssSelectorFindElementSpy).toHaveBeenCalledTimes(0); + }); + }); + }); + + describe('findElementXpath', () => { + let executeScriptSpy; + beforeEach(() => { + executeScriptSpy = spyOn(Driver.prototype, 'executeScript').and.returnValue(Promise.resolve({ value: { x: 0, y: 10, height: 100, width: 100 } })); + }); + it('calls requests', async () => { + const res = await driver.findElementXpath('/xpath1'); + expect(executeScriptSpy).toHaveBeenCalledWith({ script: "return document.evaluate('/xpath1', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getBoundingClientRect();", args: [] }); + expect(res).toEqual({ x: 0, y: 10, height: 100, width: 100 }); + }); + }); + + describe('findElementSelector', () => { + let executeScriptSpy; + beforeEach(() => { + executeScriptSpy = spyOn(Driver.prototype, 'executeScript').and.returnValue(Promise.resolve({ value: { x: 0, y: 10, height: 100, width: 100 } })); + }); + it('calls requests', async () => { + const res = await driver.findElementSelector('#id1'); + expect(executeScriptSpy).toHaveBeenCalledWith({ script: "return document.querySelector('#id1').getBoundingClientRect();", args: [] }); + expect(res).toEqual({ x: 0, y: 10, height: 100, width: 100 }); + }); + }); + describe('rect', () => { it('calls requests', async () => { const elementId = 'element'; diff --git a/packages/webdriver-utils/test/providers/genericProvider.test.js b/packages/webdriver-utils/test/providers/genericProvider.test.js index 95aca30b6..8f34ce56e 100644 --- a/packages/webdriver-utils/test/providers/genericProvider.test.js +++ b/packages/webdriver-utils/test/providers/genericProvider.test.js @@ -134,31 +134,118 @@ describe('GenericProvider', () => { describe('screenshot', () => { let getTagSpy; let getTilesSpy; + let iOSGetTagSpy; + let iOSGetTilesSpy; + + describe('With Desktop', () => { + let desktopTag; + let desktopTiles; + beforeEach(() => { + desktopTag = { + name: 'Windows_11_Chrome_103', + osName: 'Windows', + osVersion: '11', + width: 1000, + height: 1000, + orientation: 'landscape', + browserName: 'chrome', + browserVersion: '103', + resolution: '1980 x 1080' + }; + desktopTiles = { + tiles: [{ + statusBarHeight: 0, + sha: 'abc', + navBarHeight: 0, + headerHeight: 0, + footerHeight: 0, + fullscreen: false + }], + domInfoSha: 'mock-dom-sha' + }; + getTagSpy = spyOn(GenericProvider.prototype, 'getTag').and.returnValue(Promise.resolve(desktopTag)); + getTilesSpy = spyOn(GenericProvider.prototype, 'getTiles').and.returnValue(Promise.resolve(desktopTiles)); + spyOn(DesktopMetaData.prototype, 'windowSize') + .and.returnValue(Promise.resolve({ width: 1920, height: 1080 })); + }); - beforeEach(() => { - getTagSpy = spyOn(GenericProvider.prototype, 'getTag').and.returnValue(Promise.resolve('mock-tag')); - getTilesSpy = spyOn(GenericProvider.prototype, 'getTiles').and.returnValue(Promise.resolve({ tiles: 'mock-tile', domInfoSha: 'mock-dom-sha' })); - spyOn(DesktopMetaData.prototype, 'windowSize') - .and.returnValue(Promise.resolve({ width: 1920, height: 1080 })); + it('calls correct funcs', async () => { + genericProvider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}, 'local-poc-poa', 'staging-poc-poa', {}); + await genericProvider.createDriver(); + let res = await genericProvider.screenshot('mock-name', {}); + expect(getTagSpy).toHaveBeenCalledTimes(1); + expect(genericProvider.statusBarHeight).toEqual(0); + expect(getTilesSpy).toHaveBeenCalledOnceWith(0, 0, false); + expect(res).toEqual({ + name: 'mock-name', + tag: desktopTag, + tiles: desktopTiles.tiles, + externalDebugUrl: 'https://localhost/v1', + environmentInfo: 'staging-poc-poa', + ignoredElementsData: { ignoreElementsData: [] }, + consideredElementsData: { considerElementsData: [] }, + clientInfo: 'local-poc-poa', + domInfoSha: 'mock-dom-sha', + metadata: null + }); + }); }); - it('calls correct funcs', async () => { - genericProvider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}, 'local-poc-poa', 'staging-poc-poa', {}); - await genericProvider.createDriver(); - let res = await genericProvider.screenshot('mock-name', {}); - expect(getTagSpy).toHaveBeenCalledTimes(1); - expect(getTilesSpy).toHaveBeenCalledOnceWith(0, 0, false); - expect(res).toEqual({ - name: 'mock-name', - tag: 'mock-tag', - tiles: 'mock-tile', - externalDebugUrl: 'https://localhost/v1', - environmentInfo: 'staging-poc-poa', - ignoredElementsData: { ignoreElementsData: [] }, - consideredElementsData: { considerElementsData: [] }, - clientInfo: 'local-poc-poa', - domInfoSha: 'mock-dom-sha', - metadata: null + describe('With Mobile iOS', () => { + let iosTag; + let iosTiles; + + beforeEach(() => { + const scrollFactors = { value: [0, 10] }; + iosTag = { + name: 'iPhone 11 Pro', + osName: 'iOS', + osVersion: '15', + width: 1000, + height: 1000, + orientation: 'potrait', + browserName: 'safari', + browserVersion: '15', + resolution: '1980 x 1080' + }; + iosTiles = { + tiles: [{ + statusBarHeight: 132, + sha: 'abc', + navBarHeight: 0, + headerHeight: 0, + footerHeight: 0, + fullscreen: false + }], + domInfoSha: 'mock-dom-sha' + }; + iOSGetTagSpy = spyOn(GenericProvider.prototype, 'getTag').and.returnValue(Promise.resolve(iosTag)); + iOSGetTilesSpy = spyOn(GenericProvider.prototype, 'getTiles').and.returnValue(Promise.resolve(iosTiles)); + spyOn(DesktopMetaData.prototype, 'windowSize') + .and.returnValue(Promise.resolve({ width: 1920, height: 1080 })); + spyOn(Driver.prototype, 'executeScript') + .and.returnValue(scrollFactors); + }); + + it('calls correct funcs with iOS', async () => { + genericProvider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}, 'local-poc-poa', 'staging-poc-poa', {}); + await genericProvider.createDriver(); + let res = await genericProvider.screenshot('mock-name', {}); + expect(iOSGetTagSpy).toHaveBeenCalledTimes(1); + expect(genericProvider.statusBarHeight).toEqual(132); + expect(iOSGetTilesSpy).toHaveBeenCalledOnceWith(0, 0, false); + expect(res).toEqual({ + name: 'mock-name', + tag: iosTag, + tiles: iosTiles.tiles, + externalDebugUrl: 'https://localhost/v1', + environmentInfo: 'staging-poc-poa', + ignoredElementsData: { ignoreElementsData: [] }, + consideredElementsData: { considerElementsData: [] }, + clientInfo: 'local-poc-poa', + domInfoSha: 'mock-dom-sha', + metadata: null + }); }); }); }); @@ -177,31 +264,237 @@ describe('GenericProvider', () => { }); }); + describe('updatePageShiftFactor', () => { + let provider; + + describe('When iOS', () => { + beforeEach(async () => { + provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); + await provider.createDriver(); + spyOn(Driver.prototype, 'executeScript').and.returnValue({ value: [0, 10] }); + provider.currentTag = { osName: 'iOS' }; + provider.pageYShiftFactor = 0; + provider.statusBarHeight = 0; + }); + + describe('when element is visible in viewport', () => { + beforeEach(() => { + provider.initialScrollFactor = { value: [0, 10] }; + }); + it('should update pageYShiftFactor for iOS when location.y is 0', async () => { + await provider.updatePageShiftFactor({ y: 0 }, 2); + expect(provider.pageYShiftFactor).toBe(-20); + }); + + it('should not update pageYShiftFactor for iOS when location.y is not 0', async () => { + // Location.y is not 0 + await provider.updatePageShiftFactor({ y: 5 }, 2); + expect(provider.pageYShiftFactor).toBe(0); + }); + }); + + describe('when element is not visible in viewport and iOS scrolls automatically', () => { + beforeEach(() => { + provider.initialScrollFactor = { value: [0, 30] }; + }); + it('should update pageYShiftFactor to negative value even if location.y is 0', async () => { + await provider.updatePageShiftFactor({ y: 0 }, 2); + expect(provider.pageYShiftFactor).toBe(-50000); + }); + + it('should update pageYShiftFactor to negative value even if location.y is not 0', async () => { + // Location.y is not 0 + await provider.updatePageShiftFactor({ y: 5 }, 2); + expect(provider.pageYShiftFactor).toBe(-50000); + }); + }); + }); + + describe('When OS X', () => { + beforeEach(async () => { + provider = new GenericProvider('123', 'http:executorUrl', { platform: 'OS X' }, {}); + await provider.createDriver(); + spyOn(Driver.prototype, 'executeScript').and.returnValue({ value: [0, 10] }); + provider.currentTag = { osName: 'OS X' }; + provider.pageYShiftFactor = 0; + provider.statusBarHeight = 0; + }); + + describe('When Safari browserVersion > 13', () => { + describe('when element is visible in viewport', () => { + beforeEach(() => { + provider.initialScrollFactor = { value: [0, 10] }; + provider.currentTag.browserName = 'safari'; + provider.currentTag.browserVersion = 15; + }); + + it('should not update pageYShiftFactor for OS X if scrolled', async () => { + await provider.updatePageShiftFactor({ y: 0 }, 1); + expect(provider.pageYShiftFactor).toBe(0); + }); + }); + }); + + describe('When Safari browserVersion <= 13', () => { + describe('when element is visible in viewport', () => { + beforeEach(() => { + provider.initialScrollFactor = { value: [0, 10] }; + provider.currentTag.browserName = 'safari'; + provider.currentTag.browserVersion = 13; + }); + + it('should update pageYShiftFactor for OS X platforms accordingly if scrolled', async () => { + await provider.updatePageShiftFactor({ y: 0 }, 1); + expect(provider.pageYShiftFactor).toBe(-10); + }); + }); + }); + }); + + describe('When Other', () => { + beforeEach(async () => { + provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); + await provider.createDriver(); + provider.currentTag = { osName: 'Android' }; + provider.pageYShiftFactor = 0; + }); + + it('should not update pageYShiftFactor for non-iOS platforms', async () => { + spyOn(Driver.prototype, 'executeScript').and.returnValue({ value: [0, 0] }); + await provider.updatePageShiftFactor({ y: 0 }, 1); + expect(provider.pageYShiftFactor).toBe(0); + }); + + it('should update pageYShiftFactor for non-iOS platforms accordingly if scrolled', async () => { + spyOn(Driver.prototype, 'executeScript').and.returnValue({ value: [0, 10] }); + await provider.updatePageShiftFactor({ y: 0 }, 1); + expect(provider.pageYShiftFactor).toBe(-10); + }); + }); + }); + describe('getRegionObject', () => { let provider; let mockLocation = { x: 10, y: 20, width: 100, height: 200 }; - beforeEach(() => { + + describe('When on Tile 0', () => { + beforeEach(async () => { + // mock metadata + provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); + provider.currentTag = { osName: 'Windows' }; + await provider.createDriver(); + spyOn(DesktopMetaData.prototype, 'devicePixelRatio') + .and.returnValue(1); + spyOn(Driver.prototype, 'executeScript') + .and.returnValue({ value: [0, 0] }); + spyOn(Driver.prototype, 'rect').and.returnValue(Promise.resolve(mockLocation)); + }); + + it('should return a JSON object with the correct selector and coordinates for tile 0', async () => { + await provider.createDriver(); + + // Call function with mock data + const selector = 'mock-selector'; + const result = await provider.getRegionObject(selector, 'mockElementId'); + + // Assert expected result + expect(result.selector).toEqual(selector); + expect(result.coOrdinates).toEqual({ + top: mockLocation.y, + bottom: mockLocation.y + mockLocation.height, + left: mockLocation.x, + right: mockLocation.x + mockLocation.width + }); + }); + }); + + describe('When on Tile 1', () => { + beforeEach(async () => { + // mock metadata + provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); + provider.currentTag = { osName: 'iOS' }; + await provider.createDriver(); + spyOn(DesktopMetaData.prototype, 'devicePixelRatio') + .and.returnValue(1); + spyOn(Driver.prototype, 'executeScript') + .and.returnValue({ value: [0, 0] }); + spyOn(Driver.prototype, 'rect').and.returnValue(Promise.resolve(mockLocation)); + provider.pageYShiftFactor = -10; + }); + + afterEach(() => { + provider.pageYShiftFactor = 0; + provider.currentTag = null; + }); + it('should return a JSON object with the correct selector and coordinates', async () => { + await provider.createDriver(); + + // Call function with mock data + const selector = 'mock-selector'; + const result = await provider.getRegionObject(selector, 'mockElementId'); + + // Assert expected result + expect(result.selector).toEqual(selector); + expect(result.coOrdinates).toEqual({ + top: mockLocation.y + provider.pageYShiftFactor, + bottom: mockLocation.y + mockLocation.height + provider.pageYShiftFactor, + left: mockLocation.x, + right: mockLocation.x + mockLocation.width + }); + }); + }); + }); + + describe('getRegionObjectFromBoundingBox', () => { + let provider; + let mockLocation = { x: 10, y: 20, width: 100, height: 200 }; + beforeEach(async () => { // mock metadata provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); + provider.currentTag = { osName: 'Windows' }; + await provider.createDriver(); spyOn(DesktopMetaData.prototype, 'devicePixelRatio') .and.returnValue(1); - spyOn(Driver.prototype, 'rect').and.returnValue(Promise.resolve(mockLocation)); + provider.statusBarHeight = 0; }); - it('should return a JSON object with the correct selector and coordinates', async () => { - await provider.createDriver(); - - // Call function with mock data - const selector = 'mock-selector'; - const result = await provider.getRegionObject(selector, 'mockElementId'); + describe('When not an iOS', () => { + it('should return a JSON object with the correct selector and coordinates', async () => { + // Call function with mock data + const selector = 'mock-selector'; + const result = await provider.getRegionObjectFromBoundingBox(selector, mockLocation); + + // Assert expected result + expect(result.selector).toEqual(selector); + expect(result.coOrdinates).toEqual({ + top: mockLocation.y, + bottom: mockLocation.y + mockLocation.height, + left: mockLocation.x, + right: mockLocation.x + mockLocation.width + }); + }); + }); - // Assert expected result - expect(result.selector).toEqual(selector); - expect(result.coOrdinates).toEqual({ - top: mockLocation.y, - bottom: mockLocation.y + mockLocation.height, - left: mockLocation.x, - right: mockLocation.x + mockLocation.width + describe('When iOS', () => { + beforeEach(() => { + provider.currentTag = { osName: 'iOS' }; + provider.statusBarHeight = 132; + }); + it('should return a JSON object with the correct selector and coordinates with added statusBarHeight', async () => { + await provider.createDriver(); + + // Call function with mock data + const selector = 'mock-selector'; + const result = await provider.getRegionObjectFromBoundingBox(selector, mockLocation); + + // Assert expected result + expect(result.selector).toEqual(selector); + expect(result.coOrdinates).toEqual({ + top: mockLocation.y + provider.statusBarHeight, + bottom: mockLocation.y + mockLocation.height + provider.statusBarHeight, + left: mockLocation.x, + right: mockLocation.x + mockLocation.width + }); }); }); }); @@ -209,31 +502,32 @@ describe('GenericProvider', () => { describe('getSeleniumRegionsByXpaths', () => { let getRegionObjectSpy; let provider; + let xpathResponse = { top: 0, bottom: 500, right: 0, left: 300 }; beforeEach(async () => { provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); await provider.createDriver(); - getRegionObjectSpy = spyOn(GenericProvider.prototype, 'getRegionObject').and.returnValue({}); + getRegionObjectSpy = spyOn(GenericProvider.prototype, 'getRegionObjectFromBoundingBox').and.returnValue(xpathResponse); }); it('should add regions for each xpath', async () => { - spyOn(Driver.prototype, 'findElement').and.returnValue(Promise.resolve({ ELEMENT: 'mock_id' })); + spyOn(Driver.prototype, 'findElementBoundingBox').and.returnValue(Promise.resolve({ x: 0, y: 100, height: 500, width: 300 })); const xpaths = ['/xpath/1', '/xpath/2', '/xpath/3']; const elementsArray = await provider.getSeleniumRegionsBy('xpath', xpaths); - expect(provider.driver.findElement).toHaveBeenCalledTimes(3); + expect(provider.driver.findElementBoundingBox).toHaveBeenCalledTimes(3); expect(getRegionObjectSpy).toHaveBeenCalledTimes(3); - expect(elementsArray).toEqual([{}, {}, {}]); + expect(elementsArray).toEqual([xpathResponse, xpathResponse, xpathResponse]); }); it('should ignore xpath when element is not found', async () => { - spyOn(Driver.prototype, 'findElement').and.rejectWith(new Error('Element not found')); + spyOn(Driver.prototype, 'findElementBoundingBox').and.rejectWith(new Error('Element not found')); const xpaths = ['/xpath/1', '/xpath/2', '/xpath/3']; const elementsArray = await provider.getSeleniumRegionsBy('xpath', xpaths); - expect(provider.driver.findElement).toHaveBeenCalledTimes(3); + expect(provider.driver.findElementBoundingBox).toHaveBeenCalledTimes(3); expect(getRegionObjectSpy).not.toHaveBeenCalled(); expect(elementsArray).toEqual([]); }); @@ -246,48 +540,120 @@ describe('GenericProvider', () => { beforeEach(async () => { provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); await provider.createDriver(); - getRegionObjectSpy = spyOn(GenericProvider.prototype, 'getRegionObject').and.returnValue({}); + getRegionObjectSpy = spyOn(GenericProvider.prototype, 'getRegionObjectFromBoundingBox').and.returnValue({}); }); it('should add regions for each id', async () => { - spyOn(Driver.prototype, 'findElement').and.returnValue(Promise.resolve({ ELEMENT: 'mock_id' })); + spyOn(Driver.prototype, 'findElementBoundingBox').and.returnValue(Promise.resolve({ value: { x: 0, y: 100, height: 500, width: 300 } })); const ids = ['#id1', '#id2', '#id3']; const elementsArray = await provider.getSeleniumRegionsBy('css selector', ids); - expect(provider.driver.findElement).toHaveBeenCalledTimes(3); + expect(provider.driver.findElementBoundingBox).toHaveBeenCalledTimes(3); expect(getRegionObjectSpy).toHaveBeenCalledTimes(3); expect(elementsArray).toEqual([{}, {}, {}]); }); it('should ignore id when element is not found', async () => { - spyOn(Driver.prototype, 'findElement').and.rejectWith(new Error('Element not found')); + spyOn(Driver.prototype, 'findElementBoundingBox').and.rejectWith(new Error('Element not found')); const ids = ['#id1', '#id2', '#id3']; const elementsArray = await provider.getSeleniumRegionsBy('css selector', ids); - expect(provider.driver.findElement).toHaveBeenCalledTimes(3); + expect(provider.driver.findElementBoundingBox).toHaveBeenCalledTimes(3); expect(getRegionObjectSpy).not.toHaveBeenCalled(); expect(elementsArray).toEqual([]); }); }); + describe('getInitialPosition', () => { + let provider; + beforeEach(async () => { + provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); + provider.currentTag = { osName: 'Windows' }; + await provider.createDriver(); + }); + describe('when not IOS', () => { + it('should not get the initial scroll position', async () => { + await provider.getInitialPosition(); + expect(provider.initialScrollFactor).toEqual({ value: [0, 0] }); + }); + }); + + describe('when IOS', () => { + let executeScriptSpy; + beforeEach(() => { + provider.currentTag = { osName: 'iOS' }; + executeScriptSpy = spyOn(Driver.prototype, 'executeScript'); + }); + + afterEach(() => { + provider.currentTag = null; + }); + it('should get the initial scroll position', async () => { + spyOn(Driver.prototype, 'executeScript').and.returnValue({ value: [0, 200] }); + await provider.getInitialPosition(); + expect(executeScriptSpy).toHaveBeenCalledWith({ script: 'return [parseInt(window.scrollX), parseInt(window.scrollY)];', args: [] }); + expect(provider.initialScrollFactor).toEqual({ value: [0, 200] }); + }); + }); + }); + + describe('scrollToInitialPosition', () => { + let provider; + beforeEach(async () => { + provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); + provider.currentTag = { osName: 'Windows' }; + await provider.createDriver(); + }); + describe('when not IOS', () => { + it('should not scroll to position', async () => { + await provider.scrollToInitialPosition(0, 50); + expect(spyOn(Driver.prototype, 'executeScript')).toHaveBeenCalledTimes(0); + }); + }); + + describe('when IOS', () => { + let executeScriptSpy; + beforeEach(() => { + provider.currentTag = { osName: 'iOS' }; + provider.initialScrollFactor = { value: [0, 50] }; + executeScriptSpy = spyOn(Driver.prototype, 'executeScript'); + }); + + afterEach(() => { + provider.currentTag = null; + }); + it('should scroll to position', async () => { + await provider.scrollToInitialPosition(0, 50); + expect(executeScriptSpy).toHaveBeenCalledTimes(1); + expect(executeScriptSpy).toHaveBeenCalledWith({ script: 'window.scrollTo(0, 50)', args: [] }); + }); + }); + }); + describe('getSeleniumRegionsByElement', () => { let getRegionObjectSpy; + let getInitialPositionSpy; + let scrollToInitialPositionSpy; let provider; beforeEach(async () => { provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); await provider.createDriver(); getRegionObjectSpy = spyOn(GenericProvider.prototype, 'getRegionObject').and.returnValue({}); + getInitialPositionSpy = spyOn(GenericProvider.prototype, 'getInitialPosition'); + scrollToInitialPositionSpy = spyOn(GenericProvider.prototype, 'scrollToInitialPosition'); }); it('should add regions for each element', async () => { const elements = ['mockElement_1', 'mockElement_2', 'mockElement_3']; const elementsArray = await provider.getSeleniumRegionsByElement(elements); - + expect(getInitialPositionSpy).toHaveBeenCalledTimes(1); expect(getRegionObjectSpy).toHaveBeenCalledTimes(3); + expect(scrollToInitialPositionSpy).toHaveBeenCalledTimes(1); + expect(scrollToInitialPositionSpy).toHaveBeenCalledWith(provider.initialScrollFactor.value[0], provider.initialScrollFactor.value[1]); expect(elementsArray).toEqual([{}, {}, {}]); }); @@ -342,4 +708,107 @@ describe('GenericProvider', () => { expect(elementsArray).toEqual([]); }); }); + + describe('findRegions', () => { + let provider; + let doTransformationSpy; + let undoTransformationSpy; + let getSeleniumRegionsBySpy; + let getSeleniumRegionsByElementSpy; + let getSeleniumRegionsByLocationSpy; + const location = [ + { top: 100, bottom: 1090, left: 100, right: 200 } + ]; + + beforeEach(async () => { + provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); + await provider.createDriver(); + doTransformationSpy = spyOn(GenericProvider.prototype, 'doTransformations'); + undoTransformationSpy = spyOn(GenericProvider.prototype, 'undoTransformations'); + getSeleniumRegionsBySpy = spyOn(GenericProvider.prototype, 'getSeleniumRegionsBy').and.returnValue(Promise.resolve(location)); + getSeleniumRegionsByElementSpy = spyOn(GenericProvider.prototype, 'getSeleniumRegionsByElement').and.returnValue(Promise.resolve([])); + getSeleniumRegionsByLocationSpy = spyOn(GenericProvider.prototype, 'getSeleniumRegionsByLocation').and.returnValue(Promise.resolve([])); + }); + + describe('When no regions are passed', () => { + it('should return empty array when called and no transformation should be applied', async () => { + const xpath = []; + const selector = []; + const seleniumElements = []; + const customRegions = []; + const res = await provider.findRegions(xpath, selector, seleniumElements, customRegions); + expect(doTransformationSpy).not.toHaveBeenCalled(); + expect(undoTransformationSpy).not.toHaveBeenCalled(); + expect(res).toEqual([]); + }); + }); + + describe('When regions are passed', () => { + it('should return array when called transformation should be applied', async () => { + const xpath = ['/a/b/c']; + const selector = []; + const seleniumElements = []; + const customRegions = []; + await provider.findRegions(xpath, selector, seleniumElements, customRegions); + expect(doTransformationSpy).toHaveBeenCalled(); + expect(getSeleniumRegionsBySpy).toHaveBeenCalledTimes(2); + expect(getSeleniumRegionsByElementSpy).toHaveBeenCalledTimes(1); + expect(getSeleniumRegionsByLocationSpy).toHaveBeenCalledTimes(1); + expect(undoTransformationSpy).toHaveBeenCalled(); + }); + }); + }); + + describe('doTransformations', () => { + let provider; + let executeScriptSpy; + + beforeEach(async () => { + provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); + await provider.createDriver(); + executeScriptSpy = spyOn(Driver.prototype, 'executeScript'); + }); + + it('should do transfomation', async () => { + const hideScrollbarStyle = ` + /* Hide scrollbar for Chrome, Safari and Opera */ + ::-webkit-scrollbar { + display: none !important; + } + + /* Hide scrollbar for IE, Edge and Firefox */ + body, html { + -ms-overflow-style: none !important; /* IE and Edge */ + scrollbar-width: none !important; /* Firefox */ + }`.replace(/\n/g, ''); + const jsScript = ` + const e = document.createElement('style'); + e.setAttribute('class', 'poa-injected'); + e.innerHTML = '${hideScrollbarStyle}' + document.head.appendChild(e);`; + await provider.doTransformations(); + expect(executeScriptSpy).toHaveBeenCalledWith({ script: jsScript, args: [] }); + }); + }); + + describe('undoTransformations', () => { + let provider; + let executeScriptSpy; + + beforeEach(async () => { + provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {}); + await provider.createDriver(); + executeScriptSpy = spyOn(Driver.prototype, 'executeScript'); + }); + + it('should remove transfomation', async () => { + const data = '.abcdef'; + const jsScript = ` + const n = document.querySelectorAll('${data}'); + n.forEach((e) => {e.remove()});`; + + await provider.undoTransformations(data); + expect(executeScriptSpy).toHaveBeenCalledWith({ script: jsScript, args: [] }); + }); + }); }); From f5924b050d0c04f8ac63d610af291b32f51565f8 Mon Sep 17 00:00:00 2001 From: Amit Singh Sansoya Date: Fri, 24 Nov 2023 17:53:45 +0530 Subject: [PATCH 2/2] :bookmark: v1.27.5-beta.1 (#1442) --- lerna.json | 2 +- packages/cli-app/package.json | 6 +++--- packages/cli-build/package.json | 4 ++-- packages/cli-command/package.json | 8 ++++---- packages/cli-config/package.json | 4 ++-- packages/cli-exec/package.json | 4 ++-- packages/cli-snapshot/package.json | 4 ++-- packages/cli-upload/package.json | 4 ++-- packages/cli/package.json | 20 ++++++++++---------- packages/client/package.json | 6 +++--- packages/config/package.json | 4 ++-- packages/core/package.json | 12 ++++++------ packages/dom/package.json | 2 +- packages/env/package.json | 4 ++-- packages/logger/package.json | 2 +- packages/sdk-utils/package.json | 2 +- packages/webdriver-utils/package.json | 6 +++--- 17 files changed, 47 insertions(+), 47 deletions(-) diff --git a/lerna.json b/lerna.json index 6ddd619a5..731508892 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "packages": [ "packages/*" ], diff --git a/packages/cli-app/package.json b/packages/cli-app/package.json index 1271fecc2..fb45b4b1f 100644 --- a/packages/cli-app/package.json +++ b/packages/cli-app/package.json @@ -1,6 +1,6 @@ { "name": "@percy/cli-app", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -33,7 +33,7 @@ ] }, "dependencies": { - "@percy/cli-command": "1.27.5-beta.0", - "@percy/cli-exec": "1.27.5-beta.0" + "@percy/cli-command": "1.27.5-beta.1", + "@percy/cli-exec": "1.27.5-beta.1" } } diff --git a/packages/cli-build/package.json b/packages/cli-build/package.json index 9a0e0098c..f94ed3ac0 100644 --- a/packages/cli-build/package.json +++ b/packages/cli-build/package.json @@ -1,6 +1,6 @@ { "name": "@percy/cli-build", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -33,6 +33,6 @@ ] }, "dependencies": { - "@percy/cli-command": "1.27.5-beta.0" + "@percy/cli-command": "1.27.5-beta.1" } } diff --git a/packages/cli-command/package.json b/packages/cli-command/package.json index 4e65e738a..164234cec 100644 --- a/packages/cli-command/package.json +++ b/packages/cli-command/package.json @@ -1,6 +1,6 @@ { "name": "@percy/cli-command", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -36,8 +36,8 @@ "test:coverage": "yarn test --coverage" }, "dependencies": { - "@percy/config": "1.27.5-beta.0", - "@percy/core": "1.27.5-beta.0", - "@percy/logger": "1.27.5-beta.0" + "@percy/config": "1.27.5-beta.1", + "@percy/core": "1.27.5-beta.1", + "@percy/logger": "1.27.5-beta.1" } } diff --git a/packages/cli-config/package.json b/packages/cli-config/package.json index dcf3a684c..96e1c9dca 100644 --- a/packages/cli-config/package.json +++ b/packages/cli-config/package.json @@ -1,6 +1,6 @@ { "name": "@percy/cli-config", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -33,6 +33,6 @@ ] }, "dependencies": { - "@percy/cli-command": "1.27.5-beta.0" + "@percy/cli-command": "1.27.5-beta.1" } } diff --git a/packages/cli-exec/package.json b/packages/cli-exec/package.json index c73114405..5a2df4c3b 100644 --- a/packages/cli-exec/package.json +++ b/packages/cli-exec/package.json @@ -1,6 +1,6 @@ { "name": "@percy/cli-exec", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -33,7 +33,7 @@ ] }, "dependencies": { - "@percy/cli-command": "1.27.5-beta.0", + "@percy/cli-command": "1.27.5-beta.1", "cross-spawn": "^7.0.3", "which": "^2.0.2" } diff --git a/packages/cli-snapshot/package.json b/packages/cli-snapshot/package.json index f4de28ee6..b5b204ccf 100644 --- a/packages/cli-snapshot/package.json +++ b/packages/cli-snapshot/package.json @@ -1,6 +1,6 @@ { "name": "@percy/cli-snapshot", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -33,7 +33,7 @@ ] }, "dependencies": { - "@percy/cli-command": "1.27.5-beta.0", + "@percy/cli-command": "1.27.5-beta.1", "yaml": "^2.0.0" } } diff --git a/packages/cli-upload/package.json b/packages/cli-upload/package.json index cb9ea9663..b2dbd7729 100644 --- a/packages/cli-upload/package.json +++ b/packages/cli-upload/package.json @@ -1,6 +1,6 @@ { "name": "@percy/cli-upload", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -33,7 +33,7 @@ ] }, "dependencies": { - "@percy/cli-command": "1.27.5-beta.0", + "@percy/cli-command": "1.27.5-beta.1", "fast-glob": "^3.2.11", "image-size": "^1.0.0" } diff --git a/packages/cli/package.json b/packages/cli/package.json index aadc79507..251146ba6 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@percy/cli", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -31,14 +31,14 @@ "test:coverage": "yarn test --coverage" }, "dependencies": { - "@percy/cli-app": "1.27.5-beta.0", - "@percy/cli-build": "1.27.5-beta.0", - "@percy/cli-command": "1.27.5-beta.0", - "@percy/cli-config": "1.27.5-beta.0", - "@percy/cli-exec": "1.27.5-beta.0", - "@percy/cli-snapshot": "1.27.5-beta.0", - "@percy/cli-upload": "1.27.5-beta.0", - "@percy/client": "1.27.5-beta.0", - "@percy/logger": "1.27.5-beta.0" + "@percy/cli-app": "1.27.5-beta.1", + "@percy/cli-build": "1.27.5-beta.1", + "@percy/cli-command": "1.27.5-beta.1", + "@percy/cli-config": "1.27.5-beta.1", + "@percy/cli-exec": "1.27.5-beta.1", + "@percy/cli-snapshot": "1.27.5-beta.1", + "@percy/cli-upload": "1.27.5-beta.1", + "@percy/client": "1.27.5-beta.1", + "@percy/logger": "1.27.5-beta.1" } } diff --git a/packages/client/package.json b/packages/client/package.json index 25258e88c..b6df91372 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@percy/client", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -32,7 +32,7 @@ "test:coverage": "yarn test --coverage" }, "dependencies": { - "@percy/env": "1.27.5-beta.0", - "@percy/logger": "1.27.5-beta.0" + "@percy/env": "1.27.5-beta.1", + "@percy/logger": "1.27.5-beta.1" } } diff --git a/packages/config/package.json b/packages/config/package.json index 58866ea87..cdc83d3d1 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,6 +1,6 @@ { "name": "@percy/config", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -38,7 +38,7 @@ "test:types": "tsd" }, "dependencies": { - "@percy/logger": "1.27.5-beta.0", + "@percy/logger": "1.27.5-beta.1", "ajv": "^8.6.2", "cosmiconfig": "^8.0.0", "yaml": "^2.0.0" diff --git a/packages/core/package.json b/packages/core/package.json index b1718b3bc..bd91a1b92 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@percy/core", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -43,11 +43,11 @@ "test:types": "tsd" }, "dependencies": { - "@percy/client": "1.27.5-beta.0", - "@percy/config": "1.27.5-beta.0", - "@percy/dom": "1.27.5-beta.0", - "@percy/logger": "1.27.5-beta.0", - "@percy/webdriver-utils": "1.27.5-beta.0", + "@percy/client": "1.27.5-beta.1", + "@percy/config": "1.27.5-beta.1", + "@percy/dom": "1.27.5-beta.1", + "@percy/logger": "1.27.5-beta.1", + "@percy/webdriver-utils": "1.27.5-beta.1", "content-disposition": "^0.5.4", "cross-spawn": "^7.0.3", "extract-zip": "^2.0.1", diff --git a/packages/dom/package.json b/packages/dom/package.json index 9a0ba8337..d9450a352 100644 --- a/packages/dom/package.json +++ b/packages/dom/package.json @@ -1,6 +1,6 @@ { "name": "@percy/dom", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", diff --git a/packages/env/package.json b/packages/env/package.json index 43957d29d..bebd3cb66 100644 --- a/packages/env/package.json +++ b/packages/env/package.json @@ -1,6 +1,6 @@ { "name": "@percy/env", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -32,6 +32,6 @@ "test:coverage": "yarn test --coverage" }, "dependencies": { - "@percy/logger": "1.27.5-beta.0" + "@percy/logger": "1.27.5-beta.1" } } diff --git a/packages/logger/package.json b/packages/logger/package.json index a9f377c3b..c48fb1a3d 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -1,6 +1,6 @@ { "name": "@percy/logger", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", diff --git a/packages/sdk-utils/package.json b/packages/sdk-utils/package.json index a008192e4..ae0127061 100644 --- a/packages/sdk-utils/package.json +++ b/packages/sdk-utils/package.json @@ -1,6 +1,6 @@ { "name": "@percy/sdk-utils", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", diff --git a/packages/webdriver-utils/package.json b/packages/webdriver-utils/package.json index e6c989caa..0b2770e0d 100644 --- a/packages/webdriver-utils/package.json +++ b/packages/webdriver-utils/package.json @@ -1,6 +1,6 @@ { "name": "@percy/webdriver-utils", - "version": "1.27.5-beta.0", + "version": "1.27.5-beta.1", "license": "MIT", "repository": { "type": "git", @@ -29,7 +29,7 @@ "test:coverage": "yarn test --coverage" }, "dependencies": { - "@percy/config": "1.27.5-beta.0", - "@percy/sdk-utils": "1.27.5-beta.0" + "@percy/config": "1.27.5-beta.1", + "@percy/sdk-utils": "1.27.5-beta.1" } }