Skip to content

Commit

Permalink
chore: Adds test for getElements Chromedriver error response
Browse files Browse the repository at this point in the history
  • Loading branch information
nextlevelbeard committed Aug 25, 2023
1 parent 2a09fd4 commit 57a0e5d
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 3 deletions.
27 changes: 24 additions & 3 deletions packages/webdriverio/src/utils/getElementObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,26 @@ interface GetElementProps {
isShadowElement?: boolean
}

interface ChromedriverErrorResponse {
error: string,
message: string
stacktrace: string,
}

class ChromedriverError extends Error {
constructor(obj: Error | ChromedriverErrorResponse) {

const { name, stack } = obj as Error
const { error, stacktrace } = obj as ChromedriverErrorResponse

super(error || name || '')
Object.assign(this, {
message: obj.message,
stack: stacktrace || stack,
})
}
}

/**
* transforms a findElement response into a WDIO element
* @param {string} selector selector that was used to query the element
Expand Down Expand Up @@ -91,7 +111,7 @@ export const getElement = function findElement(
export const getElements = function getElements(
this: WebdriverIO.Browser | WebdriverIO.Element,
selector: Selector | ElementReference[] | WebdriverIO.Element[],
elemResponse: (ElementReference | Error)[],
elemResponse: (ElementReference | Error | ChromedriverErrorResponse)[],
props: GetElementProps = { isReactElement: false, isShadowElement: false }
): ElementArray {
const browser = getBrowserObject(this as WebdriverIO.Element)
Expand All @@ -109,7 +129,7 @@ export const getElements = function getElements(
...getWDIOPrototype('element')
}

const elements = [elemResponse].flat(1).map((res: ElementReference | Element | Error, i) => {
const elements = [elemResponse].flat(1).map((res: ElementReference | Element | Error | ChromedriverErrorResponse, i) => {
/**
* if we already deal with an element, just return it
*/
Expand All @@ -133,7 +153,8 @@ export const getElements = function getElements(
const elementKey = this.isW3C ? ELEMENT_KEY : 'ELEMENT'
client[elementKey] = elementId
} else {
client.error = res as Error
res = res as ChromedriverErrorResponse | Error
client.error = res instanceof Error ? res : new ChromedriverError(res)
}

client.selector = Array.isArray(selector)
Expand Down
73 changes: 73 additions & 0 deletions packages/webdriverio/tests/utils/getElementObject.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import path from 'node:path'
import { describe, it, beforeEach, expect, vi } from 'vitest'
import { remote } from '../../src/index.js'

import * as getElem from '../../src/utils/getElementObject.js'

const origGetElem: typeof getElem = await vi.importActual('../../src/utils/getElementObject')

const chromedriverError = {
error: 'no such element',
message: 'no such element: No node with given id found\n (Session info: headless chrome=116.0.5845.50)',
stacktrace: 'Long\nStack\nTrace\n'
}

vi.mock('got')
vi.mock('@wdio/logger', () => import(path.join(process.cwd(), '__mocks__', '@wdio/logger')))
vi.mock('../../src/commands/element/waitForExist', () => ({
__esModule: true,
waitForExist: vi.fn().mockImplementation(() => { return true })
}))
vi.mock('../../src/utils/getElementObject.js', async () => {

const mod = {
getElement: vi.fn(),
getElements: vi.fn()
}

return { __esModule: true, ...mod, default: { ...mod } }
})

describe('getElements', () => {

let browser: WebdriverIO.Browser

beforeEach(async () => {

browser = await remote({
baseUrl: 'http://foobar.com',
capabilities: {
browserName: 'foobar'
}
})

vi.mocked(getElem.getElement).mockClear()
vi.mocked(getElem.getElements).mockClear()

vi.mocked(getElem.getElements).mockImplementation(
(elem, _res, props) => origGetElem
.getElements
.call(browser, elem, chromedriverError, props)
)
})

it('should deal with a Chromedriver error response', async () => {

const error = new Error()
Object.assign(error, {
name: chromedriverError.error,
message: chromedriverError.message,
stack: chromedriverError.stacktrace,
})

const elems = await browser.$$('#foo')
const [elem] = elems

expect(elems.foundWith).toBe('$$')

expect(elems).toHaveLength(1)

expect(elem.error).toBeInstanceOf(Error)
expect(elem).toEqual(expect.objectContaining({ error }))
})
})

0 comments on commit 57a0e5d

Please sign in to comment.