Skip to content

Testing Guide

nexa-test-utils provides testing utilities inspired by Testing Library, designed for Nexa components.

Setup

ts
import { render, cleanup, fireEvent, screen, waitFor } from 'nexa-test-utils'
import { afterEach } from 'vitest'

afterEach(() => cleanup())

Rendering Components

ts
import { defineComponent, h, signal } from 'nexa-framework'

const Counter = defineComponent({
  setup() {
    const count = signal(0)
    return { count }
  },
  render(ctx) {
    return h('div', null, [
      h('span', null, String(ctx.count.value)),
      h('button', { onClick: () => ctx.count.value++ }, ['Increment']),
    ])
  },
})

const { container, unmount } = await render(Counter)

Render Options

ts
// Render into a custom container
const target = document.createElement('div')
const { container } = await render(MyComponent, target)

Querying Elements

ts
// Find by text (throws if not found)
const heading = screen.getByText('Hello Nexa')

// Find by text (returns null if not found)
const maybe = screen.queryByText('Optional')

// Find all matching text
const items = screen.getAllByText('Item')

// Find by role
const button = screen.getByRole('button')

Firing Events

ts
// Click
fireEvent.click(button)

// Input
fireEvent.input(input, 'new value')

// Keyboard
fireEvent.keydown(input, 'Enter')

// Focus / Blur
fireEvent.focus(input)
fireEvent.blur(input)

// Change
fireEvent.change(select)

Async Assertions

ts
await waitFor(() => {
  expect(screen.getByText('Loaded')).toBeTruthy()
})

// Custom timeout
await waitFor(
  () => expect(container.innerHTML).toContain('data'),
  { timeout: 2000, interval: 100 }
)

Full Example

ts
import { describe, it, expect, afterEach } from 'vitest'
import { render, cleanup, fireEvent, screen } from 'nexa-test-utils'
import { defineComponent, h, signal } from 'nexa-framework'

afterEach(() => cleanup())

describe('Counter', () => {
  it('increments on click', async () => {
    const Counter = defineComponent({
      setup() {
        const count = signal(0)
        return { count, increment: () => count.value++ }
      },
      render(ctx) {
        return h('div', null, [
          h('span', null, String(ctx.count.value)),
          h('button', { onClick: ctx.increment }, ['+']),
        ])
      },
    })

    await render(Counter)
    expect(screen.getByText('0')).toBeTruthy()

    fireEvent.click(screen.getByText('+'))
    expect(screen.getByText('1')).toBeTruthy()
  })
})

Released under the MIT License.