`, ``, and ``, use `renderer.getPaintedText()`.
The subpath re-exports **`@gpuix/native/testing`**, including `TestRenderer` and `hasNativeTestRenderer`.
## Automation
```ts
import { launch } from '@gpuix/solid/automation'
const app = await launch({
command: 'bun',
args: ['app.tsx'],
env: { GPUIX_BACKGROUND: '1' },
})
await app.getByTestId('bump').waitFor()
await app.getByTestId('bump').click()
await app.screenshot({ path: 'tmp/after-click.png' })
await app.close()
```
```ts
import { createTestRoot } from '@gpuix/solid/testing'
import { connectTest } from '@gpuix/solid/automation'
const { renderer, render } = createTestRoot()
render(() => )
const app = await connectTest(renderer)
await app.getByTestId('bump').click()
```
Mark targets with **`testId`**. `click()` hits last painted bounds. `fill()` and `press()` use the live GPUI input pipeline. They do not need window focus.
`@gpuix/solid/automation` re-exports **`@gpuix/native/automation`**: `launch`, `connectTest`, `connectStdio`, `App`, `Locator`.
A browser `render()` installs **`globalThis.gpuix`**.
## Shared host types
`@gpuix/solid` re-exports **`@gpuix/native/host`**. App code can import `StyleDesc`, `HostProps`, `findRanges`, and `createMutationQueue` from either package.
```ts
import { GpuixRenderer } from '@gpuix/solid'
import type { EventPayload, WindowOptions, StyleDesc } from '@gpuix/solid'
```
Host elements are the same as React:
| Element | Role |
| ---------------------------- | ------------------------- |
| `div` | Flex container |
| `text` | Selectable text |
| `input` / `textarea` | Native editors |
| `virtual-list` | Visible rows only |
| `code` / `diff` / `markdown` | Native text |
| `img` / `svg` | Images and tintable icons |
| `anchored` | Positioned overlay |
JSX adds Solid **`children`** and **`ref`** on top of `HostProps`.
## Compiler internals
These exist because **`babel-preset-solid`** targets `@gpuix/solid` as the universal module. Application code does not import them.
```ts
createElement, createTextNode, insert, insertNode, setProp,
spread, memo, effect, createComponent, mergeProps, use
```
```ts
import { jsx, jsxs, Fragment } from '@gpuix/solid/jsx-runtime'
```
`jsxImportSource` already points here. Do not import the JSX runtime by hand.
## React vs Solid
| | React | Solid |
| ----------- | -------------------------------------------- | ------------------------------------------------- |
| JSX | `"react-jsx"` | `"preserve"` |
| Mount | `render( )` | `render(() => )` |
| State | `useState` | `createSignal` |
| Window size | `useWindowSize()` | `createWindowSize()` |
| Find bar | `useTextSearch(options)` | `createTextSearch(() => options)` |
| Select root | `Select.Root` | `Select` |
| Tests | `createTestRoot()` then `root.render( )` | `createTestRoot()` then `app.render(() => )` |
The native addon, mutation queue, and automation client are shared. A Solid app and a React app can drive the same window types and the same `testId` locators.