Skip to content

Commit

Permalink
Fixing FindRegion + Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Amit3200 committed Oct 22, 2023
1 parent d0eea0c commit fc03d0c
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 50 deletions.
26 changes: 12 additions & 14 deletions packages/webdriver-utils/src/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ export default class Driver {
this.passedCapabilities = passedCapabilities;
}

requestPostOptions(command) {
return {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(command)
};
}

async getCapabilites() {
return await Cache.withCache(Cache.caps, this.sessionId, async () => {
try {
Expand Down Expand Up @@ -43,13 +53,7 @@ export default class Driver {
if (!command.script.includes('browserstack_executor')) {
command.script = `/* percy_automate_script */ \n ${command.script}`;
}
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(command)
};
const options = this.requestPostOptions(command);
const baseUrl = `${this.executorUrl}/session/${this.sessionId}/execute/sync`;
const response = JSON.parse((await request(baseUrl, options)).body);
return response;
Expand All @@ -68,13 +72,7 @@ export default class Driver {
}

async findElement(using, value) {
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify({ using, value })
};
const options = this.requestPostOptions({ using, value });
const baseUrl = `${this.executorUrl}/session/${this.sessionId}/element`;
const response = JSON.parse((await request(baseUrl, options)).body);
return response.value;
Expand Down
1 change: 1 addition & 0 deletions packages/webdriver-utils/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default class WebdriverUtils {
const comparisonData = await automate.screenshot(snapshotName, options);
comparisonData.metadata.cliScreenshotStartTime = startTime;
comparisonData.metadata.cliScreenshotEndTime = Date.now();
log.debug(`[${snapshotName}] : Comparison Data: ${JSON.stringify(comparisonData)}`);
return comparisonData;
} catch (e) {
log.error(`[${snapshotName}] : Error - ${e.message}`);
Expand Down
2 changes: 1 addition & 1 deletion packages/webdriver-utils/src/metadata/desktopMetaData.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default class DesktopMetaData {

async screenResolution() {
return await Cache.withCache(Cache.resolution, this.driver.sessionId, async () => {
const data = await this.driver.executeScript({ script: 'return [(window.screen.width * window.devicePixelRatio).toString(), (window.screen.height * window.devicePixelRatio).toString()];', args: [] });
const data = await this.driver.executeScript({ script: 'return [parseInt(window.screen.width * window.devicePixelRatio).toString(), parseInt(window.screen.height * window.devicePixelRatio).toString()];', args: [] });
const screenInfo = data.value;
return `${screenInfo[0]} x ${screenInfo[1]}`;
});
Expand Down
4 changes: 0 additions & 4 deletions packages/webdriver-utils/src/providers/automateProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,6 @@ export default class AutomateProvider extends GenericProvider {
const resolution = await this.metaData.screenResolution();
const orientation = (this.metaData.orientation() || automateCaps.deviceOrientation)?.toLowerCase();

// for android window size only constitutes of browser viewport, hence adding nav / status / url bar heights
[this.header, this.footer] = await this.getHeaderFooter(deviceName, osVersion, browserName);
height = this.metaData.device() && osName?.toLowerCase() === 'android' ? height + this.header + this.footer : height;

return {
name: deviceName,
osName,
Expand Down
16 changes: 11 additions & 5 deletions packages/webdriver-utils/src/providers/genericProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export default class GenericProvider {
this.debugUrl = null;
this.header = 0;
this.footer = 0;
this.pageYShiftFactor = 0;
this.pageXShiftFactor = 0;
}

addDefaultOptions() {
Expand Down Expand Up @@ -89,6 +91,10 @@ export default class GenericProvider {
const tiles = await this.getTiles(this.header, this.footer, fullscreen);
log.debug(`[${name}] : Tiles ${JSON.stringify(tiles)}`);

const scrollFactors = await this.driver.executeScript({ script: 'return [parseInt(window.scrollX * window.devicePixelRatio), parseInt(window.scrollY * window.devicePixelRatio)];', args: [] });
this.pageYShiftFactor = tag.osName === 'iOS' ? tiles.tiles[0].statusBarHeight : (tiles.tiles[0].statusBarHeight - scrollFactors.value[1]);
this.pageXShiftFactor = tag.osName === 'iOS' ? 0 : (-scrollFactors.value[0]);

const ignoreRegions = await this.findRegions(
ignoreRegionXpaths, ignoreRegionSelectors, ignoreRegionElements, customIgnoreRegions
);
Expand Down Expand Up @@ -192,15 +198,15 @@ export default class GenericProvider {
}

async getRegionObject(selector, elementId) {
const scaleFactor = parseInt(await this.metaData.devicePixelRatio());
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 };
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(location.y * scaleFactor) + this.pageYShiftFactor,
bottom: Math.ceil((location.y + size.height) * scaleFactor) + this.pageYShiftFactor,
left: Math.floor(location.x * scaleFactor) + this.pageXShiftFactor,
right: Math.ceil((location.x + size.width) * scaleFactor) + this.pageXShiftFactor
};

const jsonObject = {
Expand Down
14 changes: 14 additions & 0 deletions packages/webdriver-utils/test/driver.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,18 @@ describe('Driver', () => {
expect(res).toEqual('mockVal');
});
});

describe('requestPostOptions', () => {
const command = { simple: 'test' };
const expectedResponse = {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(command)
};
it('returns post options', () => {
expect(driver.requestPostOptions(command)).toEqual(expectedResponse);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ describe('DesktopMetaData', () => {
screenInfo = await desktopMetaData.screenResolution();
expect(screenInfo).toEqual('1980 x 1080');
expect(executeScriptSpy)
.toHaveBeenCalledWith({ script: 'return [(window.screen.width * window.devicePixelRatio).toString(), (window.screen.height * window.devicePixelRatio).toString()];', args: [] });
.toHaveBeenCalledWith({ script: 'return [parseInt(window.screen.width * window.devicePixelRatio).toString(), parseInt(window.screen.height * window.devicePixelRatio).toString()];', args: [] });
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ describe('AutomateProvider', () => {

beforeEach(async () => {
spyOn(Driver.prototype, 'getCapabilites');
spyOn(GenericProvider.prototype, 'getHeaderFooter').and.returnValue(Promise.resolve([123, 456]));
browserstackExecutorSpy = spyOn(AutomateProvider.prototype, 'browserstackExecutor')
.and.returnValue(Promise.resolve({ value: '{ "result": "{\\"dom_sha\\": \\"abc\\", \\"sha\\": [\\"abc-1\\", \\"xyz-2\\"]}", "success":true }' }));
executeScriptSpy = spyOn(Driver.prototype, 'executeScript')
Expand Down Expand Up @@ -244,7 +243,6 @@ describe('AutomateProvider', () => {
let windowSizeSpy;
let orientationSpy;
let resolutionSpy;
let getHeaderFooterSpy;
let percyBuildInfo = {
id: '123',
url: 'https://percy.io/abc/123'
Expand All @@ -256,7 +254,6 @@ describe('AutomateProvider', () => {
percyScreenshotBeginSpy = spyOn(AutomateProvider.prototype,
'percyScreenshotBegin').and.returnValue({ value: '{"buildHash":"12e3","sessionHash":"abc1d","capabilities":{"browserName":"chrome","browserVersion":"113.0","os":"win11","os_version":"11","deviceOrientation":false,"resolution":["1920","1080"]},"success":true,"deviceName":"x.x.x.x"}' });
spyOn(Driver.prototype, 'getCapabilites');
getHeaderFooterSpy = spyOn(GenericProvider.prototype, 'getHeaderFooter').and.returnValue(Promise.resolve([0, 0]));
windowSizeSpy = spyOn(DesktopMetaData.prototype, 'windowSize')
.and.returnValue(Promise.resolve({ width: 1000, height: 1000 }));
resolutionSpy = spyOn(DesktopMetaData.prototype, 'screenResolution')
Expand All @@ -275,7 +272,6 @@ describe('AutomateProvider', () => {
expect(windowSizeSpy).toHaveBeenCalledTimes(1);
expect(resolutionSpy).toHaveBeenCalledTimes(1);
expect(orientationSpy).toHaveBeenCalledTimes(1);
expect(getHeaderFooterSpy).toHaveBeenCalledTimes(1);
expect(res).toEqual({
name: 'Windows_11_chrome_113',
osName: 'Windows',
Expand All @@ -296,7 +292,6 @@ describe('AutomateProvider', () => {
percyScreenshotBeginSpy = spyOn(AutomateProvider.prototype,
'percyScreenshotBegin').and.returnValue({ value: '{"buildHash":"12e3","sessionHash":"abc1d","capabilities":{"browserName":"chrome_android","browserVersion":"chrome_android","os":"android","os_version":"11","deviceOrientation":"portrait","resolution":["1920","1080"]},"success":true,"deviceName":"Samsung Galaxy S21"}' });
spyOn(Driver.prototype, 'getCapabilites');
getHeaderFooterSpy = spyOn(GenericProvider.prototype, 'getHeaderFooter').and.returnValue(Promise.resolve([0, 0]));
windowSizeSpy = spyOn(MobileMetaData.prototype, 'windowSize')
.and.returnValue(Promise.resolve({ width: 1000, height: 1000 }));
resolutionSpy = spyOn(MobileMetaData.prototype, 'screenResolution')
Expand All @@ -315,7 +310,6 @@ describe('AutomateProvider', () => {
expect(windowSizeSpy).toHaveBeenCalledTimes(1);
expect(resolutionSpy).toHaveBeenCalledTimes(1);
expect(orientationSpy).toHaveBeenCalledTimes(1);
expect(getHeaderFooterSpy).toHaveBeenCalledTimes(1);
expect(res).toEqual({
name: 'Samsung Galaxy S21',
osName: 'Android',
Expand Down
75 changes: 56 additions & 19 deletions packages/webdriver-utils/test/providers/genericProvider.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,13 @@ describe('GenericProvider', () => {
let getTilesSpy;

beforeEach(() => {
const scrollFactors = { value: [0, 10] };
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 }));
spyOn(Driver.prototype, 'executeScript')
.and.returnValue(scrollFactors);
});

it('calls correct funcs', async () => {
Expand Down Expand Up @@ -184,28 +187,62 @@ describe('GenericProvider', () => {
describe('getRegionObject', () => {
let provider;
let mockLocation = { x: 10, y: 20, width: 100, height: 200 };
beforeEach(() => {
// mock metadata
provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {});
spyOn(DesktopMetaData.prototype, 'devicePixelRatio')
.and.returnValue(1);
spyOn(Driver.prototype, 'rect').and.returnValue(Promise.resolve(mockLocation));

describe('When on Tile 0', () => {
beforeEach(() => {
// mock metadata
provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {});
spyOn(DesktopMetaData.prototype, 'devicePixelRatio')
.and.returnValue(1);
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
});
});
});

it('should return a JSON object with the correct selector and coordinates', async () => {
await provider.createDriver();
describe('When on Tile 1', () => {
beforeEach(() => {
// mock metadata
provider = new GenericProvider('123', 'http:executorUrl', { platform: 'win' }, {});
spyOn(DesktopMetaData.prototype, 'devicePixelRatio')
.and.returnValue(1);
spyOn(Driver.prototype, 'rect').and.returnValue(Promise.resolve(mockLocation));
provider.pageYShiftFactor = -10;
});

// 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
afterEach(() => {
provider.pageYShiftFactor = 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');

// 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
});
});
});
});
Expand Down

0 comments on commit fc03d0c

Please sign in to comment.