@@ -2,26 +2,21 @@ import 'dotenv/config';
22import { describe , test , expect , afterAll , afterEach , vi } from 'vitest' ;
33import exec from '#test/utils/exec' ;
44import cliPath from '#test/utils/cliPath' ;
5+ import waitForOutput from '#test/utils/waitForOutput' ;
56import path from 'path' ;
67import fs from 'fs' ;
78import { requireRealCredentials } from '#test/utils/credentials' ;
89
910vi . setConfig ( { testTimeout : 30000 } ) ;
1011
11- // Force this test file to run in sequence to avoid race conditions with fixture files
12- // @vitest -environment node
13-
14- const stepTimeout = 3500 ;
15-
1612const cwd = name => path . join ( process . cwd ( ) , 'test' , 'fixtures' , 'deploy' , name ) ;
1713const run = ( fixtureName , options , callback ) => {
1814 return exec (
19- `${ cliPath } sync ${ options } ` ,
15+ `${ cliPath } sync ${ options || '' } ` ,
2016 { cwd : cwd ( fixtureName ) , env : process . env } ,
2117 callback
2218 ) ;
2319} ;
24- const sleep = ms => new Promise ( resolve => setTimeout ( resolve , ms ) ) ;
2520
2621const kill = p => {
2722 p . stdout . destroy ( ) ;
@@ -50,15 +45,14 @@ afterAll(() => {
5045 }
5146} ) ;
5247
53- // Skip all tests if credentials aren't available
5448describe ( 'Happy path' , ( ) => {
5549 test ( 'sync assets' , { retry : 2 } , async ( ) => {
5650 requireRealCredentials ( ) ;
5751
5852 const steps = async ( child ) => {
59- await sleep ( stepTimeout ) ;
53+ await waitForOutput ( child , / S y n c h r o n i z i n g c h a n g e s t o / ) ;
6054 exec ( 'echo "x" >> app/assets/bar.js' , { cwd : cwd ( 'correct_with_assets' ) } ) ;
61- await sleep ( stepTimeout ) ;
55+ await waitForOutput ( child , / \[ S y n c \] S y n c e d a s s e t : a p p \/ a s s e t s \/ b a r \. j s / ) ;
6256 kill ( child ) ;
6357 } ;
6458
@@ -70,9 +64,9 @@ describe('Happy path', () => {
7064
7165 test ( 'sync with direct assets upload' , { retry : 2 } , async ( ) => {
7266 const steps = async ( child ) => {
73- await sleep ( stepTimeout ) ;
67+ await waitForOutput ( child , / S y n c h r o n i z i n g c h a n g e s t o / ) ;
7468 exec ( 'echo "x" >> app/assets/bar.js' , { cwd : cwd ( 'correct_with_assets' ) } ) ;
75- await sleep ( stepTimeout ) ;
69+ await waitForOutput ( child , / \[ S y n c \] S y n c e d a s s e t : a p p \/ a s s e t s \/ b a r \. j s / ) ;
7670 kill ( child ) ;
7771 } ;
7872 const { stdout } = await run ( 'correct_with_assets' , '-d' , steps ) ;
@@ -94,53 +88,45 @@ properties:
9488 const testDir = path . join ( cwd ( 'correct_with_assets' ) , 'app' , dir ) ;
9589 const testFile = path . join ( cwd ( 'correct_with_assets' ) , 'app' , fileName ) ;
9690
97- // Wait for sync to initialize before creating file
98- await sleep ( stepTimeout ) ;
91+ await waitForOutput ( child , / S y n c h r o n i z i n g c h a n g e s t o / ) ;
9992
100- // Use Node.js fs for cross-platform compatibility
10193 if ( ! fs . existsSync ( testDir ) ) {
10294 fs . mkdirSync ( testDir , { recursive : true } ) ;
10395 }
10496
10597 fs . writeFileSync ( testFile , validYML ) ;
106- // Wait longer for sync to complete (stabilityThreshold 500ms + network time + queue processing)
107- await sleep ( stepTimeout * 2 ) ;
98+ await waitForOutput ( child , new RegExp ( `\\[Sync\\] Synced: ${ fileName . replace ( / \/ / g, '[/\\\\]' ) } ` ) ) ;
10899
109100 fs . unlinkSync ( testFile ) ;
110- await sleep ( stepTimeout ) ;
101+ await waitForOutput ( child , new RegExp ( `\\[Sync\\] Deleted: ${ fileName . replace ( / \/ / g, '[/\\\\]' ) } ` ) ) ;
102+
111103 kill ( child ) ;
112104 } ;
113105 const { stdout } = await run ( 'correct_with_assets' , null , steps ) ;
114106
115107 expect ( stdout ) . toMatch ( process . env . MPKIT_URL ) ;
116- // Use regex to handle potential path separator differences
117108 expect ( stdout ) . toMatch ( new RegExp ( `\\[Sync\\] Synced: ${ fileName . replace ( / \/ / g, '[/\\\\]' ) } ` ) ) ;
118109 expect ( stdout ) . toMatch ( new RegExp ( `\\[Sync\\] Deleted: ${ fileName . replace ( / \/ / g, '[/\\\\]' ) } ` ) ) ;
119110 } ) ;
120111
121112 test ( 'sync single file with -f option' , { retry : 2 } , async ( ) => {
122113 requireRealCredentials ( ) ;
123114
124- // Create a temporary file to sync
125115 const testFilePath = 'app/views/pages/test-single-sync.liquid' ;
126116 const fullTestPath = path . join ( cwd ( 'correct_with_assets' ) , testFilePath ) ;
127117 const testContent = '<!-- Test single file sync -->\n<h1>Test Page</h1>\n' ;
128118
129- // Write test file
130119 fs . writeFileSync ( fullTestPath , testContent ) ;
131120
132121 try {
133- // Run sync with -f option (without callback, so it runs to completion)
134122 const { stdout, code } = await exec (
135123 `${ cliPath } sync -f ${ testFilePath } ` ,
136124 { cwd : cwd ( 'correct_with_assets' ) , env : process . env }
137125 ) ;
138126
139- // Verify output - note that filePathUnixified removes the app/ prefix
140127 expect ( code ) . toBe ( 0 ) ;
141128 expect ( stdout ) . toMatch ( / \[ S y n c \] S y n c e d : v i e w s \/ p a g e s \/ t e s t - s i n g l e - s y n c \. l i q u i d / ) ;
142129 } finally {
143- // Clean up test file
144130 if ( fs . existsSync ( fullTestPath ) ) {
145131 fs . unlinkSync ( fullTestPath ) ;
146132 }
@@ -150,26 +136,21 @@ properties:
150136 test ( 'sync single asset file with -f option' , { retry : 2 } , async ( ) => {
151137 requireRealCredentials ( ) ;
152138
153- // Create a temporary asset file to sync
154139 const testFilePath = 'app/assets/test-single-sync.js' ;
155140 const fullTestPath = path . join ( cwd ( 'correct_with_assets' ) , testFilePath ) ;
156141 const testContent = '// Test single asset file sync\nconsole.log("test");\n' ;
157142
158- // Write test file
159143 fs . writeFileSync ( fullTestPath , testContent ) ;
160144
161145 try {
162- // Run sync with -f option (without callback, so it runs to completion)
163146 const { stdout, code } = await exec (
164147 `${ cliPath } sync -f ${ testFilePath } ` ,
165148 { cwd : cwd ( 'correct_with_assets' ) , env : process . env }
166149 ) ;
167150
168- // Verify output
169151 expect ( code ) . toBe ( 0 ) ;
170152 expect ( stdout ) . toMatch ( / \[ S y n c \] S y n c e d a s s e t : a p p \/ a s s e t s \/ t e s t - s i n g l e - s y n c \. j s / ) ;
171153 } finally {
172- // Clean up test file
173154 if ( fs . existsSync ( fullTestPath ) ) {
174155 fs . unlinkSync ( fullTestPath ) ;
175156 }
@@ -179,27 +160,18 @@ properties:
179160 test ( '422 validation error shows proper format with single error message' , { retry : 2 } , async ( ) => {
180161 requireRealCredentials ( ) ;
181162
182- // Use fixture with invalid schema file that triggers 422 validation error
183163 const testFilePath = 'app/schema/invalid-property-type.yml' ;
184164
185- // Run sync with -f option - this should fail with validation error
186165 const { stderr, code } = await exec (
187166 `${ cliPath } sync -f ${ testFilePath } ` ,
188167 { cwd : cwd ( 'invalid_schema' ) , env : process . env }
189168 ) ;
190169
191- // Verify error output
192170 expect ( code ) . toBe ( 1 ) ;
193-
194- // Should show [Sync] Failed to sync with timestamp and file path
195171 expect ( stderr ) . toMatch ( / \[ \d { 2 } : \d { 2 } : \d { 2 } \] \[ S y n c \] F a i l e d t o s y n c : s c h e m a \/ i n v a l i d - p r o p e r t y - t y p e \. y m l / ) ;
196-
197- // Should include the validation error message
198172 expect ( stderr ) . toMatch ( / V a l i d a t i o n f a i l e d / ) ;
199173
200- // Verify error is NOT duplicated - count occurrences of "Failed to sync"
201174 const failedToSyncMatches = ( stderr . match ( / F a i l e d t o s y n c / g) || [ ] ) . length ;
202175 expect ( failedToSyncMatches ) . toBe ( 1 ) ;
203176 } ) ;
204-
205177} ) ;
0 commit comments