@@ -732,6 +732,81 @@ test.describe('test nav at different viewports', () => {
732732 } )
733733} )
734734
735+ test . describe ( 'secondary-bar breadcrumb scroller' , ( ) => {
736+ // The secondary bar (and its breadcrumb scroller) only renders at wide
737+ // viewports, and the fixture trail is short enough to fit there, so we cap the
738+ // scroller width to force a deterministic overflow independent of title
739+ // lengths — then exercise the chevrons.
740+ test ( 'chevrons scroll one crumb at a time instead of jumping to the ends' , async ( { page } ) => {
741+ // Smooth-scroll settle waits across several chevron clicks add up past the
742+ // default 5s cap.
743+ test . setTimeout ( 20000 )
744+ page . setViewportSize ( { width : 1300 , height : 700 } )
745+ await page . goto ( '/get-started/foo/bar' )
746+
747+ const bar = page . getByTestId ( 'breadcrumbs-bar' )
748+ await expect ( bar ) . toBeVisible ( )
749+
750+ const scrollArea = page . locator ( '[data-search="breadcrumbs"]' )
751+ await expect ( scrollArea ) . toBeVisible ( )
752+
753+ // Force a deterministic overflow independent of title lengths: cap the
754+ // scroll region, drop the nav's min-width:100% (which otherwise stretches the
755+ // short fixture trail to fill the container so it never overflows), and pad
756+ // the crumbs so several are hidden at once — enough that a per-crumb nudge is
757+ // distinguishable from a jump to the end.
758+ await page . addStyleTag ( {
759+ content : `
760+ [data-search="breadcrumbs"] { max-width: 360px; }
761+ [data-search="breadcrumbs"] nav { min-width: 0 !important; }
762+ [data-search="breadcrumbs"] li { padding-right: 60px; }
763+ ` ,
764+ } )
765+
766+ const scrollLeftOf = ( ) => scrollArea . evaluate ( ( el ) => el . scrollLeft )
767+ const maxScrollOf = ( ) => scrollArea . evaluate ( ( el ) => el . scrollWidth - el . clientWidth )
768+ await expect . poll ( maxScrollOf ) . toBeGreaterThan ( 0 )
769+
770+ // Anchor to the right end explicitly so we start from a known state: fully
771+ // scrolled right (current page visible), only the left chevron active.
772+ await scrollArea . evaluate ( ( el ) => el . scrollTo ( { left : el . scrollWidth , behavior : 'instant' } ) )
773+ const maxScroll = await maxScrollOf ( )
774+ await expect . poll ( scrollLeftOf ) . toBe ( maxScroll )
775+
776+ const leftChevron = page . getByRole ( 'button' , { name : 'Scroll breadcrumbs left' } )
777+ const rightChevron = page . getByRole ( 'button' , { name : 'Scroll breadcrumbs right' } )
778+ // At the right extreme the left chevron is active and the right one is hidden.
779+ await expect ( leftChevron ) . toBeVisible ( )
780+ await expect ( rightChevron ) . toBeHidden ( )
781+
782+ // One left click nudges toward the start by a single crumb — it must move,
783+ // but must NOT jump all the way to 0 (the old behavior) while more than one
784+ // crumb is still hidden to the left.
785+ await leftChevron . click ( )
786+ await expect . poll ( scrollLeftOf ) . toBeLessThan ( maxScroll )
787+ const afterOneLeft = await scrollLeftOf ( )
788+ expect ( afterOneLeft ) . toBeGreaterThan ( 0 )
789+ // The right chevron appears once we're no longer at the right extreme.
790+ await expect ( rightChevron ) . toBeVisible ( )
791+
792+ // A right click walks back toward the current page by one crumb, not a full
793+ // jump back to the right extreme.
794+ await rightChevron . click ( )
795+ await expect . poll ( scrollLeftOf ) . toBeGreaterThan ( afterOneLeft )
796+
797+ // Repeated left clicks eventually reach the start, which hides the left
798+ // chevron (canScrollLeft flips false). Drive off the chevron's own visibility
799+ // rather than an exact scrollLeft, since smooth scrolling can leave a
800+ // sub-pixel remainder.
801+ for ( let i = 0 ; i < 6 && ( await leftChevron . isVisible ( ) ) ; i ++ ) {
802+ await leftChevron . click ( )
803+ await page . waitForTimeout ( 200 )
804+ }
805+ await expect ( leftChevron ) . toBeHidden ( )
806+ await expect . poll ( scrollLeftOf ) . toBeLessThanOrEqual ( 1 )
807+ } )
808+ } )
809+
735810test . describe ( 'survey' , ( ) => {
736811 test . skip ( ! ANALYTICS_ENABLED , 'Analytics are disabled' )
737812
0 commit comments