diff options
author | Paul Slaughter <pslaughter@gitlab.com> | 2020-05-29 02:19:52 +0300 |
---|---|---|
committer | Evan Read <eread@gitlab.com> | 2020-05-29 02:19:52 +0300 |
commit | b871f1c7b1c70dc02f2aa495da5f1f6a17206676 (patch) | |
tree | 4a14bd0251c145297768a16b2a63af61a3531fd0 /spec/frontend/default | |
parent | 38cbfc7c7b559b3b39c546aaf488f18e551ffd1a (diff) |
Update table of contents redesign for mobile
- Introduces a toc-sm and toc-lg class to
help with rendering of sm and lg header.
- Implements some responsive helpers like
toc-level-#i and toc-separator
- Update unit tests
Diffstat (limited to 'spec/frontend/default')
3 files changed, 232 insertions, 127 deletions
diff --git a/spec/frontend/default/components/__snapshots__/table_of_contents_spec.js.snap b/spec/frontend/default/components/__snapshots__/table_of_contents_spec.js.snap index 6483dea6..164fde41 100644 --- a/spec/frontend/default/components/__snapshots__/table_of_contents_spec.js.snap +++ b/spec/frontend/default/components/__snapshots__/table_of_contents_spec.js.snap @@ -5,124 +5,149 @@ exports[`frontend/default/components/table_of_contents matches snapshot 1`] = ` class="table-of-contents-container position-relative" id="markdown-toc" > - <a - aria-controls="markdown-toc" - class="toc-collapse collapsed" - data-testid="collapse" - href="#" - role="button" - /> - <div - class="table-of-contents sm-collapsed" - data-testid="container" + class="table-of-contents" > - <h4> - On this page: + <h4 + class="border-0 toc-sm" + > + <a + aria-controls="markdown-toc" + aria-expanded="true" + class="d-flex text-decoration-none" + data-testid="collapse" + href="#" + role="button" + > + <i + class="fa d-flex align-items-center justify-content-center mr-1 gl-w-3 fa-angle-down" + role="presentation" + /> + + On this page + + </a> </h4> - <ul - class="nav nav-pills flex-column my-0" - data-testid="main-list" + <h4 + class="border-0 gl-font-base font-weight-bold toc-lg" > - <li> - <a - class="nav-link" - href="#lorem" - id="Lorem-anchor" - > - Lorem - </a> - - <ul - class="nav nav-pills flex-column" + On this page + </h4> + + <div + class="" + data-testid="container" + > + <ul + class="nav nav-pills flex-column my-0" + data-testid="main-list" + > + <li + class="" > - <li> - <a - class="nav-link" - href="#lorem-" - id="Lorem 2-anchor" + <a + class="nav-link d-block toc-level-0" + href="#lorem" + id="Lorem-anchor" + > + Lorem + </a> + + <ul + class="nav nav-pills flex-column" + > + <li + class="" > - Lorem 2 - </a> - - <!----> - </li> - </ul> - </li> - <li> - <a - class="nav-link" - href="#ipsum" - id="Ipsum-anchor" - > - Ipsum - </a> - - <ul - class="nav nav-pills flex-column" + <a + class="nav-link d-block toc-level-1" + href="#lorem-" + id="Lorem 2-anchor" + > + Lorem 2 + </a> + + <!----> + </li> + </ul> + </li> + <li + class="" > - <li> - <a - class="nav-link" - href="#dolar" - id="Dolar-anchor" - > - Dolar - </a> - - <ul - class="nav nav-pills flex-column" + <a + class="nav-link d-block toc-level-0" + href="#ipsum" + id="Ipsum-anchor" + > + Ipsum + </a> + + <ul + class="nav nav-pills flex-column" + > + <li + class="" > - <li> - <a - class="nav-link" - href="#sit" - id="Sit-anchor" + <a + class="nav-link d-block toc-level-1" + href="#dolar" + id="Dolar-anchor" + > + Dolar + </a> + + <ul + class="nav nav-pills flex-column" + > + <li + class="" > - Sit - </a> - - <!----> - </li> - <li> - <a - class="nav-link" - href="#amit" - id="Amit-anchor" + <a + class="nav-link d-block toc-level-2" + href="#sit" + id="Sit-anchor" + > + Sit + </a> + + <!----> + </li> + <li + class="" > - Amit - </a> - - <!----> - </li> - <li> - <a - class="nav-link" - href="#test" - id="Test-anchor" + <a + class="nav-link d-block toc-level-2" + href="#amit" + id="Amit-anchor" + > + Amit + </a> + + <!----> + </li> + <li + class="" > - Test - </a> - - <!----> - </li> - </ul> - </li> - </ul> - </li> - </ul> - - <div - class="border-top mt-3 pt-3" - > - <ul - class="nav nav-pills flex-column my-0" - data-testid="help-and-feedback" - > - <li> + <a + class="nav-link d-block toc-level-2" + href="#test" + id="Test-anchor" + > + Test + </a> + + <!----> + </li> + </ul> + </li> + </ul> + </li> + <li + class="toc-separator" + > <a - class="nav-link" + class="nav-link d-block toc-level-0" href="#test-help-and-feedback" > Help and feedback diff --git a/spec/frontend/default/components/table_of_contents_list_spec.js b/spec/frontend/default/components/table_of_contents_list_spec.js index 2d69f880..302c153f 100644 --- a/spec/frontend/default/components/table_of_contents_list_spec.js +++ b/spec/frontend/default/components/table_of_contents_list_spec.js @@ -15,6 +15,8 @@ describe('frontend/default/components/table_of_contents_list', () => { }; const findItemsData = () => parseTOC(wrapper.element); + const findLinks = () => wrapper.findAll('a'); + const findListItems = () => wrapper.findAll('li'); afterEach(() => { wrapper.destroy(); @@ -32,6 +34,14 @@ describe('frontend/default/components/table_of_contents_list', () => { it('renders all items', () => { expect(findItemsData()).toEqual(items); }); + + it('starts at level 0', () => { + expect( + findLinks() + .at(0) + .classes('toc-level-0'), + ).toBe(true); + }); }); describe('with empty items', () => { @@ -43,4 +53,70 @@ describe('frontend/default/components/table_of_contents_list', () => { expect(wrapper.element).toMatchSnapshot(); }); }); + + describe('with level', () => { + beforeEach(() => { + createComponent({ + items: [ + { + text: 'A', + items: [{ text: 'A_1' }, { text: 'A_2' }], + }, + { + text: 'B', + items: [{ text: 'B_1', items: [{ text: 'B_1_1' }] }], + }, + ], + level: 1, + }); + }); + + it('increments levels for nested lists', () => { + // Order isn't important. We just want to find the link + level class mapping + const data = findLinks().wrappers.reduce( + (acc, link) => + Object.assign(acc, { + [link.text()]: link.classes().find(x => x.startsWith('toc-level')), + }), + {}, + ); + + expect(data).toEqual({ + A: 'toc-level-1', + A_1: 'toc-level-2', + A_2: 'toc-level-2', + B: 'toc-level-1', + B_1: 'toc-level-2', + B_1_1: 'toc-level-3', + }); + }); + }); + + describe('with separator', () => { + beforeEach(() => { + createComponent({ + items: [ + { + text: 'Lorem', + }, + { + text: 'Ipsum', + withSeparator: true, + }, + ], + }); + }); + + it('has separator class for separator item', () => { + const data = findListItems().wrappers.map(x => ({ + text: x.text(), + hasSeparator: x.classes('toc-separator'), + })); + + expect(data).toEqual([ + { text: 'Lorem', hasSeparator: false }, + { text: 'Ipsum', hasSeparator: true }, + ]); + }); + }); }); diff --git a/spec/frontend/default/components/table_of_contents_spec.js b/spec/frontend/default/components/table_of_contents_spec.js index a256cae5..6585289d 100644 --- a/spec/frontend/default/components/table_of_contents_spec.js +++ b/spec/frontend/default/components/table_of_contents_spec.js @@ -30,11 +30,18 @@ describe('frontend/default/components/table_of_contents', () => { }; const findCollapseButton = () => wrapper.find('[data-testid="collapse"]'); + const findCollapseIcon = () => findCollapseButton().find('i'); const findCollapsibleContainer = () => wrapper.find('[data-testid="container"]'); const findMainList = () => wrapper.find('[data-testid="main-list"]'); - const findHelpAndFeedback = () => wrapper.find('[data-testid="help-and-feedback"]'); + const findMainListItems = () => findMainList().props('items'); const clickCollapseButton = () => findCollapseButton().trigger('click'); + const expectCollapsed = (isCollapsed = true) => { + expect(findCollapseButton().attributes('aria-expanded')).toBe(isCollapsed ? undefined : 'true'); + expect(findCollapsibleContainer().props('isCollapsed')).toBe(isCollapsed); + expect(findCollapseIcon().classes(isCollapsed ? 'fa-angle-right' : 'fa-angle-down')).toBe(true); + }; + it('matches snapshot', () => { createComponent({ hasHelpAndFeedback: true }, mount); expect(wrapper.element).toMatchSnapshot(); @@ -45,16 +52,18 @@ describe('frontend/default/components/table_of_contents', () => { createComponent({ hasHelpAndFeedback: true }); }); - it('shows help and feedback', () => { - expect(findHelpAndFeedback().exists()).toBe(true); - expect(findHelpAndFeedback().props('items')).toEqual([ - { - href: `#${TEST_HELP_AND_FEEDBACK_ID}`, - id: null, - items: [], - text: 'Help and feedback', - }, - ]); + it('appends help and feedback item', () => { + expect(findMainListItems()).toEqual( + TEST_ITEMS.concat([ + { + href: `#${TEST_HELP_AND_FEEDBACK_ID}`, + id: null, + items: [], + text: 'Help and feedback', + withSeparator: true, + }, + ]), + ); }); }); @@ -63,17 +72,12 @@ describe('frontend/default/components/table_of_contents', () => { createComponent({}, mount); }); - it('does not show help and feedback', () => { - expect(findHelpAndFeedback().exists()).toBe(false); - }); - it('renders toc list', () => { - expect(findMainList().props('items')).toEqual(TEST_ITEMS); + expect(findMainListItems()).toEqual(TEST_ITEMS); }); - it('is initially collapsed', () => { - expect(findCollapseButton().classes('collapsed')).toBe(true); - expect(findCollapsibleContainer().classes('sm-collapsed')).toBe(true); + it('is initially uncollapsed', () => { + expectCollapsed(false); }); describe('when collapse button is pressed', () => { @@ -85,8 +89,8 @@ describe('frontend/default/components/table_of_contents', () => { expect(findCollapsibleContainer().classes('sm-collapsing')).toBe(true); }); - it('updates button class', () => { - expect(findCollapseButton().classes('collapsed')).toBe(false); + it('immediately updates collapse status', () => { + expectCollapsed(true); }); it('when button pressed again, nothing happens because in the middle of collapsing', () => { @@ -94,7 +98,7 @@ describe('frontend/default/components/table_of_contents', () => { return wrapper.vm.$nextTick(() => { expect(findCollapsibleContainer().classes('sm-collapsing')).toBe(true); - expect(findCollapseButton().classes('collapsed')).toBe(false); + expectCollapsed(true); }); }); }); |