@@ -415,6 +415,146 @@ test.describe('Bulk Edit', () => {
415415 await expect ( page . locator ( '.row-1 .cell-title' ) ) . toContainText ( updatedTitle )
416416 } )
417417
418+ test . describe ( 'preserves URL where filter on bulk actions across pages' , ( ) => {
419+ // Regression coverage for the URL `where` filter being dropped on
420+ // "Select all N across pages" + bulk Publish / Unpublish / Edit.
421+ // Existing "filters and across pages" tests use the search bar (?search=),
422+ // which propagates via a separate code path. The structured ?where[...]
423+ // param was silently dropped between the List view and the bulk drawers.
424+ const filteredTitlePrefix = 'ATM'
425+ const otherTitlePrefix = 'Other'
426+ const seedCount = 6 // exceeds defaultLimit of 5, forces the across-pages button
427+
428+ async function seedFilteredAndOtherPosts ( {
429+ filteredDraft = false ,
430+ otherDraft = false ,
431+ } : { filteredDraft ?: boolean ; otherDraft ?: boolean } = { } ) {
432+ await deleteAllPosts ( )
433+ for ( let i = 1 ; i <= seedCount ; i ++ ) {
434+ await createPost ( { title : `${ filteredTitlePrefix } page ${ i } ` } , { draft : filteredDraft } )
435+ await wait ( 50 )
436+ }
437+ for ( let i = 1 ; i <= seedCount ; i ++ ) {
438+ await createPost ( { title : `${ otherTitlePrefix } page ${ i } ` } , { draft : otherDraft } )
439+ await wait ( 50 )
440+ }
441+ }
442+
443+ const filteredListUrl = ( ) =>
444+ `${ postsUrl . list } ?where[and][0][title][like]=${ encodeURIComponent ( filteredTitlePrefix ) } `
445+
446+ test ( 'should preserve URL where filter on bulk unpublish across pages' , async ( ) => {
447+ await seedFilteredAndOtherPosts ( )
448+
449+ await page . goto ( filteredListUrl ( ) )
450+ await expect . poll ( ( ) => page . url ( ) , { timeout : POLL_TOPASS_TIMEOUT } ) . toContain ( 'where' )
451+ await expect ( page . locator ( '.table table > tbody > tr' ) ) . toHaveCount ( 5 )
452+
453+ await page . locator ( 'input#select-all' ) . check ( )
454+ await page . locator ( 'button#select-all-across-pages' ) . click ( )
455+
456+ await page . locator ( '.list-selection__button[aria-label="Unpublish"]' ) . click ( )
457+ await page . locator ( '#unpublish-posts #confirm-action' ) . click ( )
458+
459+ await expect ( page . locator ( '.payload-toast-container .toast-success' ) ) . toContainText (
460+ `Updated ${ seedCount } Posts successfully.` ,
461+ )
462+
463+ const stillPublishedOthers = await payload . find ( {
464+ collection : postsSlug ,
465+ where : {
466+ and : [ { title : { like : otherTitlePrefix } } , { _status : { equals : 'published' } } ] ,
467+ } ,
468+ } )
469+ expect ( stillPublishedOthers . totalDocs ) . toBe ( seedCount )
470+
471+ const draftedFiltered = await payload . find ( {
472+ collection : postsSlug ,
473+ where : {
474+ and : [ { title : { like : filteredTitlePrefix } } , { _status : { equals : 'draft' } } ] ,
475+ } ,
476+ } )
477+ expect ( draftedFiltered . totalDocs ) . toBe ( seedCount )
478+ } )
479+
480+ test ( 'should preserve URL where filter on bulk publish across pages' , async ( ) => {
481+ await seedFilteredAndOtherPosts ( { filteredDraft : true , otherDraft : true } )
482+
483+ await page . goto ( filteredListUrl ( ) )
484+ await expect . poll ( ( ) => page . url ( ) , { timeout : POLL_TOPASS_TIMEOUT } ) . toContain ( 'where' )
485+ await expect ( page . locator ( '.table table > tbody > tr' ) ) . toHaveCount ( 5 )
486+
487+ await page . locator ( 'input#select-all' ) . check ( )
488+ await page . locator ( 'button#select-all-across-pages' ) . click ( )
489+
490+ await page . locator ( '.list-selection__button[aria-label="Publish"]' ) . click ( )
491+ await page . locator ( '#publish-posts #confirm-action' ) . click ( )
492+
493+ await expect ( page . locator ( '.payload-toast-container .toast-success' ) ) . toContainText (
494+ `Updated ${ seedCount } Posts successfully.` ,
495+ )
496+
497+ const stillDraftOthers = await payload . find ( {
498+ collection : postsSlug ,
499+ where : {
500+ and : [ { title : { like : otherTitlePrefix } } , { _status : { equals : 'draft' } } ] ,
501+ } ,
502+ } )
503+ expect ( stillDraftOthers . totalDocs ) . toBe ( seedCount )
504+
505+ const publishedFiltered = await payload . find ( {
506+ collection : postsSlug ,
507+ where : {
508+ and : [ { title : { like : filteredTitlePrefix } } , { _status : { equals : 'published' } } ] ,
509+ } ,
510+ } )
511+ expect ( publishedFiltered . totalDocs ) . toBe ( seedCount )
512+ } )
513+
514+ test ( 'should preserve URL where filter on bulk edit across pages' , async ( ) => {
515+ await seedFilteredAndOtherPosts ( )
516+ const editedDescription = 'Edited via filtered bulk edit'
517+
518+ await page . goto ( filteredListUrl ( ) )
519+ await expect . poll ( ( ) => page . url ( ) , { timeout : POLL_TOPASS_TIMEOUT } ) . toContain ( 'where' )
520+ await expect ( page . locator ( '.table table > tbody > tr' ) ) . toHaveCount ( 5 )
521+
522+ await page . locator ( 'input#select-all' ) . check ( )
523+ await page . locator ( 'button#select-all-across-pages' ) . click ( )
524+
525+ const { field, modal } = await selectFieldToEdit ( page , {
526+ fieldID : 'description' ,
527+ fieldLabel : 'Description' ,
528+ } )
529+ await field . fill ( editedDescription )
530+ await modal . locator ( '.form-submit button[type="submit"].edit-many__publish' ) . click ( )
531+
532+ await expect ( page . locator ( '.payload-toast-container .toast-success' ) ) . toContainText (
533+ `Updated ${ seedCount } Posts successfully.` ,
534+ )
535+
536+ const editedFiltered = await payload . find ( {
537+ collection : postsSlug ,
538+ where : { description : { equals : editedDescription } } ,
539+ } )
540+ expect ( editedFiltered . totalDocs ) . toBe ( seedCount )
541+ expect ( editedFiltered . docs . every ( ( doc ) => doc . title ?. startsWith ( filteredTitlePrefix ) ) ) . toBe (
542+ true ,
543+ )
544+
545+ const untouchedOthers = await payload . find ( {
546+ collection : postsSlug ,
547+ where : {
548+ and : [
549+ { title : { like : otherTitlePrefix } } ,
550+ { description : { not_equals : editedDescription } } ,
551+ ] ,
552+ } ,
553+ } )
554+ expect ( untouchedOthers . totalDocs ) . toBe ( seedCount )
555+ } )
556+ } )
557+
418558 test ( 'should not override un-edited values if it has a defaultValue' , async ( ) => {
419559 await deleteAllPosts ( )
420560
0 commit comments