🏡 index : quine-global/webdriverio.git

import path from 'node:path'
import { expect, describe, it, vi, beforeEach } from 'vitest'
import logger from '@wdio/logger'
import { remote } from '../../../src/index.js'

vi.mock('fetch')
const log = logger('test')
vi.mock('@wdio/logger', () => import(path.join(process.cwd(), '__mocks__', '@wdio/logger')))

describe('getContext test', () => {
    let browser: WebdriverIO.Browser
    let androidContexts: any[] = []
    let iOSContexts: any[] = []
    let logSpy

    beforeEach(async () => {
        androidContexts = [
            { id: 'NATIVE_APP' },
            {
                id: 'WEBVIEW_com.wdiodemoapp',
                title: 'WebdriverIO',
                url: 'https://webdriver.io/',
                packageName: 'com.wdiodemoapp',
                webviewPageId: 'B32A3DC8B0FEA92C435CE26D51F46986',
            },
            {
                id: 'WEBVIEW_chrome',
                title: 'Android Chrome',
                url: 'https://www.google.com/',
                packageName: 'com.android.chrome',
                webviewPageId: '1A2B3C4D5E6F7G8H9I0J',
            },
        ]
        iOSContexts = [
            { id: 'NATIVE_APP' },
            {
                id: 'WEBVIEW_86150.1',
                title: 'WebdriverIO',
                url: 'https://webdriver.io/',
                bundleId: 'org.reactjs.native.example.wdiodemoapp',
            },
            {
                id: 'WEBVIEW_86152.1',
                title: 'Safari',
                url: 'https://www.apple.com/',
                bundleId: 'com.apple.mobilesafari',
            },
        ]
        vi.mocked(fetch).mockClear()
    })

    it('should return the current context as a string when no options are provided', async () => {
        browser = await remote({
            baseUrl: 'http://foobar.com',
            capabilities: {
                browserName: 'foobar',
                mobileMode: true,
            } as any,
        })

        const getAppiumContextSpy = vi.spyOn(browser, 'getAppiumContext').mockResolvedValue('NATIVE_APP')
        const result = await browser.getContext()

        expect(result).toEqual('NATIVE_APP')
        expect(getAppiumContextSpy).toHaveBeenCalledTimes(1)

        getAppiumContextSpy.mockRestore()
    })

    it('should return detailed context information for Android', async () => {
        browser = await remote({
            baseUrl: 'http://foobar.com',
            capabilities: {
                browserName: 'foobar',
                mobileMode: true,
                platformName: 'Android',
            } as any,
        })

        const getContextsSpy = vi.spyOn(browser, 'getContexts').mockResolvedValue(androidContexts)
        const getAppiumContextSpy = vi.spyOn(browser, 'getAppiumContext').mockResolvedValue('WEBVIEW_com.wdiodemoapp')
        const result = await browser.getContext({ returnDetailedContext: true })

        expect(getContextsSpy).toHaveBeenCalledTimes(1)
        expect(getAppiumContextSpy).toHaveBeenCalledTimes(1)
        expect(result).toEqual(androidContexts[1])

        getContextsSpy.mockRestore()
        getAppiumContextSpy.mockRestore()
    })

    it('should return detailed context information for iOS', async () => {
        browser = await remote({
            baseUrl: 'http://foobar.com',
            capabilities: {
                browserName: 'foobar',
                mobileMode: true,
                platformName: 'iOS',
            } as any,
        })

        const getContextsSpy = vi.spyOn(browser, 'getContexts').mockResolvedValue(iOSContexts)
        const getAppiumContextSpy = vi.spyOn(browser, 'getAppiumContext').mockResolvedValue('WEBVIEW_86150.1')
        const result = await browser.getContext({ returnDetailedContext: true })

        expect(getContextsSpy).toHaveBeenCalledTimes(1)
        expect(getAppiumContextSpy).toHaveBeenCalledTimes(1)
        expect(result).toEqual(iOSContexts[1])

        getContextsSpy.mockRestore()
        getAppiumContextSpy.mockRestore()
    })

    it('should log a warning and return a string if no detailed context is found', async () => {
        logSpy = vi.spyOn(log, 'warn')
        browser = await remote({
            baseUrl: 'http://foobar.com',
            capabilities: {
                browserName: 'foobar',
                mobileMode: true,
            } as any,
        })

        const getContextsSpy = vi.spyOn(browser, 'getContexts').mockResolvedValue([])
        const getAppiumContextSpy = vi.spyOn(browser, 'getAppiumContext').mockResolvedValue('WEBVIEW_unknown')

        const result = await browser.getContext({ returnDetailedContext: true })

        expect(getContextsSpy).toHaveBeenCalledTimes(1)
        expect(getAppiumContextSpy).toHaveBeenCalledTimes(1)
        expect(result).toEqual('WEBVIEW_unknown')
        expect(logSpy).toHaveBeenCalledWith(
            "We did not get back any detailed context for the current context 'WEBVIEW_unknown'. We will return the current context as a string."
        )

        logSpy.mockRestore()
        getContextsSpy.mockRestore()
        getAppiumContextSpy.mockRestore()
    })

    it('should throw an error for non-mobile platforms', async () => {
        browser = await remote({
            baseUrl: 'http://foobar.com',
            capabilities: {
                browserName: 'foobar',
            } as any,
        })
        await expect(browser.getContext()).rejects.toThrow(
            'The `getContext` command is only available for mobile platforms.'
        )
    })

    it('should log and return the first matching context when multiple detailed contexts are found', async () => {
        logSpy = vi.spyOn(log, 'warn')
        browser = await remote({
            baseUrl: 'http://foobar.com',
            capabilities: {
                browserName: 'foobar',
                mobileMode: true,
            } as any,
        })

        const getContextsSpy = vi.spyOn(browser, 'getContexts').mockResolvedValue([
            { id: 'WEBVIEW_duplicate' },
            { id: 'WEBVIEW_duplicate' },
        ])
        const getAppiumContextSpy = vi.spyOn(browser, 'getAppiumContext').mockResolvedValue('WEBVIEW_duplicate')

        const result = await browser.getContext({ returnDetailedContext: true })

        expect(getContextsSpy).toHaveBeenCalledTimes(1)
        expect(getAppiumContextSpy).toHaveBeenCalledTimes(1)
        expect(result).toEqual({ id: 'WEBVIEW_duplicate' })
        expect(logSpy).toHaveBeenCalledWith(
            "We found more than 1 detailed context for the current context 'WEBVIEW_duplicate'. We will return the first context."
        )

        logSpy.mockRestore()
        getContextsSpy.mockRestore()
        getAppiumContextSpy.mockRestore()
    })
})