Skip to content

Commit 23b74ad

Browse files
committed
Replace cypress with vitest
1 parent 8c695b1 commit 23b74ad

18 files changed

+156
-1271
lines changed

.github/workflows/e2e-tests.yml

Lines changed: 0 additions & 47 deletions
This file was deleted.

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
"typecheck": "turbo run typecheck",
1515
"test": "turbo run test",
1616
"coverage": "turbo run coverage",
17-
"e2e": "turbo run e2e",
1817
"docs:dev": "pnpm run --filter docs dev",
1918
"docs:build": "pnpm run --filter docs build",
2019
"docs:serve": "pnpm run --filter docs serve",
@@ -29,7 +28,6 @@
2928
"devDependencies": {
3029
"@changesets/cli": "^2.28.1",
3130
"@eslint/js": "^9.23.0",
32-
"cypress": "^14.2.0",
3331
"eslint": "^9.23.0",
3432
"eslint-config-prettier": "^10.1.1",
3533
"eslint-plugin-prettier": "^5.2.3",

packages/react/cypress.config.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

packages/react/cypress/component/form-tests.cy.tsx

Lines changed: 0 additions & 118 deletions
This file was deleted.

packages/react/cypress/support/commands.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

packages/react/cypress/support/component-index.html

Lines changed: 0 additions & 11 deletions
This file was deleted.

packages/react/cypress/support/component.tsx

Lines changed: 0 additions & 18 deletions
This file was deleted.

packages/react/package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@
4444
"dev": "tsup --project tsconfig.build.json --watch",
4545
"typecheck": "tsc",
4646
"test": "vitest run",
47-
"coverage": "vitest run --coverage",
48-
"e2e": "cypress run --component --browser chrome"
47+
"coverage": "vitest run --coverage"
4948
},
5049
"dependencies": {
5150
"@formulier/core": "workspace:*",
@@ -55,16 +54,15 @@
5554
"@formulier/core": "workspace:0.2.8",
5655
"@formulier/tsconfig": "workspace:*",
5756
"@testing-library/react": "^16.2.0",
57+
"@testing-library/user-event": "^14.6.1",
5858
"@types/react": "^19.0.12",
5959
"@types/react-dom": "^19.0.4",
6060
"@types/shallow-clone": "^3.0.2",
6161
"@types/use-sync-external-store": "^0.0.6",
6262
"@vitest/coverage-istanbul": "^3.0.9",
63-
"cypress": "^14.2.0",
6463
"jsdom": "^26.0.0",
6564
"react": "^19.0.0",
6665
"react-dom": "^19.0.0",
67-
"vite": "^6.2.2",
6866
"vitest": "^3.0.9"
6967
},
7068
"peerDependencies": {

packages/react/tests/form.test.tsx

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
2+
/* eslint-disable @typescript-eslint/no-unsafe-call */
3+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
4+
5+
import * as React from 'react'
6+
import {describe, expect, it} from 'vitest'
7+
import {render} from '@testing-library/react'
8+
import {userEvent} from '@testing-library/user-event'
9+
10+
import {FormProvider, useCreateForm, useFormInstance} from '../src/form.js'
11+
import {useFormField} from '../src/field.js'
12+
13+
const user = userEvent.setup()
14+
15+
function Form({children}: {children: React.ReactNode}) {
16+
const form = useCreateForm({initialValues: {field: 'value'}})
17+
return <FormProvider form={form}>{children}</FormProvider>
18+
}
19+
20+
function Field({name, validate}: {name: string; validate?: (value: unknown) => string | null}) {
21+
const form = useFormInstance()
22+
const [field, meta] = useFormField(form, {name, validate})
23+
return (
24+
<>
25+
<input
26+
data-testid="input"
27+
{...field}
28+
value={field.value || ''}
29+
onChange={event => field.onChange(event.target.value)}
30+
/>
31+
{meta.error ? <span data-testid="error">{meta.error}</span> : null}
32+
</>
33+
)
34+
}
35+
36+
describe('Form', () => {
37+
it('renders a basic field', () => {
38+
const {getByTestId} = render(
39+
<Form>
40+
<Field name="field" />
41+
</Form>,
42+
)
43+
expect(getByTestId('input')).toHaveValue('value')
44+
})
45+
46+
it('updates the value of the field', async () => {
47+
const {getByTestId} = render(
48+
<Form>
49+
<Field name="field" />
50+
</Form>,
51+
)
52+
await user.type(getByTestId('input'), '{backspace}{backspace}encia')
53+
expect(getByTestId('input')).toHaveValue('valencia')
54+
})
55+
56+
it('should not run validation initially', async () => {
57+
const {getByTestId, queryByTestId} = render(
58+
<Form>
59+
<Field name="field" validate={value => (value !== 'valencia' ? 'Value should be "valencia"' : null)} />
60+
</Form>,
61+
)
62+
await user.type(getByTestId('input'), '{backspace}{backspace}encia')
63+
expect(queryByTestId('error')).not.toBeInTheDocument()
64+
})
65+
66+
it('should run validation after blur', async () => {
67+
const {getByTestId} = render(
68+
<Form>
69+
<Field name="field" validate={value => (value !== 'valencia' ? 'Value should be "valencia"' : null)} />
70+
</Form>,
71+
)
72+
await user.type(getByTestId('input'), '{backspace}{backspace}{tab}')
73+
expect(getByTestId('error')).toHaveTextContent('Value should be "valencia"')
74+
})
75+
76+
it('should run validation continually once blurred', async () => {
77+
const {getByTestId, queryByTestId} = render(
78+
<Form>
79+
<Field name="field" validate={value => (value !== 'valencia' ? 'Value should be "valencia"' : null)} />
80+
</Form>,
81+
)
82+
await user.click(getByTestId('input'))
83+
await user.type(getByTestId('input'), '{tab}{shift>}{tab}{/shift}')
84+
await user.type(getByTestId('input'), '{backspace}{backspace}')
85+
expect(getByTestId('error')).toHaveTextContent('Value should be "valencia"')
86+
await user.type(getByTestId('input'), 'en')
87+
expect(getByTestId('error')).toHaveTextContent('Value should be "valencia"')
88+
await user.type(getByTestId('input'), 'cia')
89+
expect(queryByTestId('error')).not.toBeInTheDocument()
90+
})
91+
92+
it('should clear value after unmount', async () => {
93+
function Test() {
94+
const [show, setShow] = React.useState(true)
95+
96+
return (
97+
<Form>
98+
{show && (
99+
<Field name="field" validate={value => (value !== 'valencia' ? 'Value should be "valencia"' : null)} />
100+
)}
101+
<button data-testid="toggle" type="button" onClick={() => setShow(show => !show)}>
102+
Toggle field
103+
</button>
104+
</Form>
105+
)
106+
}
107+
const {getByTestId, queryByTestId} = render(<Test />)
108+
expect(getByTestId('input')).toHaveValue('value')
109+
await user.click(getByTestId('toggle'))
110+
expect(queryByTestId('input')).not.toBeInTheDocument()
111+
await user.click(getByTestId('toggle'))
112+
expect(queryByTestId('input')).toBeInTheDocument()
113+
expect(getByTestId('input')).toHaveValue('')
114+
})
115+
})

packages/react/tests/test-setup.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import '@testing-library/jest-dom/vitest'
2+
import {cleanup} from '@testing-library/react'
3+
import {afterEach} from 'vitest'
4+
5+
// https://testing-library.com/docs/react-testing-library/api#cleanup
6+
afterEach(() => cleanup())

0 commit comments

Comments
 (0)