-
Notifications
You must be signed in to change notification settings - Fork 33
GAUD-10289 - Add initial divider axe, unit and vdiff tests #7217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b507937
d2cedd3
361c092
ca0ea3c
4e736ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import { createPage } from './page-fixtures.js'; | ||
| import { html } from 'lit'; | ||
|
|
||
| export function createDivider({ | ||
| currentSize = 450, | ||
| maxSize = 600, | ||
| minSize = 320, | ||
| panelType = 'panel', | ||
| panelPosition = 'start' | ||
| } = {}) { | ||
| return html` | ||
| <d2l-page-divider-internal | ||
| label="Resize" | ||
| current-size="${currentSize}" | ||
| min-size="${minSize}" | ||
| max-size="${maxSize}" | ||
| panel-type="${panelType}" | ||
| panel-position="${panelPosition}"> | ||
| </d2l-page-divider-internal> | ||
| `; | ||
| } | ||
|
|
||
| function createDividerPage(options) { | ||
| return createPage({ | ||
| mainHeight: '100px', | ||
| sideNavHeight: '100px', | ||
| supportingHeight: '100px', | ||
| ...options | ||
| }); | ||
| } | ||
|
|
||
| export function getDivider(elem, panelKey) { | ||
| return elem.shadowRoot.querySelector(`d2l-page-divider-internal[data-panel-key="${panelKey}"]`); | ||
| } | ||
|
|
||
| export function getSlider(elem) { | ||
| return elem.shadowRoot.querySelector('.divider'); | ||
| } | ||
|
|
||
| export const pageDividerFixtures = { | ||
| sideNavBothHeaders: createDividerPage({ layout: 'side-nav', hasMainHeader: true, hasSideNavHeader: true }), | ||
| sideNavBothHeadersFooter: createDividerPage({ layout: 'side-nav', hasMainHeader: true, hasSideNavHeader: true, hasFooter: true }), | ||
| sideNavLongMainBothHeaders: createDividerPage({ layout: 'side-nav', hasMainHeader: true, hasSideNavHeader: true, mainHeight: '400px' }), | ||
| sideNavImmersiveFooter: createDividerPage({ layout: 'side-nav', header: 'immersive', hasFooter: true }), | ||
| sideNavImmersiveLongFooter: createDividerPage({ layout: 'side-nav', header: 'immersive', hasFooter: true, sideNavHeight: '400px' }), | ||
| supportingLongFooter: createDividerPage({ layout: 'supporting', hasFooter: true, supportingHeight: '400px' }), | ||
| supportingImmersiveLongMain: createDividerPage({ layout: 'supporting', header: 'immersive', mainHeight: '400px' }), | ||
| supportingImmersiveFooter: createDividerPage({ layout: 'supporting', header: 'immersive', hasFooter: true }), | ||
| supportingImmersiveBothHeaders: createDividerPage({ layout: 'supporting', header: 'immersive', hasMainHeader: true, hasSupportingHeader: true }), | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import '../page-divider-internal.js'; | ||
| import { clickElem, expect, fixture, hoverElem } from '@brightspace-ui/testing'; | ||
| import { getDivider, pageDividerFixtures } from './page-divider-internal-fixtures.js'; | ||
|
|
||
| describe('page-divider-internal', () => { | ||
|
|
||
| it('hover', async() => { | ||
| const elem = await fixture(pageDividerFixtures.supportingImmersiveFooter); | ||
| await hoverElem(getDivider(elem, 'supporting')); | ||
| await expect(elem).to.be.accessible(); | ||
| }); | ||
|
|
||
| it('focus', async() => { | ||
| const elem = await fixture(pageDividerFixtures.sideNavBothHeadersFooter); | ||
| await clickElem(getDivider(elem, 'side-nav')); | ||
| await expect(elem).to.be.accessible(); | ||
| }); | ||
|
|
||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| import { expect, fixture, html, nextFrame, oneEvent, runConstructor, sendKeysElem } from '@brightspace-ui/testing'; | ||
| import { KEYBOARD_STEP, KEYBOARD_STEP_LARGE } from '../page-divider-internal.js'; | ||
| import { createDivider } from './page-divider-internal-fixtures.js'; | ||
|
|
||
| describe('d2l-page-divider-internal', () => { | ||
|
|
||
| it('should construct', () => { | ||
| runConstructor('d2l-page-divider-internal'); | ||
| }); | ||
|
|
||
| describe('accessibility', () => { | ||
| it('calculates aria values correctly', async() => { | ||
| const elem = await fixture(html`<d2l-page-divider-internal label="Resize" min-size="100" max-size="200" current-size="150"></d2l-page-divider-internal>`); | ||
| const slider = elem.shadowRoot.querySelector('.divider'); | ||
| expect(slider.getAttribute('aria-valuemax')).to.equal('200'); | ||
| expect(slider.getAttribute('aria-valuemin')).to.equal('0'); | ||
| expect(slider.getAttribute('aria-valuenow')).to.equal('150'); | ||
| expect(slider.getAttribute('aria-valuetext')).to.equal('75 %'); | ||
| }); | ||
|
|
||
| it('does not set aria values when in unknown state', async() => { | ||
| const elem = await fixture(html`<d2l-page-divider-internal label="Resize"></d2l-page-divider-internal>`); | ||
| const slider = elem.shadowRoot.querySelector('.divider'); | ||
| expect(slider.hasAttribute('aria-valuemax')).to.be.false; | ||
| expect(slider.hasAttribute('aria-valuemin')).to.be.false; | ||
| expect(slider.hasAttribute('aria-valuenow')).to.be.false; | ||
| expect(slider.hasAttribute('aria-valuetext')).to.be.false; | ||
| }); | ||
| }); | ||
|
|
||
| describe('events', () => { | ||
| describe('d2l-page-divider-toggle', () => { | ||
| describe('keyboard', () => { | ||
| ['Enter', ' '].forEach(key => { | ||
| it(`dispatches d2l-page-divider-toggle on "${key === ' ' ? 'Space' : key}"`, async() => { | ||
| const elem = await fixture(createDivider()); | ||
| sendKeysElem(elem, 'press', key); | ||
| const e = await oneEvent(elem, 'd2l-page-divider-toggle'); | ||
| expect(e.detail).to.be.null; // TO DO: Will eventually have the collapse state | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| describe('mouse', () => { | ||
| // TO DO | ||
| }); | ||
|
|
||
| }); | ||
|
|
||
| describe('d2l-page-divider-resize', () => { | ||
| describe('keyboard', () => { | ||
| const currentSize = 450; | ||
| const minSize = 320; | ||
| const maxSize = 600; | ||
| const step = KEYBOARD_STEP; | ||
| const halfStep = Math.ceil(step / 2); | ||
| const largeStep = KEYBOARD_STEP_LARGE; | ||
| const halfLargeStep = Math.ceil(largeStep / 2); | ||
|
|
||
| [ | ||
| { name: 'start panel', panelType: 'panel', panelPosition: 'start', grow: 'ArrowRight', shrink: 'ArrowLeft', inactiveKeys: ['ArrowUp', 'ArrowDown'] }, | ||
| { name: 'end panel', panelType: 'panel', panelPosition: 'end', grow: 'ArrowLeft', shrink: 'ArrowRight', inactiveKeys: ['ArrowUp', 'ArrowDown'] }, | ||
| { name: 'drawer', panelType: 'drawer', grow: 'ArrowUp', shrink: 'ArrowDown', inactiveKeys: ['ArrowLeft', 'ArrowRight'] }, | ||
| { name: 'start panel in rtl', rtl: true, panelType: 'panel', panelPosition: 'start', grow: 'ArrowLeft', shrink: 'ArrowRight', inactiveKeys: ['ArrowUp', 'ArrowDown'] }, | ||
| { name: 'end panel in rtl', rtl: true, panelType: 'panel', panelPosition: 'end', grow: 'ArrowRight', shrink: 'ArrowLeft', inactiveKeys: ['ArrowUp', 'ArrowDown'] }, | ||
| { name: 'drawer rtl', rtl: true, panelType: 'drawer', grow: 'ArrowUp', shrink: 'ArrowDown', inactiveKeys: ['ArrowLeft', 'ArrowRight'] }, | ||
| ].forEach(test => { | ||
|
|
||
| describe(test.name, () => { | ||
|
|
||
| [ | ||
| { action: 'grow', key: test.grow, expectedSize: currentSize + step }, | ||
| { action: 'shrink', key: test.shrink, expectedSize: currentSize - step }, | ||
| { action: 'large grow', key: 'PageUp', expectedSize: currentSize + largeStep }, | ||
| { action: 'large shrink', key: 'PageDown', expectedSize: currentSize - largeStep }, | ||
| { action: 'max', key: 'End', expectedSize: maxSize }, | ||
| { action: 'min', key: 'Home', expectedSize: minSize } | ||
| ].forEach(({ action, key, expectedSize }) => { | ||
| it(`dispatches event with requestedSize ${expectedSize} when "${action}" action requested (Key: ${key})`, async() => { | ||
| const elem = await fixture( | ||
| createDivider({ panelType: test.panelType, panelPosition: test.panelPosition }), | ||
| { rtl: test.rtl } | ||
| ); | ||
| sendKeysElem(elem, 'press', key); | ||
| const e = await oneEvent(elem, 'd2l-page-divider-resize'); | ||
| expect(e.detail.requestedSize).to.equal(expectedSize); | ||
| }); | ||
| }); | ||
|
|
||
| [ | ||
| { action: 'grow', key: test.grow, currentSize: maxSize - halfStep, expectedSize: maxSize }, | ||
| { action: 'shrink', key: test.shrink, currentSize: minSize + halfStep, expectedSize: minSize }, | ||
| { action: 'large grow', key: 'PageUp', currentSize: maxSize - halfLargeStep, expectedSize: maxSize }, | ||
| { action: 'large shrink', key: 'PageDown', currentSize: minSize + halfLargeStep, expectedSize: minSize }, | ||
| { action: 'max', key: 'End', currentSize: maxSize, expectedSize: maxSize }, | ||
| { action: 'min', key: 'Home', currentSize: minSize, expectedSize: minSize } | ||
| ].forEach(({ action, key, currentSize, expectedSize }) => { | ||
| it(`does not ${action} past limits`, async() => { | ||
| const elem = await fixture( | ||
| createDivider({ currentSize, panelType: test.panelType, panelPosition: test.panelPosition }), | ||
| { rtl: test.rtl } | ||
| ); | ||
| sendKeysElem(elem, 'press', key); | ||
| const e = await oneEvent(elem, 'd2l-page-divider-resize'); | ||
| expect(e.detail.requestedSize).to.equal(expectedSize); | ||
| }); | ||
| }); | ||
|
|
||
| it('does not dispatch event when inactive keys pressed', async() => { | ||
| const elem = await fixture( | ||
| createDivider({ panelType: test.panelType, panelPosition: test.panelPosition }), | ||
| { rtl: test.rtl } | ||
| ); | ||
| let dispatched = false; | ||
| elem.addEventListener('d2l-page-divider-resize', () => dispatched = true); | ||
| for (const key of test.inactiveKeys) { | ||
| await sendKeysElem(elem, 'press', key); | ||
| } | ||
| await nextFrame(); | ||
| expect(dispatched).to.be.false; | ||
| }); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| describe('mouse', () => { | ||
| // TO DO | ||
| }); | ||
| }); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| import { expect, fixture, focusElem, hoverElem } from '@brightspace-ui/testing'; | ||
| import { getDivider, pageDividerFixtures } from './page-divider-internal-fixtures.js'; | ||
|
|
||
| describe('page-divider-internal', () => { | ||
|
|
||
| describe('hover', () => { | ||
| [ | ||
| { name: 'side-nav', divider: 'side-nav', fixture: pageDividerFixtures.sideNavBothHeaders }, | ||
| { name: 'supporting-immersive', divider: 'supporting', fixture: pageDividerFixtures.supportingImmersiveFooter } | ||
| ].forEach(test => { | ||
| it(test.name, async() => { | ||
| const elem = await fixture(test.fixture, { pagePadding: false, viewport: { width: 1000, height: 400 } }); | ||
| await hoverElem(getDivider(elem, test.divider)); | ||
| await expect(elem).to.be.golden({ margin: 0 }); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| describe('focus', () => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The variety of focus and focus-scrolled vdiffs is kinda pointless right now, but will eventually be important to show where the collapse button and floating arrows live in the different scenarios. |
||
| [ | ||
| { name: 'side-nav', divider: 'side-nav', fixture: pageDividerFixtures.sideNavBothHeadersFooter }, | ||
| { name: 'side-nav-immersive', divider: 'side-nav', fixture: pageDividerFixtures.sideNavImmersiveFooter }, | ||
| { name: 'side-nav-long-no-scroll', divider: 'side-nav', fixture: pageDividerFixtures.sideNavLongMainBothHeaders }, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| { name: 'supporting', divider: 'supporting', fixture: pageDividerFixtures.supportingLongFooter }, | ||
| { name: 'supporting-immersive', divider: 'supporting', fixture: pageDividerFixtures.supportingImmersiveBothHeaders }, | ||
| { name: 'supporting-immersive-long-no-scroll', divider: 'supporting', fixture: pageDividerFixtures.supportingImmersiveLongMain } | ||
| ].forEach(test => { | ||
| it(test.name, async() => { | ||
| const elem = await fixture(test.fixture, { pagePadding: false, viewport: { width: 1000, height: 400 } }); | ||
| await focusElem(getDivider(elem, test.divider)); | ||
| await expect(elem).to.be.golden({ margin: 0 }); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| describe('focus-scrolled', () => { | ||
| [ | ||
| { name: 'main', divider: 'side-nav', fixture: pageDividerFixtures.sideNavLongMainBothHeaders }, | ||
| { name: 'panel', divider: 'supporting', fixture: pageDividerFixtures.supportingLongFooter }, | ||
| { name: 'immersive-main', divider: 'supporting', fixture: pageDividerFixtures.supportingImmersiveLongMain }, | ||
| { name: 'immersive-panel', divider: 'side-nav', fixture: pageDividerFixtures.sideNavImmersiveLongFooter } | ||
| ].forEach(test => { | ||
| it(test.name, async() => { | ||
| const elem = await fixture(test.fixture, { pagePadding: false, viewport: { width: 1000, height: 400 } }); | ||
| await focusElem(getDivider(elem, test.divider)); | ||
| window.scrollTo(0, document.body.scrollHeight); | ||
| const panel = elem.shadowRoot.querySelector(`.${test.divider}-panel`); | ||
| panel.scrollTop = panel.scrollHeight; | ||
| await expect(elem).to.be.golden({ margin: 0 }); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| describe('keyboard', () => { | ||
| // TO DO once arrow visuals added | ||
| }); | ||
|
|
||
| describe('mouse', () => { | ||
| // TO DO | ||
| }); | ||
|
|
||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it's necessary for all of these to screenshot the whole page vs. just the divider? Just wondering if we could save some time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I thought about it, but most of the visual part of the divider worth testing is how it interacts with the page.
hovercould probably move out, but that's assuming we don't end up adding any additional elements to help with dragging/selecting on hover.I tried to make sure there's not duplication -
pagevdiffs has no focus/hover tests for divider, anddividervdiffs don't test the default state (which is covered bypagevdiffs).I could probably make them shorter though! And a tad less wide, but not much.