@@ -357,6 +357,216 @@ test.describe(
357357 }
358358) ;
359359
360+ async function applyLearningResourceFilter (
361+ page : Page ,
362+ filterLabel : string ,
363+ optionKey : string
364+ ) {
365+ await page . getByTestId ( `search-dropdown-${ filterLabel } ` ) . click ( ) ;
366+ await expect ( page . getByTestId ( 'drop-down-menu' ) ) . toBeVisible ( ) ;
367+ const option = page . getByTestId ( optionKey ) ;
368+ await expect ( option ) . toBeVisible ( ) ;
369+ await option . click ( ) ;
370+
371+ const filterResponse = page . waitForResponse (
372+ ( r ) =>
373+ r . url ( ) . includes ( '/api/v1/learning/resources' ) &&
374+ r . request ( ) . method ( ) === 'GET'
375+ ) ;
376+ const updateBtn = page . getByTestId ( 'update-btn' ) ;
377+ await expect ( updateBtn ) . toBeVisible ( ) ;
378+ await expect ( updateBtn ) . toBeEnabled ( ) ;
379+ await updateBtn . click ( ) ;
380+
381+ const response = await filterResponse ;
382+ await waitForAllLoadersToDisappear ( page ) ;
383+
384+ return response ;
385+ }
386+
387+ test . describe ( 'Learning Resources - Search and Filters' , ( ) => {
388+ const videoResource = new LearningResourceClass ( {
389+ resourceType : 'Video' ,
390+ categories : [ 'Discovery' ] ,
391+ contexts : [ { pageId : 'glossary' } ] ,
392+ status : 'Active' ,
393+ } ) ;
394+ const storylaneResource = new LearningResourceClass ( {
395+ resourceType : 'Storylane' ,
396+ categories : [ 'DataGovernance' ] ,
397+ contexts : [ { pageId : 'lineage' } ] ,
398+ status : 'Draft' ,
399+ } ) ;
400+
401+ test . beforeAll ( async ( { browser } ) => {
402+ const { apiContext, afterAction } = await createNewPage ( browser ) ;
403+ await videoResource . create ( apiContext ) ;
404+ await storylaneResource . create ( apiContext ) ;
405+ await afterAction ( ) ;
406+ } ) ;
407+
408+ test . afterAll ( async ( { browser } ) => {
409+ const { apiContext, afterAction } = await createNewPage ( browser ) ;
410+ await videoResource . delete ( apiContext ) ;
411+ await storylaneResource . delete ( apiContext ) ;
412+ await afterAction ( ) ;
413+ } ) ;
414+
415+ test . beforeEach ( async ( { page } ) => {
416+ await goToLearningResourcesAdmin ( page ) ;
417+ } ) ;
418+
419+ test ( 'should send correct search param to API when searching' , async ( {
420+ page,
421+ } ) => {
422+ const searchTerm = videoResource . data . name ;
423+
424+ await test . step (
425+ 'Type search term and verify API receives search param' ,
426+ async ( ) => {
427+ const searchResponse = page . waitForResponse (
428+ ( r ) =>
429+ r . url ( ) . includes ( '/api/v1/learning/resources' ) &&
430+ r . url ( ) . includes ( 'search=' ) &&
431+ r . request ( ) . method ( ) === 'GET'
432+ ) ;
433+
434+ await page
435+ . getByRole ( 'textbox' , { name : 'Search Resource' } )
436+ . fill ( searchTerm ) ;
437+ const response = await searchResponse ;
438+ await waitForAllLoadersToDisappear ( page ) ;
439+
440+ expect ( response . url ( ) ) . toContain (
441+ `search=${ encodeURIComponent ( searchTerm ) } `
442+ ) ;
443+ }
444+ ) ;
445+
446+ await test . step ( 'Verify search result is shown in table' , async ( ) => {
447+ await expect (
448+ page . getByText (
449+ videoResource . data . displayName ?? videoResource . data . name
450+ )
451+ ) . toBeVisible ( ) ;
452+ } ) ;
453+ } ) ;
454+
455+ test ( 'should send correct resourceType param when filtering by type' , async ( {
456+ page,
457+ } ) => {
458+ await test . step (
459+ 'Apply Video type filter and verify API param' ,
460+ async ( ) => {
461+ const response = await applyLearningResourceFilter (
462+ page ,
463+ 'Type' ,
464+ 'Video'
465+ ) ;
466+ expect ( response . url ( ) ) . toContain ( 'resourceType=Video' ) ;
467+ }
468+ ) ;
469+
470+ await test . step ( 'Verify filter chip is shown' , async ( ) => {
471+ await expect (
472+ page . locator ( '.filter-selection-chip' ) . filter ( { hasText : 'Video' } )
473+ ) . toBeVisible ( ) ;
474+ } ) ;
475+ } ) ;
476+
477+ test ( 'should send correct category param when filtering by category' , async ( {
478+ page,
479+ } ) => {
480+ await test . step (
481+ 'Apply Discovery category filter and verify API param' ,
482+ async ( ) => {
483+ const response = await applyLearningResourceFilter (
484+ page ,
485+ 'Categories' ,
486+ 'Discovery'
487+ ) ;
488+ expect ( response . url ( ) ) . toContain ( 'category=Discovery' ) ;
489+ }
490+ ) ;
491+
492+ await test . step ( 'Verify filter chip is shown' , async ( ) => {
493+ await expect ( page . getByTitle ( 'Discovery' ) ) . toBeVisible ( ) ;
494+ } ) ;
495+ } ) ;
496+
497+ test ( 'should send correct pageId param when filtering by context' , async ( {
498+ page,
499+ } ) => {
500+ await test . step (
501+ 'Apply Glossary context filter and verify API param' ,
502+ async ( ) => {
503+ const response = await applyLearningResourceFilter (
504+ page ,
505+ 'Context' ,
506+ 'glossary'
507+ ) ;
508+ expect ( response . url ( ) ) . toContain ( 'pageId=glossary' ) ;
509+ }
510+ ) ;
511+
512+ await test . step ( 'Verify filter chip is shown' , async ( ) => {
513+ await expect ( page . getByTitle ( 'Glossary' ) ) . toBeVisible ( ) ;
514+ } ) ;
515+ } ) ;
516+
517+ test ( 'should send correct status param when filtering by status' , async ( {
518+ page,
519+ } ) => {
520+ await test . step (
521+ 'Apply Active status filter and verify API param' ,
522+ async ( ) => {
523+ const response = await applyLearningResourceFilter (
524+ page ,
525+ 'Status' ,
526+ 'Active'
527+ ) ;
528+ expect ( response . url ( ) ) . toContain ( 'status=Active' ) ;
529+ }
530+ ) ;
531+
532+ await test . step ( 'Verify filter chip is shown' , async ( ) => {
533+ await expect ( page . getByTitle ( 'Active' ) ) . toBeVisible ( ) ;
534+ } ) ;
535+ } ) ;
536+
537+ test ( 'should clear all filters and reload without filter params' , async ( {
538+ page,
539+ } ) => {
540+ await test . step ( 'Apply a filter first' , async ( ) => {
541+ await applyLearningResourceFilter ( page , 'Type' , 'Video' ) ;
542+ await expect ( page . getByTitle ( 'Video' ) ) . toBeVisible ( ) ;
543+ } ) ;
544+
545+ await test . step ( 'Clear all filters and verify clean API call' , async ( ) => {
546+ const clearResponse = page . waitForResponse (
547+ ( r ) =>
548+ r . url ( ) . includes ( '/api/v1/learning/resources' ) &&
549+ r . request ( ) . method ( ) === 'GET'
550+ ) ;
551+ await page . getByRole ( 'button' , { name : / c l e a r a l l / i } ) . click ( ) ;
552+ const response = await clearResponse ;
553+ await waitForAllLoadersToDisappear ( page ) ;
554+
555+ expect ( response . url ( ) ) . not . toContain ( 'resourceType=' ) ;
556+ expect ( response . url ( ) ) . not . toContain ( 'category=' ) ;
557+ expect ( response . url ( ) ) . not . toContain ( 'pageId=' ) ;
558+ expect ( response . url ( ) ) . not . toContain ( 'status=' ) ;
559+ expect ( response . url ( ) ) . not . toContain ( 'search=' ) ;
560+ } ) ;
561+
562+ await test . step ( 'Verify filter chips are gone' , async ( ) => {
563+ await expect (
564+ page . locator ( '.filter-selection-container' )
565+ ) . not . toBeVisible ( ) ;
566+ } ) ;
567+ } ) ;
568+ } ) ;
569+
360570test . describe (
361571 'Learning Resources E2E Flow' ,
362572 { tag : [ '@Flow' , '@Platform' ] } ,
0 commit comments