@@ -171,8 +171,16 @@ function mergeSessionState(state) {
171171 } ;
172172}
173173
174+ function attachDivWithID ( id ) {
175+ if ( document . getElementById ( id ) ) return ;
176+ const div = document . createElement ( 'DIV' ) ;
177+ div . id = id ;
178+ document . body . appendChild ( div ) ;
179+ }
180+
174181describe ( 'NavigatorCard' , ( ) => {
175182 beforeEach ( ( ) => {
183+ document . body . innerHTML = '' ;
176184 jest . clearAllMocks ( ) ;
177185 // mock the position helper function, as its too difficult to mock the boundingClientRects
178186 getChildPositionInScroller = jest . spyOn ( NavigatorCard . methods , 'getChildPositionInScroller' )
@@ -929,6 +937,7 @@ describe('NavigatorCard', () => {
929937 } ) ;
930938
931939 it ( 'allows filtering the items, opening all items, that have matches in children' , async ( ) => {
940+ attachDivWithID ( root0Child0 . uid ) ;
932941 const wrapper = createWrapper ( ) ;
933942 await flushPromises ( ) ;
934943 // item is not scrolled to
@@ -959,6 +968,7 @@ describe('NavigatorCard', () => {
959968 root0Child1GrandChild0 ,
960969 root1 ,
961970 ] ;
971+ attachDivWithID ( root0Child0 . uid ) ;
962972
963973 const wrapper = createWrapper ( {
964974 propsData : {
@@ -980,6 +990,7 @@ describe('NavigatorCard', () => {
980990 } ) ;
981991
982992 it ( 'renders all the children of a directly matched parent' , async ( ) => {
993+ attachDivWithID ( root0Child0 . uid ) ;
983994 const wrapper = createWrapper ( ) ;
984995 const filter = wrapper . find ( FilterInput ) ;
985996 await flushPromises ( ) ;
@@ -1007,6 +1018,7 @@ describe('NavigatorCard', () => {
10071018 } ) ;
10081019
10091020 it ( 'allows filtering the items using Tags, opening all items, that have matches in children' , async ( ) => {
1021+ attachDivWithID ( root0Child0 . uid ) ;
10101022 const wrapper = createWrapper ( ) ;
10111023 await flushPromises ( ) ;
10121024 const filter = wrapper . find ( FilterInput ) ;
@@ -1024,6 +1036,7 @@ describe('NavigatorCard', () => {
10241036 } ) ;
10251037
10261038 it ( 'aliases `project` to `tutorial`, when filtering using tags' , async ( ) => {
1039+ attachDivWithID ( root0Child0 . uid ) ;
10271040 const wrapper = createWrapper ( ) ;
10281041 const filter = wrapper . find ( FilterInput ) ;
10291042 await flushPromises ( ) ;
@@ -1038,6 +1051,7 @@ describe('NavigatorCard', () => {
10381051 } ) ;
10391052
10401053 it ( 'allows filtering the items with filter and Tags, opening all items, that have matches in children' , async ( ) => {
1054+ attachDivWithID ( root0Child0 . uid ) ;
10411055 const wrapper = createWrapper ( ) ;
10421056 const filter = wrapper . find ( FilterInput ) ;
10431057 await flushPromises ( ) ;
@@ -1742,10 +1756,14 @@ describe('NavigatorCard', () => {
17421756 describe ( 'navigating' , ( ) => {
17431757 it ( 'changes the open item, when navigating across pages, keeping the previously open items' , async ( ) => {
17441758 // simulate navigating to the bottom most item.
1759+ attachDivWithID ( root0Child0 . uid ) ;
17451760 const wrapper = createWrapper ( ) ;
17461761 await flushPromises ( ) ;
1762+ // item is in viewport, no need to scroll to it
1763+ expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 0 ) ;
17471764 // simulate the new item is below the fold
17481765 getChildPositionInScroller . mockReturnValueOnce ( 1 ) ;
1766+ attachDivWithID ( root0Child1GrandChild0 . uid ) ;
17491767 wrapper . setProps ( {
17501768 activePath : [
17511769 root0 . path ,
@@ -1754,6 +1772,7 @@ describe('NavigatorCard', () => {
17541772 ] ,
17551773 } ) ;
17561774 await flushPromises ( ) ;
1775+ expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 1 ) ;
17571776 expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenLastCalledWith ( 3 ) ;
17581777 // assert all are open
17591778 const all = wrapper . findAll ( NavigatorCardItem ) ;
@@ -1786,13 +1805,15 @@ describe('NavigatorCard', () => {
17861805 // simulate the new item is above the scrollarea
17871806 getChildPositionInScroller . mockReturnValueOnce ( - 1 ) ;
17881807 // navigate to the top level sibling
1808+ attachDivWithID ( root1 . uid ) ;
17891809 wrapper . setProps ( {
17901810 activePath : [
17911811 root1 . path ,
17921812 ] ,
17931813 } ) ;
17941814 await flushPromises ( ) ;
17951815 // assert it scrolls to the item
1816+ expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 2 ) ;
17961817 expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenLastCalledWith ( 4 ) ;
17971818 // assert items are still open
17981819 expect ( all . at ( 0 ) . props ( ) ) . toMatchObject ( {
@@ -1828,13 +1849,18 @@ describe('NavigatorCard', () => {
18281849 } ) ;
18291850
18301851 it ( 'tracks current open item, from clicking child items, handling duplicate router changes on the way' , async ( ) => {
1852+ attachDivWithID ( root0Child0 . uid ) ;
18311853 const wrapper = createWrapper ( ) ;
18321854 await flushPromises ( ) ;
1855+ expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 0 ) ;
18331856 let allItems = wrapper . findAll ( NavigatorCardItem ) ;
18341857 const targetChild = allItems . at ( 2 ) ;
18351858 expect ( targetChild . props ( 'item' ) ) . toEqual ( root0Child1 ) ;
18361859 // simulate the new item is below the fold
18371860 getChildPositionInScroller . mockReturnValueOnce ( 1 ) ;
1861+ // add an element with the same ID as the one we are navigating to,
1862+ // otherwise we won't scroll to it
1863+ attachDivWithID ( root0Child1 . uid ) ;
18381864 // trigger a navigation
18391865 targetChild . vm . $emit ( 'navigate' , root0Child1 . uid ) ;
18401866 await wrapper . vm . $nextTick ( ) ;
@@ -2039,9 +2065,10 @@ describe('NavigatorCard', () => {
20392065
20402066 describe ( 'scroll to item' , ( ) => {
20412067 it ( 'resets the scroll position, if initiating a filter' , async ( ) => {
2042- const wrapper = createWrapper ( ) ;
2068+ attachDivWithID ( root0Child0 . uid ) ;
20432069 // simulate item is above the scrollarea
20442070 getChildPositionInScroller . mockReturnValueOnce ( 1 ) ;
2071+ const wrapper = createWrapper ( ) ;
20452072 await flushPromises ( ) ;
20462073 expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 1 ) ;
20472074 expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenLastCalledWith ( 1 ) ;
@@ -2055,43 +2082,45 @@ describe('NavigatorCard', () => {
20552082 expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenLastCalledWith ( 0 ) ;
20562083 } ) ;
20572084
2058- it ( 'keeps the scroll position, if the item is already in the viewport, on navigation' , async ( ) => {
2085+ it ( 'scrolls to item, if HIDE_DEPRECATED_TAG is picked' , async ( ) => {
2086+ attachDivWithID ( root0Child0 . uid ) ;
2087+ // simulate item is in viewport
2088+ getChildPositionInScroller . mockReturnValueOnce ( 0 ) ;
20592089 const wrapper = createWrapper ( ) ;
20602090 await flushPromises ( ) ;
20612091 expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 0 ) ;
2062- wrapper . findAll ( NavigatorCardItem ) . at ( 2 ) . vm . $emit ( 'navigate' , root0Child1 . uid ) ;
2063- await flushPromises ( ) ;
2064- // make sure scrollToItem is not called, because active item is already in the viewport
2065- expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 0 ) ;
2066- // simulate header scroll
2092+ // simulate item is below the viewport
20672093 getChildPositionInScroller . mockReturnValueOnce ( 1 ) ;
2068- wrapper . findAll ( NavigatorCardItem ) . at ( 2 ) . vm . $emit ( 'navigate' , root0Child0 . uid ) ;
2094+ // add the "Hide Deprecated" tag
2095+ wrapper . find ( FilterInput ) . vm . $emit ( 'update:selectedTags' , [ HIDE_DEPRECATED_TAG ] ) ;
20692096 await flushPromises ( ) ;
2070- // make sure scrollToItem is not called, because active item is already in the viewport
2097+ // assert current active item is still scrolled to
20712098 expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 1 ) ;
2099+ expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenLastCalledWith ( 1 ) ;
20722100 } ) ;
20732101
2074- it ( 'scrolls to item, if outside of visible viewport, on page navigation' , async ( ) => {
2102+ it ( 'keeps the scroll position, if the item is already in the viewport, on navigation' , async ( ) => {
2103+ attachDivWithID ( root0Child0 . uid ) ;
20752104 const wrapper = createWrapper ( ) ;
20762105 await flushPromises ( ) ;
2106+ // assert scrollToItem is not called, because its "in view"
20772107 expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 0 ) ;
2078- getChildPositionInScroller . mockReturnValueOnce ( - 1 ) ;
2079- // scroll to the item
2108+ attachDivWithID ( root0Child1 . uid ) ;
20802109 wrapper . findAll ( NavigatorCardItem ) . at ( 2 ) . vm . $emit ( 'navigate' , root0Child1 . uid ) ;
20812110 await flushPromises ( ) ;
2082- // make sure scrollToItem is called
2083- expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 1 ) ;
2084- // assert it was called for the 3-rd item
2085- expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenLastCalledWith ( 2 ) ;
2086- // assert scrolling beyond
2111+ // make sure scrollToItem is not called again, because active item is still in the viewport
2112+ expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 0 ) ;
2113+ // simulate item is below the fold and assert navigating to new place scrolls the item
20872114 getChildPositionInScroller . mockReturnValueOnce ( 1 ) ;
2088- // scroll to the item
2089- wrapper . findAll ( NavigatorCardItem ) . at ( 2 ) . vm . $emit ( 'navigate' , root0Child0 . uid ) ;
2115+ // prepare
2116+ attachDivWithID ( root0Child1GrandChild0 . uid ) ;
2117+ // navigate
2118+ wrapper . findAll ( NavigatorCardItem ) . at ( 2 ) . vm . $emit ( 'navigate' , root0Child1GrandChild0 . uid ) ;
20902119 await flushPromises ( ) ;
2091- // make sure scrollToItem is called
2092- expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 2 ) ;
2093- // assert it was called for the 3-rd item
2094- expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenLastCalledWith ( 1 ) ;
2120+ // assert scrollToItem is called, because item was under the fold
2121+ expect ( RecycleScrollerStub . methods . scrollToItem ) . toHaveBeenCalledTimes ( 1 ) ;
2122+ expect ( RecycleScrollerStub . methods . scrollToItem )
2123+ . toHaveBeenLastCalledWith ( 3 ) ;
20952124 } ) ;
20962125
20972126 it ( 'scrolls to the focused item, if not visible' , async ( ) => {
0 commit comments