MCPcopy
hub / github.com/vitest-dev/vitest / element

Function element

packages/browser/src/client/tester/expect-element.ts:12–84  ·  view source on GitHub ↗
(elementOrLocator: T, options?: ExpectPollOptions)

Source from the content-addressed store, hash-verified

10const kLocator = Symbol.for('$$vitest:locator')
11
12function element<T extends HTMLElement | SVGElement | null | Locator>(elementOrLocator: T, options?: ExpectPollOptions): PromisifyDomAssertion<HTMLElement | SVGElement | null> {
13 if (elementOrLocator != null && !(elementOrLocator instanceof HTMLElement) && !(elementOrLocator instanceof SVGElement) && !(kLocator in elementOrLocator)) {
14 throw new Error(`Invalid element or locator: ${elementOrLocator}. Expected an instance of HTMLElement, SVGElement or Locator, received ${getType(elementOrLocator)}`)
15 }
16
17 const expectElement = expect.poll<HTMLElement | SVGElement | null>(function element(this: object) {
18 if (elementOrLocator instanceof Element || elementOrLocator == null) {
19 return elementOrLocator
20 }
21
22 const isNot = chai.util.flag(this, 'negate') as boolean
23 const name = chai.util.flag(this, '_name') as string
24 // special case for `toBeInTheDocument` matcher
25 if (isNot && name === 'toBeInTheDocument') {
26 return elementOrLocator.query()
27 }
28 if (name === 'toHaveLength') {
29 // we know that `toHaveLength` requires multiple elements,
30 // but types generally expect a single one
31 return elementOrLocator.elements() as unknown as HTMLElement
32 }
33
34 if (name === 'toMatchScreenshot' && !chai.util.flag(this, '_poll.assert_once')) {
35 // `toMatchScreenshot` should only run once after the element resolves
36 chai.util.flag(this, '_poll.assert_once', true)
37 }
38
39 // element selector uses prettyDOM under the hood, which is an expensive call
40 // that should not be called on each failed locator attempt to avoid memory leak:
41 // https://github.com/vitest-dev/vitest/issues/7139
42 const isLastPollAttempt = chai.util.flag(this, '_isLastPollAttempt')
43
44 if (isLastPollAttempt) {
45 return elementOrLocator.element()
46 }
47
48 const result = elementOrLocator.query()
49
50 if (!result) {
51 throw new Error(`Cannot find element with locator: ${JSON.stringify(elementOrLocator)}`)
52 }
53
54 return result
55 }, processTimeoutOptions(options))
56
57 chai.util.flag(expectElement, '_poll.element', true)
58
59 // ask `expect.poll` to invoke trace after the assertion
60 const currentTest = getWorkerState().current
61 if (currentTest && getBrowserState().activeTraceTaskIds.has(currentTest.id)) {
62 const sourceError = new Error('__vitest_mark_trace__')
63 chai.util.flag(expectElement, '_poll.onSettled', async (meta: { assertion: Assertion; status: 'pass' | 'fail' }) => {
64 const isNot = chai.util.flag(meta.assertion, 'negate')
65 const name = chai.util.flag(meta.assertion, '_name') || '<unknown>'
66 const baseName = `expect.element().${isNot ? 'not.' : ''}${name}`
67 const traceName = meta.status === 'fail' ? `${baseName} [ERROR]` : baseName
68 const selector = !elementOrLocator || elementOrLocator instanceof Element
69 ? undefined

Callers

nothing calls this directly

Calls 9

processTimeoutOptionsFunction · 0.90
getWorkerStateFunction · 0.90
getBrowserStateFunction · 0.90
queryMethod · 0.80
elementsMethod · 0.80
elementMethod · 0.80
triggerCommandMethod · 0.80
getTypeFunction · 0.50
hasMethod · 0.45

Tested by

no test coverage detected