From 7f064f9c403fa74b9e69edfb45f888afd0753cdf Mon Sep 17 00:00:00 2001 From: Westbrook Date: Thu, 22 Aug 2019 18:03:08 -0400 Subject: [PATCH] Test coverage --- __snapshots__/Action menu.md | 50 +++++++++++++++ src/action-menu/action-menu.ts | 3 + src/dropdown/dropdown.ts | 12 ++-- test/action-menu.spec.ts | 57 +++++++++++++++++ test/dropdown.spec.ts | 114 ++++++++++++++++++++++++++++++++- 5 files changed, 230 insertions(+), 6 deletions(-) create mode 100644 __snapshots__/Action menu.md create mode 100644 test/action-menu.spec.ts diff --git a/__snapshots__/Action menu.md b/__snapshots__/Action menu.md new file mode 100644 index 0000000000..c69b6cb702 --- /dev/null +++ b/__snapshots__/Action menu.md @@ -0,0 +1,50 @@ +# `Action menu` + +#### `loads` + +```html +Select a Country with a very long label, too long in fact + + + Deselect + + + Select Inverse + + + Feather... + + + Select and Mask... + + + + Save Selection + + + Make Work Path + + +``` + +```html + + + + + + There are no options currently available. + + + +``` diff --git a/src/action-menu/action-menu.ts b/src/action-menu/action-menu.ts index c9e1b32189..c687e30c78 100644 --- a/src/action-menu/action-menu.ts +++ b/src/action-menu/action-menu.ts @@ -32,6 +32,9 @@ export class ActionMenu extends Dropdown { @property({ type: Boolean, reflect: true }) public selected: boolean = false; + protected listRole: string = 'menu'; + protected itemRole: string = 'menuitem'; + protected get buttonContent(): TemplateResult[] { return [ html` diff --git a/src/dropdown/dropdown.ts b/src/dropdown/dropdown.ts index 7cbed79775..fa0f157b67 100644 --- a/src/dropdown/dropdown.ts +++ b/src/dropdown/dropdown.ts @@ -64,6 +64,9 @@ export class Dropdown extends Focusable { @property({ type: String }) public value = ''; + protected listRole: string = 'listbox'; + protected itemRole: string = 'option'; + public constructor() { super(); this.onClick = this.onClick.bind(this); @@ -74,14 +77,14 @@ export class Dropdown extends Focusable { 'sp-menu-item-query-role', (event: CustomEvent) => { event.stopPropagation(); - event.detail.role = 'option'; + event.detail.role = this.itemRole; } ); this.addEventListener( 'sp-menu-query-role', (event: CustomEvent) => { event.stopPropagation(); - event.detail.role = 'listbox'; + event.detail.role = this.listRole; } ); } @@ -134,6 +137,7 @@ export class Dropdown extends Focusable { } public onKeydown(ev: KeyboardEvent): void { + console.warn('keydown', this.optionsMenu); if (ev.code !== 'ArrowDown') { return; } @@ -161,9 +165,7 @@ export class Dropdown extends Focusable { } item.selected = true; this.open = false; - if (this.button) { - this.button.focus(); - } + this.focus(); } public toggle(): void { diff --git a/test/action-menu.spec.ts b/test/action-menu.spec.ts new file mode 100644 index 0000000000..91de3275f2 --- /dev/null +++ b/test/action-menu.spec.ts @@ -0,0 +1,57 @@ +/* +Copyright 2019 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +import { fixture, elementUpdated } from '@open-wc/testing'; +import { ActionMenu } from '../lib/action-menu'; +import '../lib/action-menu'; +import { html } from 'lit-element'; +import { expect } from '@bundled-es-modules/chai'; + +describe('Action menu', () => { + it('loads', async () => { + const el = await fixture( + html` + + Select a Country with a very long label, too long in fact + + + Deselect + + + Select Inverse + + + Feather... + + + Select and Mask... + + + + Save Selection + + + Make Work Path + + + + ` + ); + + await elementUpdated(el); + expect(el).to.not.be.undefined; + // @ts-ignore + expect(el).lightDom.to.equalSnapshot(); + // @ts-ignore + expect(el).shadowDom.to.equalSnapshot(); + }); +}); diff --git a/test/dropdown.spec.ts b/test/dropdown.spec.ts index b6f7efa11e..09043b3143 100644 --- a/test/dropdown.spec.ts +++ b/test/dropdown.spec.ts @@ -11,10 +11,20 @@ governing permissions and limitations under the License. */ import { fixture, elementUpdated } from '@open-wc/testing'; -import { Dropdown } from '../lib/dropdown'; import '../lib/dropdown'; +import { Dropdown } from '../lib/dropdown'; import { html } from 'lit-element'; import { expect } from '@bundled-es-modules/chai'; +import { MenuItem } from '../lib/menu-item'; + +const keyboardEvent = (code: string) => + new KeyboardEvent('keydown', { + bubbles: true, + composed: true, + cancelable: true, + code, + }); +const arrowDownEvent = keyboardEvent('ArrowDown'); describe('Dropdown', () => { it('loads', async () => { @@ -54,4 +64,106 @@ describe('Dropdown', () => { // @ts-ignore expect(el).shadowDom.to.equalSnapshot(); }); + it('selects', async () => { + const el = await fixture( + html` + + Select a Country with a very long label, too long in fact + + + Deselect + + + Select Inverse + + + Feather... + + + Select and Mask... + + + + Save Selection + + + Make Work Path + + + + ` + ); + + await elementUpdated(el); + + const secondItem = el.querySelector( + 'sp-menu-item:nth-of-type(2)' + ) as MenuItem; + const button = el.button as HTMLButtonElement; + + button.click(); + await elementUpdated(el); + + expect(el.open).to.be.true; + expect(button.textContent!.trim()).to.equal(''); + + secondItem.click(); + await elementUpdated(el); + + expect(el.open).to.be.false; + expect(button.textContent!.trim()).to.equal('Select Inverse'); + }); + + it('opens on ArrowDown', async () => { + const el = await fixture( + html` + + Select a Country with a very long label, too long in fact + + + Deselect + + + Select Inverse + + + Feather... + + + Select and Mask... + + + + Save Selection + + + Make Work Path + + + + ` + ); + + await elementUpdated(el); + + const firstItem = el.querySelector( + 'sp-menu-item:nth-of-type(1)' + ) as MenuItem; + const button = el.button as HTMLButtonElement; + + el.focus(); + await elementUpdated(el); + + button.dispatchEvent(arrowDownEvent); + await elementUpdated(el); + + expect(el.open).to.be.true; + expect(button.textContent!.trim()).to.equal(''); + + firstItem.click(); + await elementUpdated(el); + + expect(el.open).to.be.false; + expect(button.textContent!.trim()).to.equal('Deselect'); + }); });