/// /// import path from 'node:path' import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest' import logger from '@wdio/logger' import PercyHandler from '../src/Percy/Percy-Handler.js' import PercyCaptureMap from '../src/Percy/PercyCaptureMap.js' import * as PercySDK from '../src/Percy/PercySDK.js' import type { Capabilities } from '@wdio/types' import * as PercyLogger from '../src/Percy/PercyLogger.js' import type { BeforeCommandArgs, AfterCommandArgs } from '@wdio/reporter' const log = logger('test') let percyHandler: PercyHandler let browser: WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser let caps: Capabilities.RemoteCapability vi.mock('got') vi.mock('@wdio/logger', () => import(path.join(process.cwd(), '__mocks__', '@wdio/logger'))) vi.useFakeTimers().setSystemTime(new Date('2020-01-01')) vi.mock('uuid', () => ({ v4: () => '123456789' })) const PercyLoggerSpy = vi.spyOn(PercyLogger.PercyLogger, 'logToFile') PercyLoggerSpy.mockImplementation(() => {}) beforeEach(() => { vi.mocked(log.info).mockClear() vi.mocked(fetch).mockClear() vi.mocked(fetch).mockResolvedValue(Response.json({ value: { automation_session: { browser_url: 'https://www.browserstack.com/automate/builds/1/sessions/2' } } })) browser = { sessionId: 'session123', config: {}, capabilities: { device: '', os: 'OS X', os_version: 'Catalina', browserName: 'chrome' }, instances: ['browserA', 'browserB'], isMultiremote: false, browserA: { sessionId: 'session456', capabilities: { 'bstack:options': { device: '', os: 'Windows', osVersion: 10, browserName: 'chrome' } } }, getInstance: vi.fn().mockImplementation((browserName: string) => browser[browserName]), browserB: {}, execute: vi.fn(), executeAsync: async () => { 'done' }, getUrl: () => { return 'https://www.google.com/'}, on: vi.fn(), } as unknown as WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser caps = { browserName: 'chrome', 'bstack:options': { os: 'OS X', osVersion: 'Catalina', accessibility: true } } as Capabilities.RemoteCapability percyHandler = new PercyHandler('manual', browser, caps, false, 'framework') }) it('should initialize correctly', () => { percyHandler = new PercyHandler('manual', browser, caps, false, 'framework') expect(percyHandler['_isAppAutomate']).toEqual(false) expect(percyHandler['_capabilities']).toEqual(caps) expect(percyHandler['_framework']).toEqual('framework') expect(percyHandler['_percyScreenshotCounter']).toEqual(0) }) describe('_setSessionName', () => { beforeEach(() => { percyHandler = new PercyHandler('manual', browser, caps, false, 'framework') }) it('sets sessionName property', async () => { percyHandler._setSessionName('1234') expect(percyHandler['_sessionName']).toEqual('1234') }) }) describe('teardown', () => { beforeEach(() => { percyHandler = new PercyHandler('manual', browser, caps, false, 'framework') }) it('resolves promise if _percyScreenshotCounter is 0', async () => { percyHandler.teardown().then(() => { expect(percyHandler['_percyScreenshotCounter']).toEqual(0) }).catch((err: any) => { expect(percyHandler['_percyScreenshotCounter']).not.equal(0) }) }) }) describe('afterScenario', () => { let percyAutoCaptureSpy: any let percyHandler: PercyHandler beforeEach(() => { percyHandler = new PercyHandler('manual', browser, caps, false, 'framework') percyHandler.before() percyAutoCaptureSpy = vi.spyOn(PercyHandler.prototype, 'percyAutoCapture') }) it('should not call percyAutoCapture', async () => { await percyHandler.afterScenario() expect(percyAutoCaptureSpy).not.toBeCalled() }) it('should call percyAutoCapture', async () => { percyHandler['_percyAutoCaptureMode'] = 'testcase' await percyHandler.afterScenario() expect(percyAutoCaptureSpy).toBeCalledTimes(1) }) afterEach(() => { percyAutoCaptureSpy.mockClear() }) }) describe('afterTest', () => { let percyAutoCaptureSpy: any let percyHandler: PercyHandler beforeEach(() => { percyHandler = new PercyHandler('manual', browser, caps, false, 'framework') percyHandler.before() percyAutoCaptureSpy = vi.spyOn(PercyHandler.prototype, 'percyAutoCapture') }) it('should not call percyAutoCapture', async () => { await percyHandler.afterTest() expect(percyAutoCaptureSpy).not.toBeCalled() }) it('should call percyAutoCapture', async () => { percyHandler['_percyAutoCaptureMode'] = 'testcase' await percyHandler.afterTest() expect(percyAutoCaptureSpy).toBeCalledTimes(1) }) afterEach(() => { percyAutoCaptureSpy.mockClear() }) }) describe('percyAutoCapture', () => { let percyScreenshotSpy: any let percyScreenshotAppSpy: any beforeEach(() => { percyHandler = new PercyHandler('auto', browser, caps, false, 'framework') percyHandler._setSessionName('1234') percyHandler.before() percyScreenshotSpy = vi.spyOn(PercySDK, 'screenshot').mockImplementation(() => Promise.resolve()) percyScreenshotAppSpy = vi.spyOn(PercySDK, 'screenshotApp').mockImplementation(() => Promise.resolve()) }) it('does not call Percy Selenium Screenshot', async () => { await percyHandler.percyAutoCapture(null, null) expect(percyScreenshotSpy).not.toBeCalled() }) it('calls Percy Selenium Screenshot', async () => { await percyHandler.percyAutoCapture('keys', null) expect(percyScreenshotSpy).toBeCalledTimes(1) }) it('calls Percy Appium Screenshot', async () => { percyHandler = new PercyHandler('auto', browser, caps, true, 'framework') await percyHandler.percyAutoCapture('keys', null) expect(percyScreenshotAppSpy).toBeCalledTimes(1) }) afterEach(() => { percyScreenshotSpy.mockClear() percyScreenshotAppSpy.mockClear() }) }) describe('browserCommand', () => { let percyAutoCaptureSpy: any let percyHandler: PercyHandler beforeEach(() => { percyHandler = new PercyHandler('auto', browser, caps, false, 'framework') percyHandler.before() percyAutoCaptureSpy = vi.spyOn(PercyHandler.prototype, 'deferCapture') }) it('should not call percyAutoCapture if no browser endpoint', async () => { const args = {} await percyHandler.browserAfterCommand(args as BeforeCommandArgs & AfterCommandArgs) expect(percyAutoCaptureSpy).not.toBeCalled() }) it('should call percyAutoCapture for event type keys', async () => { const args = { endpoint: 'actions', body: { actions: [{ type: 'key' }] } } await percyHandler.browserAfterCommand(args as BeforeCommandArgs & AfterCommandArgs) expect(percyAutoCaptureSpy).toBeCalledTimes(1) }) it('should call percyAutoCapture for event type click', async () => { const args = { endpoint: 'click' } await percyHandler.browserAfterCommand(args as BeforeCommandArgs & AfterCommandArgs) expect(percyAutoCaptureSpy).toBeCalledTimes(1) }) it('should call percyAutoCapture for event type screenshot', async () => { const args = { endpoint: 'screenshot' } await percyHandler.browserAfterCommand(args as BeforeCommandArgs & AfterCommandArgs) expect(percyAutoCaptureSpy).toBeCalledTimes(1) }) afterEach(() => { percyAutoCaptureSpy.mockClear() }) }) describe('percyCaptureMap', () => { let percyAutoCaptureMapGetNameSpy: any let percyAutoCaptureMapIncrementSpy: any let percyHandler: PercyHandler beforeEach(() => { percyHandler = new PercyHandler('auto', browser, caps, false, 'framework') percyHandler.before() percyAutoCaptureMapGetNameSpy = vi.spyOn(PercyCaptureMap.prototype, 'getName') percyAutoCaptureMapIncrementSpy = vi.spyOn(PercyCaptureMap.prototype, 'increment') }) it('should call getName method of PercyCaptureMap', async () => { await percyHandler.percyAutoCapture('keys', null) await percyHandler.percyAutoCapture('keys', null) expect(percyAutoCaptureMapGetNameSpy).toBeCalledTimes(2) }) it('should call getName method of PercyCaptureMap', async () => { await percyHandler.percyAutoCapture('click', null) await percyHandler.percyAutoCapture('click', null) expect(percyAutoCaptureMapIncrementSpy).toBeCalledTimes(2) }) afterEach(() => { percyAutoCaptureMapGetNameSpy.mockClear() percyAutoCaptureMapIncrementSpy.mockClear() }) })