Skip to content

Commit 17f13e9

Browse files
committed
feat: update getMobileViewPortPosition
- fix tests
1 parent 3a90f87 commit 17f13e9

3 files changed

Lines changed: 40 additions & 36 deletions

File tree

packages/image-comparison-core/src/helpers/utils.interfaces.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { Executor } from '../methods/methods.interfaces.js'
21
import type { DeviceRectangles } from '../methods/rectangles.interfaces.js'
32

43
export interface GetAndCreatePathOptions {
@@ -109,7 +108,6 @@ export interface GetMobileViewPortPositionOptions {
109108
isAndroid: boolean,
110109
isIOS: boolean,
111110
methods: {
112-
executor: Executor,
113111
getUrl: () => Promise<string>,
114112
url: (arg:string) => Promise<WebdriverIO.Request|void>,
115113
}

packages/image-comparison-core/src/helpers/utils.test.ts

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import {
3434
import type { FormatFileNameOptions, GetAndCreatePathOptions } from './utils.interfaces.js'
3535
import { IMAGE_STRING } from '../mocks/mocks.js'
3636
import { DEVICE_RECTANGLES } from './constants.js'
37-
import { injectWebviewOverlay } from '../clientSideScripts/injectWebviewOverlay.js'
3837
import { getMobileWebviewClickAndDimensions } from '../clientSideScripts/getMobileWebviewClickAndDimensions.js'
3938
import { checkMetaTag } from '../clientSideScripts/checkMetaTag.js'
4039
import type { ClassOptions } from './options.interfaces.js'
@@ -737,51 +736,60 @@ describe('utils', () => {
737736

738737
describe('executeNativeClick', () => {
739738
const coords = { x: 100, y: 200 }
739+
let mockBrowser: any
740+
741+
beforeEach(async () => {
742+
vi.clearAllMocks()
743+
const { browser } = await vi.importMock('@wdio/globals') as any
744+
mockBrowser = browser
745+
})
740746

741747
afterEach(() => {
742748
vi.clearAllMocks()
743749
})
744750

745-
it('should call executor with "mobile: tap" on iOS', async () => {
746-
const executor = vi.fn()
747-
await executeNativeClick({ executor, isIOS: true, ...coords })
751+
it('should call browser.execute with "mobile: tap" on iOS', async () => {
752+
mockBrowser.execute = vi.fn()
753+
754+
await executeNativeClick({ isIOS: true, ...coords })
748755

749-
expect(executor).toHaveBeenCalledWith('mobile: tap', coords)
756+
expect(mockBrowser.execute).toHaveBeenCalledWith('mobile: tap', coords)
750757
})
751758

752-
it('should call executor with "mobile: clickGesture" on Android (Appium 2)', async () => {
753-
const executor = vi.fn()
754-
await executeNativeClick({ executor, isIOS: false, ...coords })
759+
it('should call browser.execute with "mobile: clickGesture" on Android (Appium 2)', async () => {
760+
mockBrowser.execute = vi.fn()
761+
762+
await executeNativeClick({ isIOS: false, ...coords })
755763

756-
expect(executor).toHaveBeenCalledWith('mobile: clickGesture', coords)
764+
expect(mockBrowser.execute).toHaveBeenCalledWith('mobile: clickGesture', coords)
757765
})
758766

759767
it('should fall back to "doubleClickGesture" when clickGesture fails (Appium 1)', async () => {
760-
const executor = vi.fn()
768+
mockBrowser.execute = vi.fn()
761769
.mockRejectedValueOnce(new Error('WebDriverError: Unknown mobile command: clickGesture'))
762770
.mockResolvedValueOnce(undefined)
763771
const logWarnMock = vi.spyOn(log, 'warn')
764772

765-
await executeNativeClick({ executor, isIOS: false, ...coords })
773+
await executeNativeClick({ isIOS: false, ...coords })
766774

767-
expect(executor).toHaveBeenCalledWith('mobile: clickGesture', coords)
768-
expect(executor).toHaveBeenCalledWith('mobile: doubleClickGesture', coords)
775+
expect(mockBrowser.execute).toHaveBeenCalledWith('mobile: clickGesture', coords)
776+
expect(mockBrowser.execute).toHaveBeenCalledWith('mobile: doubleClickGesture', coords)
769777
expect(logWarnMock).toHaveBeenCalledWith(expect.stringContaining('falling back to `doubleClickGesture`'))
770778

771779
logWarnMock.mockRestore()
772780
})
773781

774782
it('should throw the error if it\'s not a known Appium command error', async () => {
775-
const executor = vi.fn().mockRejectedValueOnce(new Error('Some unexpected error'))
783+
mockBrowser.execute = vi.fn().mockRejectedValueOnce(new Error('Some unexpected error'))
776784

777-
await expect(executeNativeClick({ executor, isIOS: false, ...coords }))
785+
await expect(executeNativeClick({ isIOS: false, ...coords }))
778786
.rejects
779787
.toThrowError('Some unexpected error')
780788
})
781789
})
782790

783791
describe('getMobileViewPortPosition', () => {
784-
const mockExecutor = vi.fn()
792+
let mockBrowser: any
785793
const mockUrl = vi.fn()
786794
const mockGetUrl = vi.fn().mockResolvedValue('http://example.com')
787795

@@ -793,22 +801,23 @@ describe('utils', () => {
793801
screenHeight: 800,
794802
screenWidth: 400,
795803
methods: {
796-
executor: mockExecutor,
797804
url: mockUrl,
798805
getUrl: mockGetUrl,
799806
},
800807
}
801808

802-
beforeEach(() => {
809+
beforeEach(async () => {
803810
vi.clearAllMocks()
811+
const { browser } = await vi.importMock('@wdio/globals') as any
812+
mockBrowser = browser
804813
})
805814

806815
it('should return correct device rectangles for iOS WebView flow', async () => {
807-
mockExecutor
808-
.mockResolvedValueOnce(undefined) // executor for the blob (loadBase64Html)
809-
.mockResolvedValueOnce(undefined) // checkMetaTag (loadBase64Html)
816+
mockBrowser.execute = vi.fn()
817+
.mockResolvedValueOnce(undefined) // loadBase64Html
818+
.mockResolvedValueOnce(undefined) // checkMetaTag
810819
.mockResolvedValueOnce(undefined) // injectWebviewOverlay
811-
.mockResolvedValueOnce(undefined) // nativeClick
820+
.mockResolvedValueOnce(undefined) // executeNativeClick
812821
.mockResolvedValueOnce({ x: 150, y: 300, width: 100, height: 100 }) // getMobileWebviewClickAndDimensions
813822

814823
const result = await getMobileViewPortPosition({
@@ -818,8 +827,7 @@ describe('utils', () => {
818827

819828
expect(mockGetUrl).toHaveBeenCalled()
820829
expect(mockUrl).toHaveBeenCalledTimes(1)
821-
expect(mockExecutor).toHaveBeenCalledWith(injectWebviewOverlay, false)
822-
expect(mockExecutor).toHaveBeenCalledWith(getMobileWebviewClickAndDimensions, '[data-test="ics-overlay"]')
830+
expect(mockBrowser.execute).toHaveBeenCalledWith(getMobileWebviewClickAndDimensions, '[data-test="ics-overlay"]')
823831

824832
expect(result).toMatchSnapshot()
825833
})
@@ -832,7 +840,7 @@ describe('utils', () => {
832840
})
833841

834842
expect(result).toEqual(DEVICE_RECTANGLES)
835-
expect(mockExecutor).not.toHaveBeenCalled()
843+
expect(mockBrowser.execute).not.toHaveBeenCalled()
836844
})
837845

838846
it('should return initialDeviceRectangles if Android + not nativeWebScreenshot', async () => {

packages/image-comparison-core/src/helpers/utils.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import type {
1414
ScreenshotSize,
1515
} from './utils.interfaces.js'
1616
import type { ClassOptions, CompareOptions } from './options.interfaces.js'
17-
import type { Executor } from '../methods/methods.interfaces.js'
1817
import { checkMetaTag } from '../clientSideScripts/checkMetaTag.js'
1918
import { injectWebviewOverlay } from '../clientSideScripts/injectWebviewOverlay.js'
2019
import { getMobileWebviewClickAndDimensions } from '../clientSideScripts/getMobileWebviewClickAndDimensions.js'
@@ -471,14 +470,14 @@ export async function loadBase64Html({ isIOS }: {isIOS: boolean}): Promise<void>
471470
/**
472471
* Execute a native click
473472
*/
474-
export async function executeNativeClick({ executor, isIOS, x, y }:{executor: Executor, isIOS:boolean, x: number, y: number}): Promise<void> {
473+
export async function executeNativeClick({ isIOS, x, y }:{ isIOS:boolean, x: number, y: number}): Promise<void> {
475474
if (isIOS) {
476-
return executor('mobile: tap', { x, y })
475+
return browser.execute('mobile: tap', { x, y })
477476
}
478477

479478
try {
480479
// The `clickGesture` is not working on Appium 1, only on Appium 2
481-
await executor('mobile: clickGesture', { x, y })
480+
await browser.execute('mobile: clickGesture', { x, y })
482481
} catch (error: unknown) {
483482
if (
484483
error instanceof Error &&
@@ -487,7 +486,7 @@ export async function executeNativeClick({ executor, isIOS, x, y }:{executor: Ex
487486
log.warn(
488487
'Error executing `clickGesture`, falling back to `doubleClickGesture`. This likely means you are using Appium 1. Is this intentional?'
489488
)
490-
await executor('mobile: doubleClickGesture', { x, y })
489+
await browser.execute('mobile: doubleClickGesture', { x, y })
491490
} else {
492491
throw error
493492
}
@@ -509,7 +508,6 @@ export async function getMobileViewPortPosition({
509508
isIOS,
510509
isNativeContext,
511510
methods: {
512-
executor,
513511
getUrl,
514512
url,
515513
},
@@ -523,15 +521,15 @@ export async function getMobileViewPortPosition({
523521
// 1. Load a base64 HTML page
524522
await loadBase64Html({ isIOS })
525523
// 2. Inject an overlay on top of the webview with an event listener that stores the click position in the webview
526-
await executor(injectWebviewOverlay, isAndroid)
524+
await browser.execute(injectWebviewOverlay, isAndroid)
527525
// 3. Click on the overlay in the center of the screen with a native click
528526
const nativeClickX = screenWidth / 2
529527
const nativeClickY = screenHeight / 2
530-
await executeNativeClick({ executor, isIOS, x: nativeClickX, y: nativeClickY })
528+
await executeNativeClick({ isIOS, x: nativeClickX, y: nativeClickY })
531529
// We need to wait a bit here, otherwise the click is not registered
532530
await waitFor(100)
533531
// 4a. Get the data from the overlay and remove it
534-
const { y, x, width, height } = await executor(getMobileWebviewClickAndDimensions, '[data-test="ics-overlay"]')
532+
const { y, x, width, height } = await browser.execute(getMobileWebviewClickAndDimensions, '[data-test="ics-overlay"]')
535533
// 4.b reset the url
536534
await url(currentUrl)
537535
// 5. Calculate the position of the viewport based on the click position of the native click vs the overlay

0 commit comments

Comments
 (0)