@opensaas/stack-ui 0.1.7 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +3 -2
- package/CHANGELOG.md +4 -0
- package/dist/components/AdminUI.d.ts +2 -1
- package/dist/components/AdminUI.d.ts.map +1 -1
- package/dist/components/AdminUI.js +2 -2
- package/dist/components/ItemFormClient.d.ts.map +1 -1
- package/dist/components/ItemFormClient.js +78 -60
- package/dist/components/Navigation.d.ts +2 -1
- package/dist/components/Navigation.d.ts.map +1 -1
- package/dist/components/Navigation.js +3 -2
- package/dist/components/UserMenu.d.ts +11 -0
- package/dist/components/UserMenu.d.ts.map +1 -0
- package/dist/components/UserMenu.js +18 -0
- package/dist/components/fields/TextField.d.ts +2 -1
- package/dist/components/fields/TextField.d.ts.map +1 -1
- package/dist/components/fields/TextField.js +4 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/primitives/button.d.ts +1 -1
- package/dist/styles/globals.css +24 -0
- package/package.json +14 -5
- package/src/components/AdminUI.tsx +3 -0
- package/src/components/ItemFormClient.tsx +84 -62
- package/src/components/Navigation.tsx +9 -20
- package/src/components/UserMenu.tsx +44 -0
- package/src/components/fields/TextField.tsx +7 -2
- package/src/index.ts +2 -0
- package/tests/browser/README.md +154 -0
- package/tests/browser/fields/CheckboxField.browser.test.tsx +245 -0
- package/tests/browser/fields/SelectField.browser.test.tsx +263 -0
- package/tests/browser/fields/TextField.browser.test.tsx +204 -0
- package/tests/browser/fields/__screenshots__/CheckboxField.browser.test.tsx/CheckboxField--Browser--edit-mode-should-not-be-clickable-when-disabled-1.png +0 -0
- package/tests/browser/fields/__screenshots__/CheckboxField.browser.test.tsx/CheckboxField--Browser--edit-mode-should-toggle-state-with-multiple-clicks-1.png +0 -0
- package/tests/browser/fields/__screenshots__/TextField.browser.test.tsx/TextField--Browser--edit-mode-should-handle-special-characters-1.png +0 -0
- package/tests/browser/fields/__screenshots__/TextField.browser.test.tsx/TextField--Browser--edit-mode-should-support-copy-and-paste-1.png +0 -0
- package/tests/browser/primitives/Button.browser.test.tsx +122 -0
- package/tests/browser/primitives/Dialog.browser.test.tsx +279 -0
- package/tests/browser/primitives/__screenshots__/Button.browser.test.tsx/Button--Browser--should-not-trigger-click-when-disabled-1.png +0 -0
- package/tests/components/CheckboxField.test.tsx +130 -0
- package/tests/components/DeleteButton.test.tsx +331 -0
- package/tests/components/IntegerField.test.tsx +147 -0
- package/tests/components/ListTable.test.tsx +457 -0
- package/tests/components/ListViewClient.test.tsx +415 -0
- package/tests/components/SearchBar.test.tsx +254 -0
- package/tests/components/SelectField.test.tsx +192 -0
- package/vitest.config.ts +20 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest'
|
|
2
|
+
import { render, screen } from '@testing-library/react'
|
|
3
|
+
import { SelectField } from '../../src/components/fields/SelectField.js'
|
|
4
|
+
|
|
5
|
+
describe('SelectField', () => {
|
|
6
|
+
const mockOptions = [
|
|
7
|
+
{ label: 'Draft', value: 'draft' },
|
|
8
|
+
{ label: 'Published', value: 'published' },
|
|
9
|
+
{ label: 'Archived', value: 'archived' },
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
describe('edit mode', () => {
|
|
13
|
+
it('should render select with label', () => {
|
|
14
|
+
render(
|
|
15
|
+
<SelectField
|
|
16
|
+
name="status"
|
|
17
|
+
value=""
|
|
18
|
+
onChange={vi.fn()}
|
|
19
|
+
label="Status"
|
|
20
|
+
options={mockOptions}
|
|
21
|
+
/>,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
expect(screen.getByText('Status')).toBeInTheDocument()
|
|
25
|
+
// Select is rendered as a button with role combobox
|
|
26
|
+
expect(screen.getByRole('combobox')).toBeInTheDocument()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('should display default placeholder when no value selected', () => {
|
|
30
|
+
render(
|
|
31
|
+
<SelectField
|
|
32
|
+
name="status"
|
|
33
|
+
value=""
|
|
34
|
+
onChange={vi.fn()}
|
|
35
|
+
label="Status"
|
|
36
|
+
options={mockOptions}
|
|
37
|
+
/>,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
// The component uses a hard-coded placeholder text
|
|
41
|
+
expect(screen.getByText('Select an option...')).toBeInTheDocument()
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('should display current selected value label', () => {
|
|
45
|
+
render(
|
|
46
|
+
<SelectField
|
|
47
|
+
name="status"
|
|
48
|
+
value="published"
|
|
49
|
+
onChange={vi.fn()}
|
|
50
|
+
label="Status"
|
|
51
|
+
options={mockOptions}
|
|
52
|
+
/>,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
// Should show the selected option label in the select trigger
|
|
56
|
+
expect(screen.getByText('Published')).toBeInTheDocument()
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('should show required indicator when required', () => {
|
|
60
|
+
render(
|
|
61
|
+
<SelectField
|
|
62
|
+
name="status"
|
|
63
|
+
value=""
|
|
64
|
+
onChange={vi.fn()}
|
|
65
|
+
label="Status"
|
|
66
|
+
options={mockOptions}
|
|
67
|
+
required
|
|
68
|
+
/>,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
expect(screen.getByText('*')).toBeInTheDocument()
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('should display error message', () => {
|
|
75
|
+
render(
|
|
76
|
+
<SelectField
|
|
77
|
+
name="status"
|
|
78
|
+
value=""
|
|
79
|
+
onChange={vi.fn()}
|
|
80
|
+
label="Status"
|
|
81
|
+
options={mockOptions}
|
|
82
|
+
error="Status is required"
|
|
83
|
+
/>,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
expect(screen.getByText('Status is required')).toBeInTheDocument()
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('should be disabled when disabled prop is true', () => {
|
|
90
|
+
render(
|
|
91
|
+
<SelectField
|
|
92
|
+
name="status"
|
|
93
|
+
value=""
|
|
94
|
+
onChange={vi.fn()}
|
|
95
|
+
label="Status"
|
|
96
|
+
options={mockOptions}
|
|
97
|
+
disabled
|
|
98
|
+
/>,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
const select = screen.getByRole('combobox')
|
|
102
|
+
expect(select).toBeDisabled()
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it('should render select trigger element', () => {
|
|
106
|
+
render(
|
|
107
|
+
<SelectField
|
|
108
|
+
name="status"
|
|
109
|
+
value=""
|
|
110
|
+
onChange={vi.fn()}
|
|
111
|
+
label="Status"
|
|
112
|
+
options={mockOptions}
|
|
113
|
+
/>,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
// Select trigger should be present
|
|
117
|
+
const select = screen.getByRole('combobox')
|
|
118
|
+
expect(select).toBeInTheDocument()
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
describe('read mode', () => {
|
|
123
|
+
it('should render selected value as text', () => {
|
|
124
|
+
render(
|
|
125
|
+
<SelectField
|
|
126
|
+
name="status"
|
|
127
|
+
value="published"
|
|
128
|
+
onChange={vi.fn()}
|
|
129
|
+
label="Status"
|
|
130
|
+
options={mockOptions}
|
|
131
|
+
mode="read"
|
|
132
|
+
/>,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
expect(screen.getByText('Status')).toBeInTheDocument()
|
|
136
|
+
expect(screen.getByText('Published')).toBeInTheDocument()
|
|
137
|
+
expect(screen.queryByRole('combobox')).not.toBeInTheDocument()
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
it('should show dash when no value selected', () => {
|
|
141
|
+
render(
|
|
142
|
+
<SelectField
|
|
143
|
+
name="status"
|
|
144
|
+
value=""
|
|
145
|
+
onChange={vi.fn()}
|
|
146
|
+
label="Status"
|
|
147
|
+
options={mockOptions}
|
|
148
|
+
mode="read"
|
|
149
|
+
/>,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
expect(screen.getByText('-')).toBeInTheDocument()
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
it('should show dash for invalid value', () => {
|
|
156
|
+
render(
|
|
157
|
+
<SelectField
|
|
158
|
+
name="status"
|
|
159
|
+
value="invalid"
|
|
160
|
+
onChange={vi.fn()}
|
|
161
|
+
label="Status"
|
|
162
|
+
options={mockOptions}
|
|
163
|
+
mode="read"
|
|
164
|
+
/>,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
expect(screen.getByText('-')).toBeInTheDocument()
|
|
168
|
+
})
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
describe('edge cases', () => {
|
|
172
|
+
it('should handle empty options array', () => {
|
|
173
|
+
render(<SelectField name="status" value="" onChange={vi.fn()} label="Status" options={[]} />)
|
|
174
|
+
|
|
175
|
+
expect(screen.getByRole('combobox')).toBeInTheDocument()
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it('should handle single option array', () => {
|
|
179
|
+
render(
|
|
180
|
+
<SelectField
|
|
181
|
+
name="status"
|
|
182
|
+
value=""
|
|
183
|
+
onChange={vi.fn()}
|
|
184
|
+
label="Status"
|
|
185
|
+
options={[{ label: 'Only Option', value: 'only' }]}
|
|
186
|
+
/>,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
expect(screen.getByRole('combobox')).toBeInTheDocument()
|
|
190
|
+
})
|
|
191
|
+
})
|
|
192
|
+
})
|
package/vitest.config.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineConfig } from 'vitest/config'
|
|
2
2
|
import react from '@vitejs/plugin-react'
|
|
3
3
|
import path from 'path'
|
|
4
|
+
import { playwright } from '@vitest/browser-playwright'
|
|
4
5
|
|
|
5
6
|
export default defineConfig({
|
|
6
7
|
plugins: [react()],
|
|
@@ -8,11 +9,30 @@ export default defineConfig({
|
|
|
8
9
|
environment: 'happy-dom',
|
|
9
10
|
globals: true,
|
|
10
11
|
setupFiles: ['./tests/setup.ts'],
|
|
12
|
+
// Exclude browser tests from regular test runs
|
|
13
|
+
exclude: process.env.BROWSER_TEST === 'true' ? [] : ['**/browser/**'],
|
|
14
|
+
// Include only browser tests when in browser mode
|
|
15
|
+
include:
|
|
16
|
+
process.env.BROWSER_TEST === 'true'
|
|
17
|
+
? ['tests/browser/**/*.test.{ts,tsx}']
|
|
18
|
+
: ['tests/**/*.test.{ts,tsx}', '!tests/browser/**'],
|
|
11
19
|
coverage: {
|
|
12
20
|
provider: 'v8',
|
|
13
21
|
reporter: ['text', 'json', 'html', 'json-summary'],
|
|
14
22
|
exclude: ['node_modules/', 'tests/', 'dist/', '**/*.d.ts', '**/*.config.*', '**/index.ts'],
|
|
15
23
|
},
|
|
24
|
+
// Browser mode configuration
|
|
25
|
+
browser: {
|
|
26
|
+
enabled: process.env.BROWSER_TEST === 'true',
|
|
27
|
+
instances: [
|
|
28
|
+
{
|
|
29
|
+
browser: 'chromium',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
provider: playwright(),
|
|
33
|
+
headless: true,
|
|
34
|
+
screenshotFailures: true,
|
|
35
|
+
},
|
|
16
36
|
},
|
|
17
37
|
resolve: {
|
|
18
38
|
alias: {
|