@@ -224,8 +224,44 @@ describe('parseBlockedUrlPatternsFlag', () => {
224224 } ) ;
225225} ) ;
226226
227+ describe ( 'parseLabCategoriesFlag' , ( ) => {
228+ it ( 'should return empty array for falsy input' , ( ) => {
229+ expect ( prompts . parseLabCategoriesFlag ( undefined ) ) . toEqual ( [ ] ) ;
230+ expect ( prompts . parseLabCategoriesFlag ( '' ) ) . toEqual ( [ ] ) ;
231+ } ) ;
232+
233+ it ( 'should parse a single category' , ( ) => {
234+ expect ( prompts . parseLabCategoriesFlag ( 'performance' ) ) . toEqual ( [ 'performance' ] ) ;
235+ } ) ;
236+
237+ it ( 'should parse comma-separated categories and preserve order' , ( ) => {
238+ expect ( prompts . parseLabCategoriesFlag ( 'seo,performance' ) ) . toEqual ( [ 'seo' , 'performance' ] ) ;
239+ } ) ;
240+
241+ it ( 'should accept agentic-browsing' , ( ) => {
242+ expect ( prompts . parseLabCategoriesFlag ( 'agentic-browsing' ) ) . toEqual ( [ 'agentic-browsing' ] ) ;
243+ } ) ;
244+
245+ it ( 'should normalize case and trim whitespace' , ( ) => {
246+ expect ( prompts . parseLabCategoriesFlag ( ' Performance , SEO ' ) ) . toEqual ( [ 'performance' , 'seo' ] ) ;
247+ } ) ;
248+
249+ it ( 'should de-duplicate categories' , ( ) => {
250+ expect ( prompts . parseLabCategoriesFlag ( 'performance,performance,seo' ) ) . toEqual ( [ 'performance' , 'seo' ] ) ;
251+ } ) ;
252+
253+ it ( 'should throw on unknown category' , ( ) => {
254+ expect ( ( ) => prompts . parseLabCategoriesFlag ( 'pwa' ) ) . toThrow ( 'Unknown category: "pwa". Valid categories: performance, accessibility, best-practices, seo, agentic-browsing' ) ;
255+ } ) ;
256+
257+ it ( 'should throw on unknown category in comma list' , ( ) => {
258+ expect ( ( ) => prompts . parseLabCategoriesFlag ( 'performance,foo' ) ) . toThrow ( 'Unknown category: "foo"' ) ;
259+ } ) ;
260+ } ) ;
261+
227262describe ( 'promptLab' , ( ) => {
228- const baseOpts = { profile : undefined , network : undefined , device : undefined , urls : undefined , urlsFile : undefined , clean : false } ;
263+ // category set so the interactive category prompt is skipped in tests that don't exercise it
264+ const baseOpts = { profile : undefined , network : undefined , device : undefined , urls : undefined , urlsFile : undefined , category : 'performance' , clean : false } ;
229265
230266 it ( 'should return runs array with single profile when provided via flag' , async ( ) => {
231267 promptSpy . mockResolvedValueOnce ( { skipAudits : [ ] } ) ;
@@ -584,6 +620,35 @@ describe('promptLab', () => {
584620 expect ( promptSpy ) . toHaveBeenCalledTimes ( 3 ) ;
585621 } ) ;
586622 } ) ;
623+
624+ describe ( '--category' , ( ) => {
625+ it ( 'parses categories from the --category flag without prompting' , async ( ) => {
626+ promptSpy . mockResolvedValueOnce ( { skipAudits : [ ] } ) ;
627+ promptSpy . mockResolvedValueOnce ( { blockedUrlPatternsInput : '' } ) ;
628+ promptSpy . mockResolvedValueOnce ( { stripJsonProps : true } ) ;
629+ const result = await prompts . promptLab ( 'https://example.com' , { ...baseOpts , profile : 'low' , category : 'agentic-browsing,seo' } ) ;
630+ expect ( result . categories ) . toEqual ( [ 'agentic-browsing' , 'seo' ] ) ;
631+ expect ( promptSpy ) . toHaveBeenCalledTimes ( 3 ) ;
632+ } ) ;
633+
634+ it ( 'prompts with a checkbox (all selected by default) when no --category flag' , async ( ) => {
635+ promptSpy . mockResolvedValueOnce ( { categories : [ 'performance' , 'accessibility' , 'best-practices' , 'seo' , 'agentic-browsing' ] } ) ;
636+ promptSpy . mockResolvedValueOnce ( { skipAudits : [ ] } ) ;
637+ promptSpy . mockResolvedValueOnce ( { blockedUrlPatternsInput : '' } ) ;
638+ promptSpy . mockResolvedValueOnce ( { stripJsonProps : true } ) ;
639+ const result = await prompts . promptLab ( 'https://example.com' , { ...baseOpts , profile : 'low' , category : undefined } ) ;
640+ expect ( result . categories ) . toEqual ( [ 'performance' , 'accessibility' , 'best-practices' , 'seo' , 'agentic-browsing' ] ) ;
641+ } ) ;
642+
643+ it ( 'returns the subset selected in the interactive checkbox' , async ( ) => {
644+ promptSpy . mockResolvedValueOnce ( { categories : [ 'agentic-browsing' ] } ) ;
645+ promptSpy . mockResolvedValueOnce ( { skipAudits : [ ] } ) ;
646+ promptSpy . mockResolvedValueOnce ( { blockedUrlPatternsInput : '' } ) ;
647+ promptSpy . mockResolvedValueOnce ( { stripJsonProps : true } ) ;
648+ const result = await prompts . promptLab ( 'https://example.com' , { ...baseOpts , profile : 'low' , category : undefined } ) ;
649+ expect ( result . categories ) . toEqual ( [ 'agentic-browsing' ] ) ;
650+ } ) ;
651+ } ) ;
587652} ) ;
588653
589654describe ( 'promptPsi' , ( ) => {
0 commit comments