diff --git a/packages/a11y-base/test/focus-trap-controller.test.js b/packages/a11y-base/test/focus-trap-controller.test.js index c9a3bbb24f..67539939ce 100644 --- a/packages/a11y-base/test/focus-trap-controller.test.js +++ b/packages/a11y-base/test/focus-trap-controller.test.js @@ -58,9 +58,7 @@ async function tab() { } async function shiftTab() { - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); return document.activeElement; } diff --git a/packages/app-layout/test/helpers.js b/packages/app-layout/test/helpers.js index 1e39d55985..0780913471 100644 --- a/packages/app-layout/test/helpers.js +++ b/packages/app-layout/test/helpers.js @@ -9,7 +9,5 @@ export async function tab() { } export async function shiftTab() { - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); } diff --git a/packages/checkbox-group/test/checkbox-group.common.js b/packages/checkbox-group/test/checkbox-group.common.js index d53b29967d..e91bc8335f 100644 --- a/packages/checkbox-group/test/checkbox-group.common.js +++ b/packages/checkbox-group/test/checkbox-group.common.js @@ -287,9 +287,7 @@ describe('vaadin-checkbox-group', () => { await sendKeys({ press: 'Tab' }); // Move focus out of the checkbox group. - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(checkboxes[0].hasAttribute('focused')).to.be.false; expect(group.hasAttribute('focused')).to.be.false; diff --git a/packages/checkbox-group/test/validation.common.js b/packages/checkbox-group/test/validation.common.js index a109f6ea3f..a383c8d875 100644 --- a/packages/checkbox-group/test/validation.common.js +++ b/packages/checkbox-group/test/validation.common.js @@ -82,9 +82,7 @@ describe('validation', () => { expect(validateSpy.called).to.be.false; // Move focus out of the checkbox group. - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(validateSpy.calledOnce).to.be.true; }); @@ -132,9 +130,7 @@ describe('validation', () => { await sendKeys({ press: 'Tab' }); // Move focus out of the checkbox group. - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(validateSpy.called).to.be.false; }); diff --git a/packages/checkbox/test/validation.common.js b/packages/checkbox/test/validation.common.js index 44d3ef6046..749c02ff9b 100644 --- a/packages/checkbox/test/validation.common.js +++ b/packages/checkbox/test/validation.common.js @@ -108,9 +108,7 @@ describe('validation', () => { await sendKeys({ press: 'Tab' }); // Blur the checkbox. - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(validateSpy.called).to.be.false; }); diff --git a/packages/component-base/test/virtualizer-reorder-elements.test.js b/packages/component-base/test/virtualizer-reorder-elements.test.js index 22c4770519..c34071b2eb 100644 --- a/packages/component-base/test/virtualizer-reorder-elements.test.js +++ b/packages/component-base/test/virtualizer-reorder-elements.test.js @@ -152,9 +152,7 @@ describe('reorder elements', () => { // Tab upwards for (let i = tabToIndex - 1; i >= 0; i--) { await nextFrame(); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); await nextFrame(); expect(document.activeElement.id).to.equal(`item-${i}`); } diff --git a/packages/context-menu/test/a11y.common.js b/packages/context-menu/test/a11y.common.js index 54df497ef1..a7f6ffeb0b 100644 --- a/packages/context-menu/test/a11y.common.js +++ b/packages/context-menu/test/a11y.common.js @@ -79,9 +79,7 @@ describe('a11y', () => { it('should move focus to the prev element outside the menu on Shift+Tab pressed inside', async () => { contextMenuButton.click(); await nextRender(); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(getDeepActiveElement()).to.equal(firstGlobalFocusable); }); diff --git a/packages/dashboard/test/dashboard-keyboard.test.ts b/packages/dashboard/test/dashboard-keyboard.test.ts index 8441fc8d8f..d0b4a6bba6 100644 --- a/packages/dashboard/test/dashboard-keyboard.test.ts +++ b/packages/dashboard/test/dashboard-keyboard.test.ts @@ -88,9 +88,7 @@ describe('dashboard - keyboard interaction', () => { await sendKeys({ press: 'Space' }); // Focus the focus-button with shift + tab - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); // Click the focus-button await sendKeys({ press: 'Space' }); @@ -158,9 +156,7 @@ describe('dashboard - keyboard interaction', () => { it('should blur deselected widget on shift tab', async () => { const widget = getElementFromCell(dashboard, 0, 0)!; await sendKeys({ press: 'Escape' }); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(widget.hasAttribute('selected')).to.be.false; expect(widget.hasAttribute('focused')).to.be.false; expect(widget.contains(document.activeElement)).to.be.false; @@ -233,29 +229,23 @@ describe('dashboard - keyboard interaction', () => { it('should increase the widget row span on shift + arrow down', async () => { // Set minimum row height to enable vertical resizing setMinimumRowHeight(dashboard, 100); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'ArrowDown' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+ArrowDown' }); expect((dashboard.items[0] as DashboardItem).rowspan).to.equal(2); }); it('should decrease the widget row span on shift + arrow up', async () => { // Set minimum row height to enable vertical resizing setMinimumRowHeight(dashboard, 100); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'ArrowDown' }); + await sendKeys({ press: 'Shift+ArrowDown' }); await updateComplete(dashboard); - await sendKeys({ press: 'ArrowUp' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+ArrowUp' }); expect((dashboard.items[0] as DashboardItem).rowspan).to.equal(1); }); it('should dispatch an item resized event shift + arrow down', async () => { const spy = sinon.spy(); dashboard.addEventListener('dashboard-item-resized', spy); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'ArrowDown' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+ArrowDown' }); expect(spy.calledOnce).to.be.true; expect(spy.firstCall.args[0].detail.item).to.eql({ id: 0 }); expect(spy.firstCall.args[0].detail.items).to.eql(dashboard.items); @@ -266,23 +256,17 @@ describe('dashboard - keyboard interaction', () => { const spy = sinon.spy(); // @ts-ignore unexpected event type dashboard.addEventListener('item-resize', spy); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'ArrowDown' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+ArrowDown' }); expect(spy.called).to.be.false; }); it('should not increase the widget row span on shift + arrow down if row min height is not defined', async () => { - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'ArrowDown' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+ArrowDown' }); expect((dashboard.items[0] as DashboardItem).rowspan).to.not.equal(2); }); it('should not move the widget on arrow down if ctrl key is pressed', async () => { - await sendKeys({ down: 'Control' }); - await sendKeys({ press: 'ArrowDown' }); - await sendKeys({ up: 'Control' }); + await sendKeys({ press: 'Control+ArrowDown' }); expect(dashboard.items).to.eql([{ id: 0 }, { id: 1 }, { items: [{ id: 2 }, { id: 3 }] }]); }); @@ -341,9 +325,7 @@ describe('dashboard - keyboard interaction', () => { it('should release focus trap on deselect', async () => { const widget = getElementFromCell(dashboard, 0, 0)!; await sendKeys({ press: 'Escape' }); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(widget.contains(document.activeElement)).to.be.false; }); @@ -369,18 +351,14 @@ describe('dashboard - keyboard interaction', () => { }); it('should increase the widget column span on shift + arrow forwards', async () => { - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: arrowForwards }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: `Shift+${arrowForwards}` }); expect((dashboard.items[0] as DashboardItem).colspan).to.equal(2); }); it('should decrease the widget column span on shift + arrow backwards', async () => { - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: arrowForwards }); + await sendKeys({ press: `Shift+${arrowForwards}` }); await updateComplete(dashboard); - await sendKeys({ press: arrowBackwards }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: `Shift+${arrowBackwards}` }); expect((dashboard.items[0] as DashboardItem).colspan).to.equal(1); }); }); @@ -412,9 +390,7 @@ describe('dashboard - keyboard interaction', () => { it('should blur deselected selected on shift tab', async () => { await sendKeys({ press: 'Escape' }); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(section.hasAttribute('selected')).to.be.false; expect(section.hasAttribute('focused')).to.be.false; expect(section.contains(document.activeElement)).to.be.false; @@ -446,16 +422,12 @@ describe('dashboard - keyboard interaction', () => { it('should release focus trap on deselect', async () => { await sendKeys({ press: 'Escape' }); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(section.contains(document.activeElement)).to.be.false; }); it('should not increase the section row span on shift + arrow down', async () => { - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'ArrowDown' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+ArrowDown' }); expect(dashboard.items).to.eql([{ id: 0 }, { id: 1 }, { items: [{ id: 2 }, { id: 3 }] }]); }); }); @@ -565,10 +537,8 @@ describe('dashboard - keyboard interaction', () => { await sendKeys({ press: 'Space' }); await nextFrame(); // Focus backward button, click it - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); + await sendKeys({ press: 'Shift+Tab' }); await nextFrame(); expect(getMoveBackwardButton(widget).matches(':focus')).to.be.true; @@ -598,10 +568,8 @@ describe('dashboard - keyboard interaction', () => { await sendKeys({ press: 'Space' }); await nextFrame(); // Focus backwards button, click it - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); + await sendKeys({ press: 'Shift+Tab' }); await sendKeys({ press: 'Space' }); await nextFrame(); diff --git a/packages/date-picker/test/fullscreen.common.js b/packages/date-picker/test/fullscreen.common.js index 2dc7b5543a..08e8d670c2 100644 --- a/packages/date-picker/test/fullscreen.common.js +++ b/packages/date-picker/test/fullscreen.common.js @@ -157,9 +157,7 @@ describe('fullscreen mode', () => { it('should move focus to Cancel button on date cell Shift Tab', async () => { const spy = sinon.spy(overlayContent._cancelButton, 'focus'); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(spy.calledOnce).to.be.true; }); @@ -169,9 +167,7 @@ describe('fullscreen mode', () => { const spy = sinon.spy(cell, 'focus'); // Move focus to Cancel button - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); await sendKeys({ press: 'Tab' }); diff --git a/packages/date-picker/test/keyboard-input.common.js b/packages/date-picker/test/keyboard-input.common.js index 9c7dbd0569..a1b1a79c43 100644 --- a/packages/date-picker/test/keyboard-input.common.js +++ b/packages/date-picker/test/keyboard-input.common.js @@ -258,9 +258,7 @@ describe('keyboard', () => { const spy = sinon.spy(input, 'focus'); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(spy.calledOnce).to.be.true; }); @@ -273,9 +271,7 @@ describe('keyboard', () => { }); it('should move focus to Cancel button on input Shift Tab', async () => { - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(overlayContent._cancelButton.hasAttribute('focused')).to.be.true; }); @@ -283,9 +279,7 @@ describe('keyboard', () => { const spy = sinon.spy(overlayContent, 'revealDate'); overlayContent._todayButton.focus(); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); await aTimeout(1); expect(spy.called).to.be.true; @@ -328,9 +322,7 @@ describe('keyboard', () => { overlayContent._todayButton.focus(); // Move focus to the calendar - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); await waitForScrollToFinish(datePicker); diff --git a/packages/date-picker/test/keyboard-navigation.common.js b/packages/date-picker/test/keyboard-navigation.common.js index 685a2daba4..08ce25e56e 100644 --- a/packages/date-picker/test/keyboard-navigation.common.js +++ b/packages/date-picker/test/keyboard-navigation.common.js @@ -342,17 +342,13 @@ describe('keyboard navigation', () => { }); it('should focus next year with shift and pagedown', async () => { - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'PageDown' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+PageDown' }); await waitForScrollToFinish(overlay); expect(overlay.focusedDate).to.eql(new Date(2001, 0, 1)); }); it('should focus previous year with shift and pageup', async () => { - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'PageUp' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+PageUp' }); await waitForScrollToFinish(overlay); expect(overlay.focusedDate).to.eql(new Date(1999, 0, 1)); }); @@ -361,9 +357,7 @@ describe('keyboard navigation', () => { const spy = sinon.spy(); overlay.addEventListener('scroll-animation-finished', spy); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'PageUp' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+PageUp' }); await waitForScrollToFinish(overlay); const e = spy.firstCall.args[0]; @@ -382,9 +376,7 @@ describe('keyboard navigation', () => { const spy = sinon.spy(); overlay.addEventListener('scroll-animation-finished', spy); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'PageDown' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+PageDown' }); await waitForScrollToFinish(overlay); const e = spy.firstCall.args[0]; @@ -455,9 +447,7 @@ describe('keyboard navigation', () => { it('should focus max date with shift and pagedown', async () => { overlay.maxDate = new Date(2000, 11, 28); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'PageDown' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+PageDown' }); await waitForScrollToFinish(overlay); const cell = getFocusedCell(overlay); @@ -467,9 +457,7 @@ describe('keyboard navigation', () => { it('should focus min date with shift and pageup', async () => { overlay.minDate = new Date(1999, 5, 3); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'PageUp' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+PageUp' }); await waitForScrollToFinish(overlay); const cell = getFocusedCell(overlay); @@ -501,9 +489,7 @@ describe('keyboard navigation', () => { overlay.minDate = new Date(1999, 11, 25); await nextRender(overlay); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'PageUp' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+PageUp' }); await waitForScrollToFinish(overlay); const cell = getFocusedCell(overlay); @@ -515,9 +501,7 @@ describe('keyboard navigation', () => { overlay.maxDate = new Date(1999, 11, 25); await nextRender(overlay); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'PageDown' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+PageDown' }); await waitForScrollToFinish(overlay); const cell = getFocusedCell(overlay); diff --git a/packages/date-time-picker/test/validation.common.js b/packages/date-time-picker/test/validation.common.js index 5de7229c11..e3aee4cb42 100644 --- a/packages/date-time-picker/test/validation.common.js +++ b/packages/date-time-picker/test/validation.common.js @@ -101,9 +101,7 @@ const fixtures = { await aTimeout(1); // Move focus to date-picker - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(validateSpy.called).to.be.false; }); diff --git a/packages/field-highlighter/test/field-components.test.js b/packages/field-highlighter/test/field-components.test.js index 1e7c2ada31..40d355bae1 100644 --- a/packages/field-highlighter/test/field-components.test.js +++ b/packages/field-highlighter/test/field-components.test.js @@ -453,18 +453,14 @@ describe('field components', () => { it('should dispatch vaadin-highlight-hide event on Shift Tab to date picker', async () => { time.focus(); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(hideSpy.callCount).to.equal(1); expect(hideSpy.firstCall.args[0].detail.fieldIndex).to.equal(1); }); it('should dispatch second vaadin-highlight-show event on Shift Tab to date picker', async () => { time.focus(); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(showSpy.callCount).to.equal(2); expect(showSpy.getCalls()[1].args[0].detail.fieldIndex).to.equal(0); }); diff --git a/packages/grid-pro/test/edit-column.common.js b/packages/grid-pro/test/edit-column.common.js index 0dc00ea449..2edee8178c 100644 --- a/packages/grid-pro/test/edit-column.common.js +++ b/packages/grid-pro/test/edit-column.common.js @@ -63,16 +63,12 @@ describe('edit column', () => { await nextFrame(); // Press Shift + Tab to edit the select cell - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(getCellEditor(selectCell)).to.be.ok; await nextFrame(); // Press Shift + Tab to edit the text cell - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(getCellEditor(textCell)).to.be.ok; }); }); @@ -148,9 +144,7 @@ describe('edit column', () => { const firstCell = getContainerCell(grid.$.items, 1, 1); dblclick(firstCell._content); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(grid.$.table.scrollLeft).to.closeTo(1, 1); }); @@ -458,22 +452,16 @@ describe('edit column', () => { await sendKeys({ press: 'Enter' }); expect(getCellEditor(cell)).to.be.ok; - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); cell = getContainerCell(grid.$.items, 3, 1); expect(getCellEditor(cell)).to.be.ok; // Should skip non-editable rows - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); cell = getContainerCell(grid.$.items, 1, 3); expect(getCellEditor(cell)).to.be.ok; - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); cell = getContainerCell(grid.$.items, 1, 2); expect(getCellEditor(cell)).to.be.ok; }); @@ -514,9 +502,7 @@ describe('edit column', () => { expect(getCellEditor(cell)).to.be.ok; expect(grid.querySelector('vaadin-grid-pro-edit-text-field')).to.be.ok; - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(grid.querySelector('vaadin-grid-pro-edit-text-field')).to.not.be.ok; const target = cell._focusButton || cell; expect(grid.shadowRoot.activeElement).to.equal(target); @@ -546,9 +532,7 @@ describe('edit column', () => { await sendKeys({ press: 'Enter' }); expect(getCellEditor(cell)).to.be.ok; - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Enter' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Enter' }); cell = getContainerCell(grid.$.items, 1, 1); expect(getCellEditor(cell)).to.be.ok; }); @@ -574,9 +558,7 @@ describe('edit column', () => { expect(getCellEditor(cell)).to.be.ok; expect(grid.querySelector('vaadin-grid-pro-edit-text-field')).to.be.ok; - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Enter' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Enter' }); expect(grid.querySelector('vaadin-grid-pro-edit-text-field')).to.not.be.ok; const target = cell._focusButton || cell; expect(grid.shadowRoot.activeElement).to.equal(target); diff --git a/packages/grid-pro/test/keyboard-navigation.common.js b/packages/grid-pro/test/keyboard-navigation.common.js index c7ae7cc578..825e0610ba 100644 --- a/packages/grid-pro/test/keyboard-navigation.common.js +++ b/packages/grid-pro/test/keyboard-navigation.common.js @@ -56,9 +56,7 @@ describe('keyboard navigation', () => { const secondCell = getContainerCell(grid.$.items, 1, 0); const spy = sinon.spy(secondCell, 'focus'); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(spy.calledOnce).to.be.true; }); @@ -80,9 +78,7 @@ describe('keyboard navigation', () => { const secondCell = getContainerCell(grid.$.items, 1, 1); const spy = sinon.spy(secondCell, 'focus'); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(spy.calledOnce).to.be.true; }); @@ -115,9 +111,7 @@ describe('keyboard navigation', () => { const secondCell = getContainerCell(grid.$.items, 0, 0); const spy = sinon.spy(secondCell, 'focus'); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Enter' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Enter' }); expect(spy.calledOnce).to.be.true; }); @@ -126,9 +120,7 @@ describe('keyboard navigation', () => { firstCell.focus(); await sendKeys({ press: 'Enter' }); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Enter' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Enter' }); expect(getCellEditor(firstCell)).to.be.not.ok; }); @@ -190,9 +182,7 @@ describe('keyboard navigation', () => { dblclick(firstCell._content); const secondCell = getContainerCell(grid.$.items, 1, 0); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(getCellEditor(secondCell)).to.be.ok; }); @@ -210,9 +200,7 @@ describe('keyboard navigation', () => { dblclick(firstCell._content); const secondCell = getContainerCell(grid.$.items, 1, 1); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(getCellEditor(secondCell)).to.be.ok; }); @@ -242,9 +230,7 @@ describe('keyboard navigation', () => { await sendKeys({ press: 'Enter' }); const secondCell = getContainerCell(grid.$.items, 0, 0); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Enter' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Enter' }); expect(getCellEditor(secondCell)).to.be.ok; }); @@ -263,9 +249,7 @@ describe('keyboard navigation', () => { const firstCell = getContainerCell(grid.$.items, 1, 0); dblclick(firstCell._content); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Enter' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Enter' }); expect(getCellEditor(firstCell)).to.be.not.ok; }); }); diff --git a/packages/grid/test/disabled.common.js b/packages/grid/test/disabled.common.js index aa03d18274..0739c11523 100644 --- a/packages/grid/test/disabled.common.js +++ b/packages/grid/test/disabled.common.js @@ -82,9 +82,7 @@ describe('disabled', () => { it('should skip disabled grid when navigating on Shift Tab', async () => { inputAfter.focus(); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(document.activeElement).to.equal(inputBefore); }); diff --git a/packages/grid/test/keyboard-interaction-mode.common.js b/packages/grid/test/keyboard-interaction-mode.common.js index 2589f8753d..41f4f4de6a 100644 --- a/packages/grid/test/keyboard-interaction-mode.common.js +++ b/packages/grid/test/keyboard-interaction-mode.common.js @@ -278,9 +278,7 @@ describe('keyboard interaction mode', () => { const previousInput = getCellInput(0, 1); // Shift+Tab to previous input - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(document.activeElement).to.equal(previousInput); }); @@ -550,9 +548,7 @@ describe('keyboard interaction mode', () => { // Tab upwards for (let i = tabToIndex - 1; i >= 0; i--) { await rendered(); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); await rendered(); const focusedRow = document.activeElement.parentElement.assignedSlot.parentElement.parentElement; expect(focusedRow.index).to.equal(i); diff --git a/packages/menu-bar/test/menu-bar.common.js b/packages/menu-bar/test/menu-bar.common.js index d59f5a2d07..87c20e1838 100644 --- a/packages/menu-bar/test/menu-bar.common.js +++ b/packages/menu-bar/test/menu-bar.common.js @@ -243,9 +243,7 @@ describe('root menu layout', () => { it('should move focus to prev button on Shift Tab keydown', async () => { buttons[1].focus(); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(buttons[0].hasAttribute('focused')).to.be.true; }); diff --git a/packages/menu-bar/test/sub-menu.common.js b/packages/menu-bar/test/sub-menu.common.js index 950f11b163..7e5dddad97 100644 --- a/packages/menu-bar/test/sub-menu.common.js +++ b/packages/menu-bar/test/sub-menu.common.js @@ -310,9 +310,7 @@ describe('sub-menu', () => { arrowDown(buttons[3]); await oneEvent(subMenu, 'opened-changed'); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); await nextRender(subMenu); expect(subMenu.opened).to.be.true; diff --git a/packages/password-field/test/password-field.common.js b/packages/password-field/test/password-field.common.js index 9c5c983e49..4e6f2801b0 100644 --- a/packages/password-field/test/password-field.common.js +++ b/packages/password-field/test/password-field.common.js @@ -153,9 +153,7 @@ describe('password-field', () => { }); it('should not set focus-ring attribute when focusing reveal button with Shift Tab', async () => { - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(passwordField.hasAttribute('focus-ring')).to.be.false; }); @@ -165,9 +163,7 @@ describe('password-field', () => { revealButton.focus(); // Shift+Tab to the input element - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(passwordField.hasAttribute('focus-ring')).to.be.true; }); @@ -238,9 +234,7 @@ describe('disabled', () => { let focusInput; async function shiftTab() { - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); } beforeEach(() => { diff --git a/packages/popover/test/a11y.test.js b/packages/popover/test/a11y.test.js index 24acd10718..b49b4facf3 100644 --- a/packages/popover/test/a11y.test.js +++ b/packages/popover/test/a11y.test.js @@ -371,9 +371,7 @@ describe('a11y', () => { const spy = sinon.spy(target, 'focus'); // Move focus back to the target - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(spy).to.be.calledOnce; }); @@ -401,9 +399,7 @@ describe('a11y', () => { const focusable = overlay.querySelector('input'); const spy = sinon.spy(focusable, 'focus'); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(spy).to.be.calledOnce; }); @@ -429,9 +425,7 @@ describe('a11y', () => { await nextRender(); // Move focus back from the target - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); await nextRender(); const activeElement = getDeepActiveElement(); diff --git a/packages/radio-group/test/radio-group.common.js b/packages/radio-group/test/radio-group.common.js index 5e0cceed67..a80b0749af 100644 --- a/packages/radio-group/test/radio-group.common.js +++ b/packages/radio-group/test/radio-group.common.js @@ -248,9 +248,7 @@ describe('radio-group', () => { await sendKeys({ press: 'Tab' }); // Move focus out of the group. - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(buttons[0].hasAttribute('focused')).to.be.false; expect(group.hasAttribute('focused')).to.be.false; diff --git a/packages/radio-group/test/validation.common.js b/packages/radio-group/test/validation.common.js index 3b823cabfb..f669c532e2 100644 --- a/packages/radio-group/test/validation.common.js +++ b/packages/radio-group/test/validation.common.js @@ -83,9 +83,7 @@ describe('validation', () => { expect(validateSpy.called).to.be.false; // Move focus out of the group. - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(validateSpy.calledOnce).to.be.true; }); @@ -124,9 +122,7 @@ describe('validation', () => { await sendKeys({ press: 'Tab' }); // Move focus out of the checkbox group. - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(validateSpy.called).to.be.false; }); diff --git a/packages/rich-text-editor/test/a11y.common.js b/packages/rich-text-editor/test/a11y.common.js index 43ff2a6011..d488861c60 100644 --- a/packages/rich-text-editor/test/a11y.common.js +++ b/packages/rich-text-editor/test/a11y.common.js @@ -247,9 +247,7 @@ describe('accessibility', () => { it('should move focus to the first toolbar button after esc followed by shift-tab are pressed', async () => { await sendKeys({ press: 'Escape' }); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(getDeepActiveElement()).to.equal(buttons[0]); }); diff --git a/packages/upload/test/file.common.js b/packages/upload/test/file.common.js index f6b5e71b57..5ea404bcc5 100644 --- a/packages/upload/test/file.common.js +++ b/packages/upload/test/file.common.js @@ -133,9 +133,7 @@ describe(' element', () => { button.focus(); // Move focus back to the upload file. - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(fileElement.hasAttribute('focus-ring')).to.be.true; }); @@ -146,9 +144,7 @@ describe(' element', () => { await sendKeys({ press: 'Tab' }); // Move focus back to the button. - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(fileElement.hasAttribute('focus-ring')).to.be.false; }); diff --git a/test/integration/dialog-accordion.test.js b/test/integration/dialog-accordion.test.js index 53797fe945..9b6feaa3d6 100644 --- a/test/integration/dialog-accordion.test.js +++ b/test/integration/dialog-accordion.test.js @@ -49,9 +49,7 @@ describe('accordion in dialog', () => { panels[0].querySelector('input').focus(); // Move focus back to heading - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(document.activeElement).to.equal(panels[0].focusElement); }); @@ -75,9 +73,7 @@ describe('accordion in dialog', () => { panels[1].focus(); // Move focus back to first panel - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(document.activeElement).to.equal(panels[0].focusElement); }); diff --git a/test/integration/dialog-date-picker.test.js b/test/integration/dialog-date-picker.test.js index ab0fe522d9..b34e7941a1 100644 --- a/test/integration/dialog-date-picker.test.js +++ b/test/integration/dialog-date-picker.test.js @@ -51,9 +51,7 @@ describe('date-picker in dialog', () => { it('should focus the Cancel button on Shift + Tab when inside a dialog', async () => { // Focus the Cancel button - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(overlayContent._cancelButton.hasAttribute('focused')).to.be.true; }); @@ -67,9 +65,7 @@ describe('date-picker in dialog', () => { const spy = sinon.spy(datePicker.inputElement, 'focus'); - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); expect(spy.calledOnce).to.be.true; }); @@ -114,9 +110,7 @@ describe('date-picker in dialog', () => { it('should not close the dialog when closing date-picker on Cancel button Escape', async () => { // Focus the Cancel button - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); await sendKeys({ press: 'Escape' }); diff --git a/test/integration/grid-pro-custom-editor.test.js b/test/integration/grid-pro-custom-editor.test.js index 1df0f528ea..981c5ef1ac 100644 --- a/test/integration/grid-pro-custom-editor.test.js +++ b/test/integration/grid-pro-custom-editor.test.js @@ -149,9 +149,7 @@ describe('grid-pro custom editor', () => { await waitForOverlayRender(); // Move focus back to the input - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); // Change single digit to avoid calendar scroll const input = cell._content.querySelector('input'); @@ -248,9 +246,7 @@ describe('grid-pro custom editor', () => { expect(cell._content.querySelector('vaadin-date-time-picker')).to.be.ok; // Move focus to the date-picker - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); await nextRender(); expect(cell._content.querySelector('vaadin-date-time-picker')).to.be.ok; }); @@ -260,9 +256,7 @@ describe('grid-pro custom editor', () => { await waitForOverlayRender(); // Move focus back to the input - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); // Change single digit to avoid calendar scroll const input = cell._content.querySelector('input'); @@ -318,9 +312,7 @@ describe('grid-pro custom editor', () => { expect(cell._content.querySelector('vaadin-custom-field')).to.be.ok; // Move focus to the first field - await sendKeys({ down: 'Shift' }); - await sendKeys({ press: 'Tab' }); - await sendKeys({ up: 'Shift' }); + await sendKeys({ press: 'Shift+Tab' }); await nextRender(); expect(cell._content.querySelector('vaadin-custom-field')).to.be.ok; }); diff --git a/test/test-runner-commands/index.js b/test/test-runner-commands/index.js index e2837d1a47..41abcd8f7c 100644 --- a/test/test-runner-commands/index.js +++ b/test/test-runner-commands/index.js @@ -1 +1,53 @@ +import { executeServerCommand } from '@web/test-runner-commands'; + export * from '@web/test-runner-commands'; + +/** + * Extends the `sendKeys` command to support pressing multiple keys + * simultaneously when provided in the format "Shift+Tab". This format + * is natively supported by Playwright but not by Puppeteer. This wrapper + * enables the same syntax to be used in Puppeteer. + * + * In WebDriver, this functionality is still unavailable because + * web-test-runner does not provide an API for holding keys down. + * + * For more documentation on the original command, please see + * https://modern-web.dev/docs/test-runner/commands/#send-keys + * + * @typedef {{ type: string }} TypePayload + * @typedef {{ press: string }} PressPayload + * @typedef {{ down: string }} DownPayload + * @typedef {{ up: string }} UpPayload + * @param payload {TypePayload | PressPayload | DownPayload | UpPayload} + * + * @example + * // Tab to the next element + * await sendKeys({ press: 'Tab' }); + * + * @example + * // Tab to the previous element + * await sendKeys({ press: 'Shift+Tab' }); + * + * @example + * await sendKeys({ down: 'Shift' }); + * // Do something while holding Shift + * await sendKeys({ up: 'Shift' }); + */ +export async function sendKeys(payload) { + const { press } = payload; + if (press && press.includes('+')) { + const keys = press.split('+').map((key) => key.trim()); + + for (const key of keys) { + await executeServerCommand('send-keys', { down: key }); + } + + for (const key of keys.reverse()) { + await executeServerCommand('send-keys', { up: key }); + } + + return; + } + + await executeServerCommand('send-keys', payload); +}