Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/pure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export async function render(
// default to document.body instead of documentElement to avoid output of potentially-large
// head elements (such as JSS style blocks) in debug output
baseElement = document.body
document.body.dataset.testid = 'test-body'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently attached the testid only in cases where baseElement was not provided.

So if consumers provides a different baseElement it might fail again.

Not sure if the library should always attach it or not.

Copy link
Member

@sheremet-va sheremet-va Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. The id needs to be generated to be unique, see nanoid for example - ported in VItest as https://github.com/vitest-dev/vitest/blob/8353defd6743925f363a7cf4d04f0297eaecc9af/packages/utils/src/nanoid.ts#L5
  2. testid name can be redefined by the user via browser.locators.testIdAttribute, I think just using id should be fine if it's not defined already, since the locator generator will always prefer it instead

Copy link
Author

@nizans nizans Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weirdly enough the generator prefers the text content in my attempt

I tried to look at https://github.com/sheremet-va/ivya/blob/56a31c992baab353f82b46f3cadde9292eb3076a/src/selectorGenerator.ts#L112C10-L112C29
Looks like it requires a deeper dive.
Maybe its a bug in the Ivya code ?

Screen.Recording.2025-12-15.at.18.51.39.mov

Copy link
Author

@nizans nizans Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can take a different approach and grab the testIdAttribute from the config and use it?

}

if (!container) {
Expand Down
17 changes: 17 additions & 0 deletions test/fixtures/ComponentThatChanges.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react'
import type { JSX } from 'react/jsx-runtime'

export function ComponentThatChanges({
timeout = 1500,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not artificially make our tests slower. Is there a better way to test this?

}: {
timeout?: number
}): JSX.Element {
const [show, setShow] = React.useState(false)

React.useEffect(() => {
const timer = setTimeout(() => setShow(true), timeout)
return () => clearTimeout(timer)
}, [timeout])

return <div>{show ? 'Hello Vitest!' : 'Loading...'}</div>
}
30 changes: 30 additions & 0 deletions test/render.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { render } from 'vitest-browser-react'
import { HelloWorld } from './fixtures/HelloWorld'
import { Counter } from './fixtures/Counter'
import { SuspendedHelloWorld } from './fixtures/SuspendedHelloWorld'
import { ComponentThatChanges } from './fixtures/ComponentThatChanges'

test('renders simple component', async () => {
const screen = await render(<HelloWorld />)
Expand Down Expand Up @@ -49,3 +50,32 @@ test('waits for suspended boundaries', async ({ onTestFinished }) => {
await result
expect(page.getByText('Hello Vitest')).toBeInTheDocument()
})

test('should use default testid as the root selector', async () => {
const stuff = document.createElement('div')
stuff.textContent = 'DOM content that might change'
document.body.appendChild(stuff)

setTimeout(() => {
stuff.textContent = 'Changed'
}, 1000)

const screen = await render(<div></div>)

expect(page.elementLocator(screen.baseElement).selector).toEqual(
'internal:testid=[data-testid="test-body"s]',
)
})

test('Should correctly select an element after dom changes', async () => {
const stuff = document.createElement('div')
stuff.textContent = 'DOM content that might change'
document.body.appendChild(stuff)
setTimeout(() => {
Copy link
Member

@sheremet-va sheremet-va Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this code doesn't break the test, that seems weird. With your changes or without

stuff.textContent = 'Changed'
}, 1000)

const screen = await render(<ComponentThatChanges />)

await expect.element(screen.getByText('Hello Vitest!')).toBeVisible()
})