@@ -16,7 +16,7 @@ test.describe("[command-palette] presets and actions", () => {
1616
1717 test . beforeEach ( async ( { page } ) => {
1818 await page . goto ( "/" ) ;
19- await page . waitForSelector ( `[data-menu="network--view"].active` ) ;
19+ await page . waitForFunction ( ( ) => window . cachedSpecs ?. length > 0 ) ;
2020
2121 i18n = await page . evaluate ( ( ) => {
2222 const lang = document . getElementById ( "lang" ) . dataset . lang ;
@@ -40,9 +40,9 @@ test.describe("[command-palette] presets and actions", () => {
4040 await expect ( presetsSection . locator ( ".range-preset" ) ) . toHaveCount ( 5 ) ;
4141 } ) ;
4242
43- test ( "renders all four action buttons" , async ( { page } ) => {
43+ test ( "renders all five action buttons" , async ( { page } ) => {
4444 const actionsSection = page . locator ( ".section" ) . filter ( { hasText : i18n . section_actions } ) ;
45- await expect ( actionsSection . locator ( ".range-preset" ) ) . toHaveCount ( 4 ) ;
45+ await expect ( actionsSection . locator ( ".range-preset" ) ) . toHaveCount ( 5 ) ;
4646 } ) ;
4747
4848 test ( "clicking a preset adds a chip and hides the presets section" , async ( { page } ) => {
@@ -186,7 +186,7 @@ test.describe("[command-palette] dep filter", () => {
186186
187187 test . beforeEach ( async ( { page } ) => {
188188 await page . goto ( "/" ) ;
189- await page . waitForSelector ( `[data-menu="network--view"].active` ) ;
189+ await page . waitForFunction ( ( ) => window . cachedSpecs ?. length > 0 ) ;
190190
191191 i18n = await page . evaluate ( ( ) => {
192192 const lang = document . getElementById ( "lang" ) . dataset . lang ;
@@ -268,7 +268,7 @@ test.describe("[command-palette] ignore flags and warnings", () => {
268268
269269 test . beforeEach ( async ( { page } ) => {
270270 await page . goto ( "/" ) ;
271- await page . waitForSelector ( `[data-menu="network--view"].active` ) ;
271+ await page . waitForFunction ( ( ) => window . cachedSpecs ?. length > 0 ) ;
272272
273273 i18n = await page . evaluate ( ( ) => {
274274 const lang = document . getElementById ( "lang" ) . dataset . lang ;
@@ -369,3 +369,100 @@ test.describe("[command-palette] ignore flags and warnings", () => {
369369 await expect ( page . locator ( ".section" ) . filter ( { hasText : i18n . section_ignore_warnings } ) ) . not . toBeVisible ( ) ;
370370 } ) ;
371371} ) ;
372+
373+ test . describe ( "[command-palette] clear cache action" , ( ) => {
374+ async function loadI18n ( page ) {
375+ return page . evaluate ( ( ) => {
376+ const lang = document . getElementById ( "lang" ) . dataset . lang ;
377+ const activeLang = lang in window . i18n ? lang : "english" ;
378+
379+ return window . i18n [ activeLang ] . search_command ;
380+ } ) ;
381+ }
382+
383+ async function openPalette ( page ) {
384+ await page . goto ( "/" ) ;
385+ await page . waitForFunction ( ( ) => window . cachedSpecs ?. length > 0 ) ;
386+ await page . locator ( `[data-menu="network--view"].active` ) . click ( ) ;
387+ await page . keyboard . press ( "Control+k" ) ;
388+ await expect ( page . locator ( ".backdrop" ) ) . toBeVisible ( ) ;
389+ }
390+
391+ test ( "renders the clear cache action button" , async ( { page } ) => {
392+ await openPalette ( page ) ;
393+ const i18n = await loadI18n ( page ) ;
394+
395+ const actionsSection = page . locator ( ".section" ) . filter ( { hasText : i18n . section_actions } ) ;
396+ await expect ( actionsSection . locator ( ".range-preset" ) . filter ( { hasText : i18n . action_clear_cache } ) ) . toBeVisible ( ) ;
397+ } ) ;
398+
399+ // Alt+X is tested via WebSocket interception so the server cache is not actually
400+ // cleared, keeping network--view available for the next test.
401+ test ( "Alt+X sends the CLEAR command and closes the palette" , async ( { page } ) => {
402+ let clearSent = false ;
403+
404+ await page . routeWebSocket ( "ws://localhost:1339" , ( ws ) => {
405+ const server = ws . connectToServer ( ) ;
406+
407+ ws . onMessage ( ( msg ) => {
408+ const data = JSON . parse ( msg ) ;
409+ if ( data . commandName === "CLEAR" ) {
410+ clearSent = true ;
411+ ws . send ( JSON . stringify ( { status : "RELOAD" , cache : [ ] } ) ) ;
412+ }
413+ else {
414+ server . send ( msg ) ;
415+ }
416+ } ) ;
417+
418+ server . onMessage ( ( msg ) => {
419+ ws . send ( msg ) ;
420+ } ) ;
421+ } ) ;
422+
423+ await openPalette ( page ) ;
424+
425+ await page . keyboard . press ( "Alt+x" ) ;
426+
427+ await expect ( page . locator ( ".backdrop" ) ) . not . toBeVisible ( ) ;
428+ await page . waitForSelector ( `[data-menu="search--view"].active` ) ;
429+ expect ( clearSent ) . toBe ( true ) ;
430+ } ) ;
431+
432+ test ( "clicking clear cache closes the palette and hides data views" , async ( { page } ) => {
433+ let clearSent = false ;
434+
435+ await page . routeWebSocket ( "ws://localhost:1339" , ( ws ) => {
436+ const server = ws . connectToServer ( ) ;
437+
438+ ws . onMessage ( ( msg ) => {
439+ const data = JSON . parse ( msg ) ;
440+ if ( data . commandName === "CLEAR" ) {
441+ clearSent = true ;
442+ ws . send ( JSON . stringify ( { status : "RELOAD" , cache : [ ] } ) ) ;
443+ }
444+ else {
445+ server . send ( msg ) ;
446+ }
447+ } ) ;
448+
449+ server . onMessage ( ( msg ) => {
450+ ws . send ( msg ) ;
451+ } ) ;
452+ } ) ;
453+
454+ await openPalette ( page ) ;
455+ const i18n = await loadI18n ( page ) ;
456+
457+ const actionsSection = page . locator ( ".section" ) . filter ( { hasText : i18n . section_actions } ) ;
458+ await actionsSection . locator ( ".range-preset" ) . filter ( { hasText : i18n . action_clear_cache } ) . click ( ) ;
459+
460+ await expect ( page . locator ( ".backdrop" ) ) . not . toBeVisible ( ) ;
461+ await page . waitForSelector ( `[data-menu="search--view"].active` ) ;
462+ expect ( clearSent ) . toBe ( true ) ;
463+
464+ for ( const menu of [ "network--view" , "home--view" , "tree--view" , "warnings--view" ] ) {
465+ await expect ( page . locator ( `[data-menu="${ menu } "]` ) ) . toContainClass ( "hidden" ) ;
466+ }
467+ } ) ;
468+ } ) ;
0 commit comments