@@ -102,4 +102,108 @@ test.describe('signup and email verification', () => {
102102 page . getByRole ( 'button' , { name : 'Sign Up' , exact : true } )
103103 ) . toBeDisabled ( ) ;
104104 } ) ;
105+
106+ test ( 'sketch persists and runs after unauthenticated user creates an account' , async ( {
107+ page
108+ } ) => {
109+ // This test does a lot in one flow: type + run a sketch, sign up, then
110+ // run it again. The default 30s is tight for it on a loaded machine.
111+ test . setTimeout ( 60_000 ) ;
112+
113+ const username = `${ usernamePrefix ( ) } ${ Date . now ( ) } ` ;
114+ const email = `${ username } ${ emailSuffix ( ) } ` ;
115+
116+ const newCode = [
117+ 'function setup() {' ,
118+ ' createCanvas(400, 400);' ,
119+ '}' ,
120+ '' ,
121+ 'function draw() {' ,
122+ ' background(220);' ,
123+ " console.log('hi from sketch');" ,
124+ ' noLoop();' ,
125+ '}'
126+ ] . join ( '' ) ;
127+
128+ await page . goto ( '/' ) ;
129+ await dismissCookieBanner ( page ) ;
130+
131+ // Run sketch as unauthenticated user
132+ const editor = page . locator ( '.editor-holder' ) ;
133+ await editor . click ( ) ;
134+ await page . keyboard . press ( 'ControlOrMeta+A' ) ;
135+ await page . keyboard . type ( newCode , { delay : 5 } ) ;
136+
137+ // Required: signing up boots the app fresh, and the editor recovers the
138+ // unsaved sketch from the localStorage backup (see IDEView.jsx). That
139+ // backup is only written by CodeMirror's debounced onChange (1s after
140+ // typing stops) — the Play button's syncFileContent() dispatches to Redux
141+ // but never writes it. Without this wait the sketch is lost on signup.
142+ await page . waitForTimeout ( 1000 ) ;
143+
144+ await page . locator ( '#play-sketch' ) . click ( { force : true } ) ;
145+
146+ await expect (
147+ page . locator ( 'iframe[title="sketch preview"]' )
148+ ) . toHaveAttribute ( 'src' , / 9 0 0 2 / , { timeout : 10_000 } ) ;
149+
150+ await expect (
151+ page . locator ( '.preview-console__messages' )
152+ ) . toContainText ( 'hi from sketch' , { timeout : 15_000 } ) ;
153+
154+ // Try to save the sketch, which should prompt login
155+ await editor . click ( ) ;
156+ await page . keyboard . press ( 'Control+S' ) ;
157+
158+ await expect (
159+ page . getByText (
160+ 'In order to save sketches, you must be logged in. Please Login or Sign Up.'
161+ )
162+ ) . toBeVisible ( ) ;
163+
164+ // Click on the signup prompt
165+ await page . locator ( 'a[href="/signup"]' ) . last ( ) . click ( ) ;
166+ await page . waitForURL ( '**/signup' , { timeout : 10_000 } ) ;
167+
168+ await expect ( page . locator ( 'h2.form-container__title' ) ) . toHaveText (
169+ 'Sign Up'
170+ ) ;
171+
172+ await page . fill ( 'input#username' , username ) ;
173+ await page . fill ( 'input#email' , email ) ;
174+ await page . fill ( 'input#password' , password ( ) ) ;
175+ await page . fill ( 'input#confirmPassword' , password ( ) ) ;
176+
177+ await expect ( page . locator ( 'button[type="submit"]' ) ) . toBeEnabled ( {
178+ timeout : 5_000
179+ } ) ;
180+ await page . click ( 'button[type="submit"]' ) ;
181+
182+ await page . waitForURL ( ( url ) => ! url . pathname . endsWith ( '/signup' ) , {
183+ timeout : 15_000
184+ } ) ;
185+ await expect ( page . locator ( `text=${ username } ` ) . first ( ) ) . toBeVisible ( {
186+ timeout : 10_000
187+ } ) ;
188+
189+ // The sketch the user wrote while logged out survives the signup:
190+ // they land back in the editor with their code still there.
191+ await expect ( page . locator ( '.editor-holder' ) ) . toBeVisible ( ) ;
192+ // Scoped to the editor — the console has its own CodeMirror input,
193+ // so a bare .cm-content matches two elements.
194+ await expect (
195+ editor . locator ( '.cm-content' )
196+ ) . toContainText ( "console.log('hi from sketch')" , { timeout : 10_000 } ) ;
197+
198+ // ...and still runs as the now-authenticated user
199+ await page . locator ( '#play-sketch' ) . click ( { force : true } ) ;
200+
201+ await expect (
202+ page . locator ( 'iframe[title="sketch preview"]' )
203+ ) . toHaveAttribute ( 'src' , / 9 0 0 2 / , { timeout : 10_000 } ) ;
204+
205+ await expect (
206+ page . locator ( '.preview-console__messages' )
207+ ) . toContainText ( 'hi from sketch' , { timeout : 20_000 } ) ;
208+ } ) ;
105209} ) ;
0 commit comments