11import type { Meta , StoryObj } from '@storybook/vue3-vite' ;
2+ import { expect , waitFor } from 'storybook/test' ;
23import CodeEditor from './CodeEditor.vue' ;
34
5+ /**
6+ * Asserts the document is actually SYNTAX HIGHLIGHTED, not merely rendered.
7+ *
8+ * This guards a failure mode with no error signal: if the library build ever
9+ * bundles `@codemirror/language` instead of externalising it, the consumer
10+ * loads two copies of it, the language's syntax tree registers against one
11+ * set of facets and `syntaxHighlighting()` reads the other, and every editor
12+ * silently renders as flat monochrome text.
13+ *
14+ * The check is "some token is painted a colour other than the body text's",
15+ * not "tokens use more than one colour between them": a short JSON document
16+ * may legitimately contain only one *styled* tag kind (`defaultHighlightStyle`
17+ * leaves plain `propertyName` uncoloured), which would make a colour-diversity
18+ * assertion fail on working code.
19+ */
20+ async function expectHighlighted ( canvasElement : HTMLElement ) : Promise < void > {
21+ await waitFor ( async ( ) => {
22+ const content = canvasElement . querySelector ( '.cm-content' ) ;
23+ await expect ( content ) . not . toBeNull ( ) ;
24+
25+ const tokens = canvasElement . querySelectorAll ( '.cm-line span' ) ;
26+ await expect ( tokens . length ) . toBeGreaterThan ( 0 ) ;
27+
28+ const base = getComputedStyle ( content as Element ) . color ;
29+ await expect ( [ ...tokens ] . some ( ( token ) => getComputedStyle ( token ) . color !== base ) ) . toBe ( true ) ;
30+ } ) ;
31+ }
32+
433const meta : Meta < typeof CodeEditor > = {
534 title : 'Organisms/CodeEditor' ,
635 component : CodeEditor ,
@@ -19,13 +48,16 @@ const meta: Meta<typeof CodeEditor> = {
1948export default meta ;
2049type Story = StoryObj < typeof CodeEditor > ;
2150
22- export const Json : Story = { } ;
51+ export const Json : Story = {
52+ play : ( { canvasElement } ) => expectHighlighted ( canvasElement ) ,
53+ } ;
2354
2455export const Markdown : Story = {
2556 args : {
26- modelValue : '# Extraction prompt\n\nSummarize the invoice fields below.' ,
57+ modelValue : '# Extraction prompt\n\nSummarize the ** invoice** fields below.' ,
2758 language : 'markdown' ,
2859 } ,
60+ play : ( { canvasElement } ) => expectHighlighted ( canvasElement ) ,
2961} ;
3062
3163export const ReadOnlyEmpty : Story = {
@@ -38,3 +70,7 @@ export const ReadOnlyEmpty: Story = {
3870export const AutoHeight : Story = {
3971 args : { autoHeight : true , maxHeight : '12rem' } ,
4072} ;
73+
74+ export const Copyable : Story = {
75+ args : { copyable : true , readonly : true } ,
76+ } ;
0 commit comments