Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.3.3",
"@vitest/browser-playwright": "^4.0.0-beta.15",
"@vitest/utils": "^4.0.15",
"bumpp": "^9.4.2",
"changelogithub": "^0.13.9",
"eslint": "^9.8.0",
Expand Down
18 changes: 18 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion src/pure.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import type { Locator, LocatorSelectors, PrettyDOMOptions } from 'vitest/browser'
import { page, utils } from 'vitest/browser'
import { page, server, utils } from 'vitest/browser'
import React from 'react'
import type { Container } from 'react-dom/client'
import ReactDOMClient from 'react-dom/client'
import { nanoid } from '@vitest/utils/helpers'

const { debug, getElementLocatorSelectors } = utils

function getTestIdAttribute() {
return server.config.browser.locators.testIdAttribute
}

let activeActs = 0

function setActEnvironment(env: boolean | undefined): void {
Expand Down Expand Up @@ -74,6 +79,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.setAttribute(getTestIdAttribute(), nanoid())
}

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>
}
41 changes: 41 additions & 0 deletions test/render.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import { page, userEvent } from 'vitest/browser'
import { Button } from 'react-aria-components'
import { Suspense } from 'react'
import { render } from 'vitest-browser-react'
import * as vitestUtilsHelpersModule from '@vitest/utils/helpers'
import { HelloWorld } from './fixtures/HelloWorld'
import { Counter } from './fixtures/Counter'
import { SuspendedHelloWorld } from './fixtures/SuspendedHelloWorld'
import { ComponentThatChanges } from './fixtures/ComponentThatChanges'

vi.mock('@vitest/utils/helpers', { spy: true })

test('renders simple component', async () => {
const screen = await render(<HelloWorld />)
Expand Down Expand Up @@ -49,3 +53,40 @@ 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 ({ skip, task }) => {
if (task.file.projectName === 'prod (chromium)') {
skip('Cannot mock nanoid in prod build')
}
vi.mocked(vitestUtilsHelpersModule.nanoid).mockImplementation(
() => 'Random id',
)

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>Render</div>)

const selector = page.elementLocator(screen.baseElement).selector

expect(selector).toEqual('internal:testid=[data-testid="Random id"s]')

vi.mocked(vitestUtilsHelpersModule.nanoid).mockRestore()
})

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()
})