55 * LICENSE file in the root directory of this source tree.
66 */
77
8- import { expect , test } from '@playwright/test' ;
8+ import { expect , test , type Page } from '@playwright/test' ;
99import { encodeStore , type Store } from '../../lib/stores' ;
10+ import { defaultConfig } from '../../lib/defaultStore' ;
1011import { format } from 'prettier' ;
1112
1213function isMonacoLoaded ( ) : boolean {
@@ -20,6 +21,15 @@ function formatPrint(data: Array<string>): Promise<string> {
2021 return format ( data . join ( '' ) , { parser : 'babel' } ) ;
2122}
2223
24+ async function expandConfigs ( page : Page ) : Promise < void > {
25+ const expandButton = page . locator ( '[title="Expand config editor"]' ) ;
26+ expandButton . click ( ) ;
27+ }
28+
29+ const TEST_SOURCE = `export default function TestComponent({ x }) {
30+ return <Button>{x}</Button>;
31+ }` ;
32+
2333const TEST_CASE_INPUTS = [
2434 {
2535 name : 'module-scope-use-memo' ,
@@ -121,10 +131,9 @@ test('editor should open successfully', async ({page}) => {
121131
122132test ( 'editor should compile from hash successfully' , async ( { page} ) => {
123133 const store : Store = {
124- source : `export default function TestComponent({ x }) {
125- return <Button>{x}</Button>;
126- }
127- ` ,
134+ source : TEST_SOURCE ,
135+ config : defaultConfig ,
136+ showInternals : false ,
128137 } ;
129138 const hash = encodeStore ( store ) ;
130139 await page . goto ( `/#${ hash } ` , { waitUntil : 'networkidle' } ) ;
@@ -136,7 +145,7 @@ test('editor should compile from hash successfully', async ({page}) => {
136145 path : 'test-results/01-compiles-from-hash.png' ,
137146 } ) ;
138147 const text =
139- ( await page . locator ( '.monaco-editor' ) . nth ( 3 ) . allInnerTexts ( ) ) ?? [ ] ;
148+ ( await page . locator ( '.monaco-editor-output' ) . allInnerTexts ( ) ) ?? [ ] ;
140149 const output = await formatPrint ( text ) ;
141150
142151 expect ( output ) . not . toEqual ( '' ) ;
@@ -145,10 +154,9 @@ test('editor should compile from hash successfully', async ({page}) => {
145154
146155test ( 'reset button works' , async ( { page} ) => {
147156 const store : Store = {
148- source : `export default function TestComponent({ x }) {
149- return <Button>{x}</Button>;
150- }
151- ` ,
157+ source : TEST_SOURCE ,
158+ config : defaultConfig ,
159+ showInternals : false ,
152160 } ;
153161 const hash = encodeStore ( store ) ;
154162 await page . goto ( `/#${ hash } ` , { waitUntil : 'networkidle' } ) ;
@@ -157,33 +165,171 @@ test('reset button works', async ({page}) => {
157165 // Reset button works
158166 page . on ( 'dialog' , dialog => dialog . accept ( ) ) ;
159167 await page . getByRole ( 'button' , { name : 'Reset' } ) . click ( ) ;
168+ await expandConfigs ( page ) ;
169+
160170 await page . screenshot ( {
161171 fullPage : true ,
162172 path : 'test-results/02-reset-button-works.png' ,
163173 } ) ;
164174 const text =
165- ( await page . locator ( '.monaco-editor' ) . nth ( 3 ) . allInnerTexts ( ) ) ?? [ ] ;
175+ ( await page . locator ( '.monaco-editor-output' ) . allInnerTexts ( ) ) ?? [ ] ;
166176 const output = await formatPrint ( text ) ;
167177
178+ const configText =
179+ ( await page . locator ( '.monaco-editor-config' ) . allInnerTexts ( ) ) ?? [ ] ;
180+ const configOutput = configText . join ( '' ) ;
181+
168182 expect ( output ) . not . toEqual ( '' ) ;
169183 expect ( output ) . toMatchSnapshot ( '02-default-output.txt' ) ;
184+ expect ( configOutput ) . not . toEqual ( '' ) ;
185+ expect ( configOutput ) . toMatchSnapshot ( 'default-config.txt' ) ;
186+ } ) ;
187+
188+ test ( 'defaults load when only source is in Store' , async ( { page} ) => {
189+ // Test for backwards compatibility
190+ const partial = {
191+ source : TEST_SOURCE ,
192+ } ;
193+ const hash = encodeStore ( partial as Store ) ;
194+ await page . goto ( `/#${ hash } ` , { waitUntil : 'networkidle' } ) ;
195+ await page . waitForFunction ( isMonacoLoaded ) ;
196+ await expandConfigs ( page ) ;
197+
198+ await page . screenshot ( {
199+ fullPage : true ,
200+ path : 'test-results/03-missing-defaults.png' ,
201+ } ) ;
202+
203+ // Config editor has default config
204+ const configText =
205+ ( await page . locator ( '.monaco-editor-config' ) . allInnerTexts ( ) ) ?? [ ] ;
206+ const configOutput = configText . join ( '' ) ;
207+
208+ expect ( configOutput ) . not . toEqual ( '' ) ;
209+ expect ( configOutput ) . toMatchSnapshot ( 'default-config.txt' ) ;
210+
211+ const checkbox = page . locator ( 'label.show-internals' ) ;
212+ await expect ( checkbox ) . not . toBeChecked ( ) ;
213+ const ssaTab = page . locator ( 'text=SSA' ) ;
214+ await expect ( ssaTab ) . not . toBeVisible ( ) ;
215+ } ) ;
216+
217+ test ( 'show internals button toggles correctly' , async ( { page} ) => {
218+ await page . goto ( `/` , { waitUntil : 'networkidle' } ) ;
219+ await page . waitForFunction ( isMonacoLoaded ) ;
220+
221+ // show internals should be off
222+ const checkbox = page . locator ( 'label.show-internals' ) ;
223+ await checkbox . click ( ) ;
224+
225+ await page . screenshot ( {
226+ fullPage : true ,
227+ path : 'test-results/04-show-internals-on.png' ,
228+ } ) ;
229+
230+ await expect ( checkbox ) . toBeChecked ( ) ;
231+
232+ const ssaTab = page . locator ( 'text=SSA' ) ;
233+ await expect ( ssaTab ) . toBeVisible ( ) ;
234+ } ) ;
235+
236+ test ( 'error is displayed when config has syntax error' , async ( { page} ) => {
237+ const store : Store = {
238+ source : TEST_SOURCE ,
239+ config : `compilationMode: ` ,
240+ showInternals : false ,
241+ } ;
242+ const hash = encodeStore ( store ) ;
243+ await page . goto ( `/#${ hash } ` , { waitUntil : 'networkidle' } ) ;
244+ await page . waitForFunction ( isMonacoLoaded ) ;
245+ await expandConfigs ( page ) ;
246+ await page . screenshot ( {
247+ fullPage : true ,
248+ path : 'test-results/05-config-syntax-error.png' ,
249+ } ) ;
250+
251+ const text =
252+ ( await page . locator ( '.monaco-editor-output' ) . allInnerTexts ( ) ) ?? [ ] ;
253+ const output = text . join ( '' ) ;
254+
255+ // Remove hidden chars
256+ expect ( output . replace ( / \s + / g, ' ' ) ) . toContain ( 'Invalid override format' ) ;
257+ } ) ;
258+
259+ test ( 'error is displayed when config has validation error' , async ( { page} ) => {
260+ const store : Store = {
261+ source : TEST_SOURCE ,
262+ config : `import type { PluginOptions } from 'babel-plugin-react-compiler/dist';
263+
264+ ({
265+ compilationMode: "123"
266+ } satisfies Partial<PluginOptions>);` ,
267+ showInternals : false ,
268+ } ;
269+ const hash = encodeStore ( store ) ;
270+ await page . goto ( `/#${ hash } ` , { waitUntil : 'networkidle' } ) ;
271+ await page . waitForFunction ( isMonacoLoaded ) ;
272+ await expandConfigs ( page ) ;
273+ await page . screenshot ( {
274+ fullPage : true ,
275+ path : 'test-results/06-config-validation-error.png' ,
276+ } ) ;
277+
278+ const text =
279+ ( await page . locator ( '.monaco-editor-output' ) . allInnerTexts ( ) ) ?? [ ] ;
280+ const output = text . join ( '' ) ;
281+
282+ expect ( output . replace ( / \s + / g, ' ' ) ) . toContain ( 'Unexpected compilationMode' ) ;
283+ } ) ;
284+
285+ test ( 'disableMemoizationForDebugging flag works as expected' , async ( {
286+ page,
287+ } ) => {
288+ const store : Store = {
289+ source : TEST_SOURCE ,
290+ config : `import type { PluginOptions } from 'babel-plugin-react-compiler/dist';
291+
292+ ({
293+ environment: {
294+ disableMemoizationForDebugging: true
295+ }
296+ } satisfies Partial<PluginOptions>);` ,
297+ showInternals : false ,
298+ } ;
299+ const hash = encodeStore ( store ) ;
300+ await page . goto ( `/#${ hash } ` , { waitUntil : 'networkidle' } ) ;
301+ await page . waitForFunction ( isMonacoLoaded ) ;
302+ await expandConfigs ( page ) ;
303+ await page . screenshot ( {
304+ fullPage : true ,
305+ path : 'test-results/07-config-disableMemoizationForDebugging-flag.png' ,
306+ } ) ;
307+
308+ const text =
309+ ( await page . locator ( '.monaco-editor-output' ) . allInnerTexts ( ) ) ?? [ ] ;
310+ const output = await formatPrint ( text ) ;
311+
312+ expect ( output ) . not . toEqual ( '' ) ;
313+ expect ( output ) . toMatchSnapshot ( 'disableMemoizationForDebugging-output.txt' ) ;
170314} ) ;
171315
172316TEST_CASE_INPUTS . forEach ( ( t , idx ) =>
173317 test ( `playground compiles: ${ t . name } ` , async ( { page} ) => {
174318 const store : Store = {
175319 source : t . input ,
320+ config : defaultConfig ,
321+ showInternals : false ,
176322 } ;
177323 const hash = encodeStore ( store ) ;
178324 await page . goto ( `/#${ hash } ` , { waitUntil : 'networkidle' } ) ;
179325 await page . waitForFunction ( isMonacoLoaded ) ;
180326 await page . screenshot ( {
181327 fullPage : true ,
182- path : `test-results/03 -0${ idx } -${ t . name } .png` ,
328+ path : `test-results/08 -0${ idx } -${ t . name } .png` ,
183329 } ) ;
184330
185331 const text =
186- ( await page . locator ( '.monaco-editor' ) . nth ( 3 ) . allInnerTexts ( ) ) ?? [ ] ;
332+ ( await page . locator ( '.monaco-editor-output' ) . allInnerTexts ( ) ) ?? [ ] ;
187333 let output : string ;
188334 if ( t . noFormat ) {
189335 output = text . join ( '' ) ;
0 commit comments