1+ // Cypress E2E test for JsonFormatter.vue
2+ // Covers: valid/invalid JSON, format, clear, copy, error, placeholder
3+
4+ describe ( 'JsonFormatter Component' , ( ) => {
5+ const validJson = '{"foo": "bar", "num": 42, "bool": true}' ;
6+ const formattedJson = `{
7+ "foo": "bar",
8+ "num": 42,
9+ "bool": true
10+ }` ;
11+ const invalidJson = '{foo: bar}' ;
12+
13+ beforeEach ( ( ) => {
14+ cy . visit ( '/json' ) ;
15+ } ) ;
16+
17+ it ( 'shows placeholder initially' , ( ) => {
18+ cy . get ( '[data-test-id=placeholder-message]' ) . should ( 'be.visible' ) ;
19+ cy . get ( '[data-test-id=json-output]' ) . should ( 'not.exist' ) ;
20+ cy . get ( '[data-test-id=error-message]' ) . should ( 'not.exist' ) ;
21+ } ) ;
22+
23+ it ( 'formats valid JSON' , ( ) => {
24+ cy . get ( '[data-test-id=json-input]' ) . type ( validJson , { delay : 0 , parseSpecialCharSequences : false } ) ;
25+ cy . get ( '[data-test-id=format-btn]' ) . click ( ) ;
26+ cy . get ( '[data-test-id=json-output]' ) . should ( 'contain.text' , '"foo"' ) ;
27+ cy . get ( '[data-test-id=json-output]' ) . should ( 'contain.text' , '"bar"' ) ;
28+ cy . get ( '[data-test-id=json-output]' ) . should ( 'contain.text' , '"num"' ) ;
29+ cy . get ( '[data-test-id=json-output]' ) . should ( 'contain.text' , '42' ) ;
30+ cy . get ( '[data-test-id=error-message]' ) . should ( 'not.exist' ) ;
31+ cy . get ( '[data-test-id=placeholder-message]' ) . should ( 'not.exist' ) ;
32+ } ) ;
33+
34+ it ( 'clears input and output' , ( ) => {
35+ cy . get ( '[data-test-id=json-input]' ) . type ( validJson , { delay : 0 , parseSpecialCharSequences : false } ) ;
36+ cy . get ( '[data-test-id=format-btn]' ) . click ( ) ;
37+ cy . get ( '[data-test-id=clear-btn]' ) . click ( ) ;
38+ cy . get ( '[data-test-id=json-input]' ) . should ( 'have.value' , '' ) ;
39+ cy . get ( '[data-test-id=json-output]' ) . should ( 'not.exist' ) ;
40+ cy . get ( '[data-test-id=placeholder-message]' ) . should ( 'be.visible' ) ;
41+ } ) ;
42+
43+ it ( 'shows error for invalid JSON' , ( ) => {
44+ cy . get ( '[data-test-id=json-input]' ) . type ( invalidJson , { delay : 0 , parseSpecialCharSequences : false } ) ;
45+ cy . get ( '[data-test-id=format-btn]' ) . click ( ) ;
46+ cy . get ( '[data-test-id=error-message]' ) . should ( 'be.visible' ) . and ( 'contain.text' , 'Invalid JSON' ) ;
47+ cy . get ( '[data-test-id=json-output]' ) . should ( 'not.exist' ) ;
48+ cy . get ( '[data-test-id=placeholder-message]' ) . should ( 'not.exist' ) ;
49+ } ) ;
50+
51+ it ( 'copies formatted JSON to clipboard' , ( ) => {
52+ cy . window ( ) . then ( win => {
53+ cy . stub ( win . navigator . clipboard , 'writeText' ) . as ( 'writeText' ) ;
54+ } ) ;
55+ cy . get ( '[data-test-id=json-input]' ) . type ( validJson , { delay : 0 , parseSpecialCharSequences : false } ) ;
56+ cy . get ( '[data-test-id=format-btn]' ) . click ( ) ;
57+ cy . get ( '[data-test-id=copy-btn]' ) . click ( ) ;
58+ cy . get ( '@writeText' ) . should ( 'have.been.calledWith' , formattedJson ) ;
59+ } ) ;
60+
61+ it ( 'disables buttons appropriately' , ( ) => {
62+ cy . get ( '[data-test-id=format-btn]' ) . should ( 'be.disabled' ) ;
63+ cy . get ( '[data-test-id=clear-btn]' ) . should ( 'be.disabled' ) ;
64+ cy . get ( '[data-test-id=copy-btn]' ) . should ( 'be.disabled' ) ;
65+ cy . get ( '[data-test-id=json-input]' ) . type ( validJson , { delay : 0 , parseSpecialCharSequences : false } ) ;
66+ cy . get ( '[data-test-id=format-btn]' ) . should ( 'not.be.disabled' ) ;
67+ cy . get ( '[data-test-id=clear-btn]' ) . should ( 'not.be.disabled' ) ;
68+ cy . get ( '[data-test-id=copy-btn]' ) . should ( 'be.disabled' ) ;
69+ cy . get ( '[data-test-id=format-btn]' ) . click ( ) ;
70+ cy . get ( '[data-test-id=copy-btn]' ) . should ( 'not.be.disabled' ) ;
71+ } ) ;
72+ } ) ;
0 commit comments