@cdc/markup-include 4.25.8 → 4.25.10
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/dist/cdcmarkupinclude.js +17294 -11077
- package/package.json +11 -3
- package/src/CdcMarkupInclude.tsx +54 -74
- package/src/_stories/MarkupInclude.Editor.stories.tsx +465 -0
- package/src/_stories/MarkupInclude.stories.tsx +58 -58
- package/src/components/EditorPanel.tsx +27 -130
- package/src/data/initial-state.js +3 -2
- package/src/index.jsx +0 -1
- package/src/test/CdcMarkupInclude.test.jsx +8 -3
- package/src/types/Condition.ts +1 -1
- package/src/types/Config.ts +2 -1
- package/vite.config.js +1 -1
- package/src/coreStyles_markupinclude.scss +0 -1
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MARKUP INCLUDE EDITOR TESTS
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive test suite for the Markup Include component editor functionality.
|
|
5
|
+
* Tests all controls and verifies that editor interactions produce expected visual changes.
|
|
6
|
+
*
|
|
7
|
+
* RUNNING TESTS:
|
|
8
|
+
* ==============
|
|
9
|
+
* # Run all markup-include editor tests:
|
|
10
|
+
* npx vitest run --project=storybook packages/markup-include/src/_stories/*.Editor.stories.tsx
|
|
11
|
+
*
|
|
12
|
+
* # Run specific test story:
|
|
13
|
+
* npx vitest run --project=storybook packages/markup-include/src/_stories/MarkupInclude.Editor.stories.tsx -t "GeneralSectionTests"
|
|
14
|
+
*
|
|
15
|
+
* # Run tests in watch mode:
|
|
16
|
+
* npx vitest --project=storybook packages/markup-include/src/_stories/*.Editor.stories.tsx
|
|
17
|
+
*
|
|
18
|
+
* TEST COVERAGE:
|
|
19
|
+
* ==============
|
|
20
|
+
* ✅ General Section:
|
|
21
|
+
* - Title input and header display
|
|
22
|
+
*
|
|
23
|
+
* ✅ Content Editor Section:
|
|
24
|
+
* - Use Inline HTML toggle (switches between textarea and URL input)
|
|
25
|
+
* - HTML content editing and preview
|
|
26
|
+
* - Source URL input
|
|
27
|
+
* - Variable management (create, edit, delete)
|
|
28
|
+
* - Variable configuration (name, column, conditions, formatting)
|
|
29
|
+
* - Advanced options (Hide Section on Null, No Data Message)
|
|
30
|
+
*
|
|
31
|
+
* ✅ Visual Section:
|
|
32
|
+
* - Theme palette selection
|
|
33
|
+
* - Border display toggle
|
|
34
|
+
* - Border color theme toggle
|
|
35
|
+
* - Accent style toggle
|
|
36
|
+
* - Theme background color toggle
|
|
37
|
+
* - Hide background color toggle
|
|
38
|
+
*
|
|
39
|
+
* TESTING APPROACH:
|
|
40
|
+
* =================
|
|
41
|
+
* - Follows CDC testing best practices (visual-first testing)
|
|
42
|
+
* - Uses performAndAssert for state changes
|
|
43
|
+
* - Tests visual output changes, not just control state
|
|
44
|
+
* - Leverages shared testing helpers from @cdc/core/helpers/testing
|
|
45
|
+
* - Each test story focuses on one accordion section
|
|
46
|
+
* - Includes comprehensive variable system testing
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
50
|
+
import { within, userEvent, expect } from 'storybook/test'
|
|
51
|
+
import CdcMarkupInclude from '../CdcMarkupInclude'
|
|
52
|
+
import {
|
|
53
|
+
performAndAssert,
|
|
54
|
+
waitForPresence,
|
|
55
|
+
waitForAbsence,
|
|
56
|
+
waitForEditor,
|
|
57
|
+
openAccordion,
|
|
58
|
+
getVisualState,
|
|
59
|
+
testBooleanControl
|
|
60
|
+
} from '@cdc/core/helpers/testing'
|
|
61
|
+
|
|
62
|
+
const meta: Meta<typeof CdcMarkupInclude> = {
|
|
63
|
+
title: 'Components/Templates/Markup Include/Editor Tests',
|
|
64
|
+
component: CdcMarkupInclude,
|
|
65
|
+
parameters: {
|
|
66
|
+
layout: 'fullscreen'
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default meta
|
|
71
|
+
type Story = StoryObj<typeof CdcMarkupInclude>
|
|
72
|
+
|
|
73
|
+
// Test configurations - using both inline config and external fixtures
|
|
74
|
+
const testConfig = {
|
|
75
|
+
contentEditor: {
|
|
76
|
+
inlineHTML: '<h2>Test Markup Include</h2><p>{{test_variable}}</p>',
|
|
77
|
+
showHeader: true,
|
|
78
|
+
srcUrl: '',
|
|
79
|
+
title: 'Test Markup Include Title',
|
|
80
|
+
useInlineHTML: true,
|
|
81
|
+
showNoDataMessage: false,
|
|
82
|
+
noDataMessageText: 'No data available'
|
|
83
|
+
},
|
|
84
|
+
data: [
|
|
85
|
+
{ state: 'Alabama', value: 100, category: 'A' },
|
|
86
|
+
{ state: 'Alaska', value: 200, category: 'B' },
|
|
87
|
+
{ state: 'Arizona', value: 150, category: 'A' }
|
|
88
|
+
],
|
|
89
|
+
legend: {},
|
|
90
|
+
newViz: true,
|
|
91
|
+
theme: 'theme-blue',
|
|
92
|
+
type: 'markup-include',
|
|
93
|
+
visual: {
|
|
94
|
+
border: false,
|
|
95
|
+
accent: false,
|
|
96
|
+
background: false,
|
|
97
|
+
hideBackgroundColor: false,
|
|
98
|
+
borderColorTheme: false
|
|
99
|
+
},
|
|
100
|
+
markupVariables: [
|
|
101
|
+
{
|
|
102
|
+
name: 'test_variable',
|
|
103
|
+
columnName: 'value',
|
|
104
|
+
tag: '{{test_variable}}',
|
|
105
|
+
conditions: [],
|
|
106
|
+
addCommas: false
|
|
107
|
+
}
|
|
108
|
+
],
|
|
109
|
+
enableMarkupVariables: false,
|
|
110
|
+
version: '1.0.0'
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ============================================================================
|
|
114
|
+
// GENERAL SECTION TESTS
|
|
115
|
+
// Tests title input and display
|
|
116
|
+
// ============================================================================
|
|
117
|
+
export const GeneralSectionTests: Story = {
|
|
118
|
+
args: {
|
|
119
|
+
config: testConfig as any,
|
|
120
|
+
isEditor: true
|
|
121
|
+
},
|
|
122
|
+
play: async ({ canvasElement }) => {
|
|
123
|
+
const canvas = within(canvasElement)
|
|
124
|
+
await waitForEditor(canvas)
|
|
125
|
+
await openAccordion(canvas, 'General')
|
|
126
|
+
|
|
127
|
+
// ============================================================================
|
|
128
|
+
// TEST 1: Title Update
|
|
129
|
+
// Expectation: Header text updates to new string and becomes visible
|
|
130
|
+
// ============================================================================
|
|
131
|
+
const titleInput = canvasElement.querySelector('input[name*="title"]') as HTMLInputElement
|
|
132
|
+
expect(titleInput).toBeTruthy()
|
|
133
|
+
expect(titleInput.value).toBe('Test Markup Include Title')
|
|
134
|
+
|
|
135
|
+
await performAndAssert(
|
|
136
|
+
'Title Update',
|
|
137
|
+
() => {
|
|
138
|
+
const headerElement = canvasElement.querySelector('.cove-component__header h2')
|
|
139
|
+
return headerElement?.textContent?.trim() || ''
|
|
140
|
+
},
|
|
141
|
+
async () => {
|
|
142
|
+
await userEvent.clear(titleInput)
|
|
143
|
+
await userEvent.type(titleInput, 'Updated Markup Include Title E2E')
|
|
144
|
+
},
|
|
145
|
+
(before, after) => after === 'Updated Markup Include Title E2E' && after !== before
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
const headerElement = canvasElement.querySelector('.cove-component__header h2')
|
|
149
|
+
expect(headerElement).toBeTruthy()
|
|
150
|
+
expect(headerElement!.textContent?.trim()).toBe('Updated Markup Include Title E2E')
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// ============================================================================
|
|
155
|
+
// CONTENT EDITOR SECTION TESTS
|
|
156
|
+
// Tests ALL content editing functionality: basic controls, variables, and advanced features
|
|
157
|
+
// ============================================================================
|
|
158
|
+
export const ContentEditorTests: Story = {
|
|
159
|
+
args: {
|
|
160
|
+
config: testConfig as any,
|
|
161
|
+
isEditor: true
|
|
162
|
+
},
|
|
163
|
+
play: async ({ canvasElement }) => {
|
|
164
|
+
const canvas = within(canvasElement)
|
|
165
|
+
await waitForEditor(canvas)
|
|
166
|
+
await openAccordion(canvas, 'Content Editor')
|
|
167
|
+
|
|
168
|
+
// ============================================================================
|
|
169
|
+
// TEST 1: Use Inline HTML Toggle
|
|
170
|
+
// Expectation: Switching between inline HTML textarea and source URL input
|
|
171
|
+
// ============================================================================
|
|
172
|
+
const inlineHTMLCheckbox = canvasElement.querySelector('input[name*="useInlineHTML"]') as HTMLInputElement
|
|
173
|
+
expect(inlineHTMLCheckbox).toBeTruthy()
|
|
174
|
+
expect(inlineHTMLCheckbox.checked).toBe(true) // Should start as checked based on config
|
|
175
|
+
|
|
176
|
+
// Verify initial state - HTML textarea should be visible
|
|
177
|
+
let htmlTextarea = canvasElement.querySelector('textarea[name*="inlineHTML"]') as HTMLTextAreaElement
|
|
178
|
+
let srcUrlInput = canvasElement.querySelector('input[name*="srcUrl"]') as HTMLInputElement
|
|
179
|
+
expect(htmlTextarea).toBeTruthy()
|
|
180
|
+
expect(srcUrlInput).toBeFalsy() // Should not be visible when inline HTML is enabled
|
|
181
|
+
|
|
182
|
+
// Toggle to disable inline HTML (should show source URL input)
|
|
183
|
+
await performAndAssert(
|
|
184
|
+
'Toggle to Source URL Mode',
|
|
185
|
+
() => ({
|
|
186
|
+
hasTextarea: !!canvasElement.querySelector('textarea[name*="inlineHTML"]'),
|
|
187
|
+
hasSrcInput: !!canvasElement.querySelector('input[name*="srcUrl"]'),
|
|
188
|
+
checkboxChecked: inlineHTMLCheckbox.checked
|
|
189
|
+
}),
|
|
190
|
+
async () => {
|
|
191
|
+
// Click the checkbox wrapper to handle pointer-events issues
|
|
192
|
+
const checkboxWrapper = inlineHTMLCheckbox.closest('.cove-input__checkbox--small') || inlineHTMLCheckbox
|
|
193
|
+
await userEvent.click(checkboxWrapper as HTMLElement)
|
|
194
|
+
},
|
|
195
|
+
(before, after) =>
|
|
196
|
+
before.checkboxChecked !== after.checkboxChecked &&
|
|
197
|
+
before.hasTextarea !== after.hasTextarea &&
|
|
198
|
+
before.hasSrcInput !== after.hasSrcInput
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
// Verify textarea is gone and source URL input is visible
|
|
202
|
+
htmlTextarea = canvasElement.querySelector('textarea[name*="inlineHTML"]') as HTMLTextAreaElement
|
|
203
|
+
srcUrlInput = canvasElement.querySelector('input[name*="srcUrl"]') as HTMLInputElement
|
|
204
|
+
expect(htmlTextarea).toBeFalsy()
|
|
205
|
+
expect(srcUrlInput).toBeTruthy()
|
|
206
|
+
|
|
207
|
+
// Toggle back to inline HTML mode
|
|
208
|
+
const checkboxWrapper2 = inlineHTMLCheckbox.closest('.cove-input__checkbox--small') || inlineHTMLCheckbox
|
|
209
|
+
await userEvent.click(checkboxWrapper2 as HTMLElement)
|
|
210
|
+
await waitForPresence('textarea[name*="inlineHTML"]', canvasElement)
|
|
211
|
+
|
|
212
|
+
htmlTextarea = canvasElement.querySelector('textarea[name*="inlineHTML"]') as HTMLTextAreaElement
|
|
213
|
+
expect(htmlTextarea).toBeTruthy()
|
|
214
|
+
expect(htmlTextarea.value).toBe('<h2>Test Markup Include</h2><p>{{test_variable}}</p>')
|
|
215
|
+
|
|
216
|
+
// ============================================================================
|
|
217
|
+
// TEST 2: HTML Content Update
|
|
218
|
+
// Expectation: Changes to HTML textarea affect the rendered output
|
|
219
|
+
// ============================================================================
|
|
220
|
+
await performAndAssert(
|
|
221
|
+
'HTML Content Update',
|
|
222
|
+
() => {
|
|
223
|
+
const contentElement = canvasElement.querySelector('.cove-component__content')
|
|
224
|
+
return contentElement?.innerHTML || ''
|
|
225
|
+
},
|
|
226
|
+
async () => {
|
|
227
|
+
await userEvent.clear(htmlTextarea)
|
|
228
|
+
await userEvent.type(
|
|
229
|
+
htmlTextarea,
|
|
230
|
+
'<h3>Updated HTML Content</h3><p>New test content with {{{{test_variable}}</p>'
|
|
231
|
+
)
|
|
232
|
+
},
|
|
233
|
+
(before, after) => after !== before && after.includes('Updated HTML Content')
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
// ============================================================================
|
|
237
|
+
// TEST 3: Source URL Input (when in URL mode)
|
|
238
|
+
// Expectation: Source URL input accepts and stores values
|
|
239
|
+
// ============================================================================
|
|
240
|
+
// Switch back to source URL mode
|
|
241
|
+
const checkboxWrapper3 = inlineHTMLCheckbox.closest('.cove-input__checkbox--small') || inlineHTMLCheckbox
|
|
242
|
+
await userEvent.click(checkboxWrapper3 as HTMLElement)
|
|
243
|
+
await waitForPresence('input[name*="srcUrl"]', canvasElement)
|
|
244
|
+
|
|
245
|
+
srcUrlInput = canvasElement.querySelector('input[name*="srcUrl"]') as HTMLInputElement
|
|
246
|
+
expect(srcUrlInput).toBeTruthy()
|
|
247
|
+
|
|
248
|
+
await performAndAssert(
|
|
249
|
+
'Source URL Update and Content Loading',
|
|
250
|
+
() => ({
|
|
251
|
+
inputValue: srcUrlInput.value,
|
|
252
|
+
contentText: canvasElement.querySelector('.cove-component__content')?.textContent || ''
|
|
253
|
+
}),
|
|
254
|
+
async () => {
|
|
255
|
+
await userEvent.clear(srcUrlInput)
|
|
256
|
+
await userEvent.type(
|
|
257
|
+
srcUrlInput,
|
|
258
|
+
'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Markup-Include-Button-and-Text.html'
|
|
259
|
+
)
|
|
260
|
+
},
|
|
261
|
+
(before, after) => {
|
|
262
|
+
const expectedUrl =
|
|
263
|
+
'https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Markup-Include-Button-and-Text.html'
|
|
264
|
+
return (
|
|
265
|
+
after.inputValue === expectedUrl &&
|
|
266
|
+
after.inputValue !== before.inputValue &&
|
|
267
|
+
after.contentText.includes('Neque laoreet')
|
|
268
|
+
)
|
|
269
|
+
}
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
// Switch back to inline mode for subsequent tests
|
|
273
|
+
const checkboxWrapper4 = inlineHTMLCheckbox.closest('.cove-input__checkbox--small') || inlineHTMLCheckbox
|
|
274
|
+
await userEvent.click(checkboxWrapper4 as HTMLElement)
|
|
275
|
+
await waitForPresence('textarea[name*="inlineHTML"]', canvasElement)
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// ============================================================================
|
|
280
|
+
// VISUAL SECTION TESTS
|
|
281
|
+
// Tests theme and visual styling controls
|
|
282
|
+
// ============================================================================
|
|
283
|
+
export const VisualSectionTests: Story = {
|
|
284
|
+
args: {
|
|
285
|
+
config: testConfig as any,
|
|
286
|
+
isEditor: true
|
|
287
|
+
},
|
|
288
|
+
play: async ({ canvasElement }) => {
|
|
289
|
+
const canvas = within(canvasElement)
|
|
290
|
+
await waitForEditor(canvas)
|
|
291
|
+
await openAccordion(canvas, 'Visual')
|
|
292
|
+
|
|
293
|
+
const contentContainer = () => canvasElement.querySelector('.cove-component__content') as HTMLElement
|
|
294
|
+
const visualContainer = () => canvasElement.querySelector('.markup-include-component') as HTMLElement
|
|
295
|
+
expect(contentContainer()).toBeTruthy()
|
|
296
|
+
expect(visualContainer()).toBeTruthy()
|
|
297
|
+
|
|
298
|
+
// ============================================================================
|
|
299
|
+
// TEST 1: Theme Palette Change
|
|
300
|
+
// Expectation: Theme class changes on component
|
|
301
|
+
// ============================================================================
|
|
302
|
+
const getThemeState = () => {
|
|
303
|
+
// Use the contentContainer like other tests, and check its parent for theme classes
|
|
304
|
+
const content = contentContainer()
|
|
305
|
+
if (!content) return { theme: '', classes: '', element: 'content not found' }
|
|
306
|
+
|
|
307
|
+
// Check content itself and its parent for theme classes
|
|
308
|
+
const contentClasses = Array.from(content.classList).join(' ')
|
|
309
|
+
const parentClasses = content.parentElement ? Array.from(content.parentElement.classList).join(' ') : ''
|
|
310
|
+
|
|
311
|
+
const contentTheme = Array.from(content.classList).find(cls => cls.startsWith('theme-')) || ''
|
|
312
|
+
const parentTheme = content.parentElement
|
|
313
|
+
? Array.from(content.parentElement.classList).find(cls => cls.startsWith('theme-')) || ''
|
|
314
|
+
: ''
|
|
315
|
+
|
|
316
|
+
const theme = contentTheme || parentTheme || ''
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
theme,
|
|
320
|
+
classes: contentClasses + ' | parent: ' + parentClasses,
|
|
321
|
+
computedStyles: getComputedStyle(content).backgroundColor,
|
|
322
|
+
element: `${content.tagName.toLowerCase()} parent: ${content.parentElement?.tagName.toLowerCase() || 'none'}`
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const themeButtons = Array.from(canvasElement.querySelectorAll('.color-palette li')) as HTMLElement[]
|
|
327
|
+
expect(themeButtons.length).toBeGreaterThan(1)
|
|
328
|
+
|
|
329
|
+
await performAndAssert(
|
|
330
|
+
'Theme Change',
|
|
331
|
+
getThemeState,
|
|
332
|
+
async () => {
|
|
333
|
+
const selected = themeButtons.find(btn => btn.classList.contains('selected'))
|
|
334
|
+
const next = themeButtons.find(btn => !btn.classList.contains('selected')) || themeButtons[1]
|
|
335
|
+
await userEvent.click(next)
|
|
336
|
+
},
|
|
337
|
+
(before, after) => before.theme !== after.theme
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
// ============================================================================
|
|
341
|
+
// TEST 2: Display Border Toggle
|
|
342
|
+
// Expectation: Border styles change on content container
|
|
343
|
+
// ============================================================================
|
|
344
|
+
const borderCheckbox = canvasElement.querySelector(
|
|
345
|
+
'input[name*="border"]:not([name*="borderColorTheme"])'
|
|
346
|
+
) as HTMLInputElement
|
|
347
|
+
expect(borderCheckbox).toBeTruthy()
|
|
348
|
+
|
|
349
|
+
await performAndAssert(
|
|
350
|
+
'Display Border Toggle',
|
|
351
|
+
() => ({
|
|
352
|
+
checked: borderCheckbox.checked,
|
|
353
|
+
hasBorders: !visualContainer().classList.contains('no-borders')
|
|
354
|
+
}),
|
|
355
|
+
async () => {
|
|
356
|
+
const checkboxWrapper = borderCheckbox.closest('.cove-input__checkbox--small') || borderCheckbox
|
|
357
|
+
await userEvent.click(checkboxWrapper as HTMLElement)
|
|
358
|
+
},
|
|
359
|
+
(before, after) => {
|
|
360
|
+
const checkboxChanged = before.checked !== after.checked
|
|
361
|
+
const borderChanged = before.hasBorders !== after.hasBorders
|
|
362
|
+
return checkboxChanged && borderChanged
|
|
363
|
+
}
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
// ============================================================================
|
|
367
|
+
// TEST 3: Border Color Theme Toggle
|
|
368
|
+
// Expectation: Border color theme class changes
|
|
369
|
+
// ============================================================================
|
|
370
|
+
const borderColorThemeCheckbox = canvasElement.querySelector('input[name*="borderColorTheme"]') as HTMLInputElement
|
|
371
|
+
expect(borderColorThemeCheckbox).toBeTruthy()
|
|
372
|
+
|
|
373
|
+
await performAndAssert(
|
|
374
|
+
'Border Color Theme Toggle',
|
|
375
|
+
() => ({
|
|
376
|
+
checked: borderColorThemeCheckbox.checked,
|
|
377
|
+
hasBorderColorTheme: visualContainer().classList.contains('component--has-borderColorTheme')
|
|
378
|
+
}),
|
|
379
|
+
async () => {
|
|
380
|
+
const checkboxWrapper =
|
|
381
|
+
borderColorThemeCheckbox.closest('.cove-input__checkbox--small') || borderColorThemeCheckbox
|
|
382
|
+
await userEvent.click(checkboxWrapper as HTMLElement)
|
|
383
|
+
},
|
|
384
|
+
(before, after) => {
|
|
385
|
+
const checkboxChanged = before.checked !== after.checked
|
|
386
|
+
const themeChanged = before.hasBorderColorTheme !== after.hasBorderColorTheme
|
|
387
|
+
return checkboxChanged && themeChanged
|
|
388
|
+
}
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
// ============================================================================
|
|
392
|
+
// TEST 4: Accent Style Toggle
|
|
393
|
+
// Expectation: Accent class toggles
|
|
394
|
+
// ============================================================================
|
|
395
|
+
const accentCheckbox = canvasElement.querySelector('input[name*="accent"]') as HTMLInputElement
|
|
396
|
+
expect(accentCheckbox).toBeTruthy()
|
|
397
|
+
|
|
398
|
+
await performAndAssert(
|
|
399
|
+
'Accent Style Toggle',
|
|
400
|
+
() => ({
|
|
401
|
+
checked: accentCheckbox.checked,
|
|
402
|
+
hasAccent: visualContainer().classList.contains('component--has-accent')
|
|
403
|
+
}),
|
|
404
|
+
async () => {
|
|
405
|
+
const checkboxWrapper = accentCheckbox.closest('.cove-input__checkbox--small') || accentCheckbox
|
|
406
|
+
await userEvent.click(checkboxWrapper as HTMLElement)
|
|
407
|
+
},
|
|
408
|
+
(before, after) => {
|
|
409
|
+
const checkboxChanged = before.checked !== after.checked
|
|
410
|
+
const accentChanged = before.hasAccent !== after.hasAccent
|
|
411
|
+
return checkboxChanged && accentChanged
|
|
412
|
+
}
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
// ============================================================================
|
|
416
|
+
// TEST 5: Theme Background Color Toggle
|
|
417
|
+
// Expectation: Background class toggles
|
|
418
|
+
// ============================================================================
|
|
419
|
+
const backgroundCheckbox = canvasElement.querySelector(
|
|
420
|
+
'input[name*="background"]:not([name*="hide"])'
|
|
421
|
+
) as HTMLInputElement
|
|
422
|
+
expect(backgroundCheckbox).toBeTruthy()
|
|
423
|
+
|
|
424
|
+
await performAndAssert(
|
|
425
|
+
'Theme Background Color Toggle',
|
|
426
|
+
() => ({
|
|
427
|
+
checked: backgroundCheckbox.checked,
|
|
428
|
+
hasBackground: visualContainer().classList.contains('component--has-background')
|
|
429
|
+
}),
|
|
430
|
+
async () => {
|
|
431
|
+
const checkboxWrapper = backgroundCheckbox.closest('.cove-input__checkbox--small') || backgroundCheckbox
|
|
432
|
+
await userEvent.click(checkboxWrapper as HTMLElement)
|
|
433
|
+
},
|
|
434
|
+
(before, after) => {
|
|
435
|
+
const checkboxChanged = before.checked !== after.checked
|
|
436
|
+
const backgroundChanged = before.hasBackground !== after.hasBackground
|
|
437
|
+
return checkboxChanged && backgroundChanged
|
|
438
|
+
}
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
// ============================================================================
|
|
442
|
+
// TEST 6: Hide Background Color Toggle
|
|
443
|
+
// Expectation: Hide background class toggles
|
|
444
|
+
// ============================================================================
|
|
445
|
+
const hideBackgroundCheckbox = canvasElement.querySelector('input[name*="hideBackgroundColor"]') as HTMLInputElement
|
|
446
|
+
expect(hideBackgroundCheckbox).toBeTruthy()
|
|
447
|
+
|
|
448
|
+
await performAndAssert(
|
|
449
|
+
'Hide Background Color Toggle',
|
|
450
|
+
() => ({
|
|
451
|
+
checked: hideBackgroundCheckbox.checked,
|
|
452
|
+
hideBackground: visualContainer().classList.contains('component--hideBackgroundColor')
|
|
453
|
+
}),
|
|
454
|
+
async () => {
|
|
455
|
+
const checkboxWrapper = hideBackgroundCheckbox.closest('.cove-input__checkbox--small') || hideBackgroundCheckbox
|
|
456
|
+
await userEvent.click(checkboxWrapper as HTMLElement)
|
|
457
|
+
},
|
|
458
|
+
(before, after) => {
|
|
459
|
+
const checkboxChanged = before.checked !== after.checked
|
|
460
|
+
const hideChanged = before.hideBackground !== after.hideBackground
|
|
461
|
+
return checkboxChanged && hideChanged
|
|
462
|
+
}
|
|
463
|
+
)
|
|
464
|
+
}
|
|
465
|
+
}
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
-
import CdcMarkupInclude from '../CdcMarkupInclude'
|
|
3
|
-
import primary from './_mock/primary.json'
|
|
4
|
-
import noConditions from './_mock/no-conditions.json'
|
|
5
|
-
import withConditions from './_mock/with-conditions.json'
|
|
6
|
-
import buttonAndText from './_mock/button-and-text.json'
|
|
7
|
-
import iconNoText from './_mock/icon-no-text.json'
|
|
8
|
-
import imageWithText from './_mock/image-with-text.json'
|
|
9
|
-
|
|
10
|
-
const meta: Meta<typeof CdcMarkupInclude> = {
|
|
11
|
-
title: 'Components/Pages/Markup Include',
|
|
12
|
-
component: CdcMarkupInclude
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
type Story = StoryObj<typeof CdcMarkupInclude>
|
|
16
|
-
|
|
17
|
-
export const Primary: Story = {
|
|
18
|
-
args: {
|
|
19
|
-
config: primary,
|
|
20
|
-
isEditor: false
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const No_Conditions: Story = {
|
|
25
|
-
args: {
|
|
26
|
-
config: noConditions,
|
|
27
|
-
isEditor: false
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const With_conditions: Story = {
|
|
32
|
-
args: {
|
|
33
|
-
config: withConditions,
|
|
34
|
-
isEditor: false
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export const Button_and_text: Story = {
|
|
39
|
-
args: {
|
|
40
|
-
config: buttonAndText,
|
|
41
|
-
isEditor: false
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export const icon_no_text: Story = {
|
|
46
|
-
args: {
|
|
47
|
-
config: iconNoText,
|
|
48
|
-
isEditor: false
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
export const image_with_text: Story = {
|
|
52
|
-
args: {
|
|
53
|
-
config: imageWithText,
|
|
54
|
-
isEditor: false
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export default meta
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
|
+
import CdcMarkupInclude from '../CdcMarkupInclude'
|
|
3
|
+
import primary from './_mock/primary.json'
|
|
4
|
+
import noConditions from './_mock/no-conditions.json'
|
|
5
|
+
import withConditions from './_mock/with-conditions.json'
|
|
6
|
+
import buttonAndText from './_mock/button-and-text.json'
|
|
7
|
+
import iconNoText from './_mock/icon-no-text.json'
|
|
8
|
+
import imageWithText from './_mock/image-with-text.json'
|
|
9
|
+
|
|
10
|
+
const meta: Meta<typeof CdcMarkupInclude> = {
|
|
11
|
+
title: 'Components/Pages/Markup Include',
|
|
12
|
+
component: CdcMarkupInclude
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type Story = StoryObj<typeof CdcMarkupInclude>
|
|
16
|
+
|
|
17
|
+
export const Primary: Story = {
|
|
18
|
+
args: {
|
|
19
|
+
config: primary,
|
|
20
|
+
isEditor: false
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const No_Conditions: Story = {
|
|
25
|
+
args: {
|
|
26
|
+
config: noConditions,
|
|
27
|
+
isEditor: false
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const With_conditions: Story = {
|
|
32
|
+
args: {
|
|
33
|
+
config: withConditions,
|
|
34
|
+
isEditor: false
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const Button_and_text: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
config: buttonAndText,
|
|
41
|
+
isEditor: false
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const icon_no_text: Story = {
|
|
46
|
+
args: {
|
|
47
|
+
config: iconNoText,
|
|
48
|
+
isEditor: false
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export const image_with_text: Story = {
|
|
52
|
+
args: {
|
|
53
|
+
config: imageWithText,
|
|
54
|
+
isEditor: false
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default meta
|