diff --git a/packages/vaadin-avatar/test/avatar.test.js b/packages/vaadin-avatar/test/avatar.test.js index 80560c726e..5861a6c327 100644 --- a/packages/vaadin-avatar/test/avatar.test.js +++ b/packages/vaadin-avatar/test/avatar.test.js @@ -1,6 +1,6 @@ import { expect } from '@esm-bundle/chai'; import sinon from 'sinon'; -import { fixtureSync, mousedown, oneEvent, tabKeyDown } from '@vaadin/testing-helpers'; +import { fixtureSync, focusin, focusout, mousedown, oneEvent, tabKeyDown } from '@vaadin/testing-helpers'; import '../vaadin-avatar.js'; @@ -249,15 +249,6 @@ describe('vaadin-avatar', () => { }); describe('focus', () => { - function focusin(node) { - node.dispatchEvent(new CustomEvent('focusin', { bubbles: true, composed: true })); - } - - function focusout(node) { - const event = new CustomEvent('focusout', { bubbles: true, composed: true }); - node.dispatchEvent(event); - } - it('should set tabindex="0" on the avatar', () => { expect(avatar.getAttribute('tabindex')).to.equal('0'); }); diff --git a/packages/vaadin-control-state-mixin/test/control-state-mixin.test.js b/packages/vaadin-control-state-mixin/test/control-state-mixin.test.js index 60cd7e917e..57f79d2895 100644 --- a/packages/vaadin-control-state-mixin/test/control-state-mixin.test.js +++ b/packages/vaadin-control-state-mixin/test/control-state-mixin.test.js @@ -1,6 +1,14 @@ import { expect } from '@esm-bundle/chai'; import sinon from 'sinon'; -import { aTimeout, fixtureSync, keyboardEventFor, keyDownOn, nextFrame } from '@vaadin/testing-helpers'; +import { + aTimeout, + fixtureSync, + focusin, + focusout, + keyboardEventFor, + keyDownOn, + nextFrame +} from '@vaadin/testing-helpers'; import { PolymerElement, html } from '@polymer/polymer/polymer-element.js'; import { ControlStateMixin } from '../vaadin-control-state-mixin.js'; @@ -95,14 +103,6 @@ describe('control-state-mixin', () => { }); describe('focus-ring', () => { - const focusin = () => { - focusElement.dispatchEvent(new CustomEvent('focusin', { composed: true, bubbles: true })); - }; - - const focusout = () => { - focusElement.dispatchEvent(new CustomEvent('focusout', { composed: true, bubbles: true })); - }; - it('should set _isShiftTabbing when pressing shift-tab', () => { const event = keyboardEventFor('keydown', 9, 'shift'); customElement.dispatchEvent(event); @@ -118,35 +118,35 @@ describe('control-state-mixin', () => { it('should set the focus-ring attribute when TAB is pressed and focus is received', () => { keyDownOn(document.body, 9); - focusin(); + focusin(focusElement); expect(customElement.hasAttribute('focus-ring')).to.be.true; - focusout(); + focusout(focusElement); expect(customElement.hasAttribute('focus-ring')).to.be.false; }); it('should set the focus-ring attribute when SHIFT+TAB is pressed and focus is received', () => { keyDownOn(document.body, 9, 'shift'); - focusin(); + focusin(focusElement); expect(customElement.hasAttribute('focus-ring')).to.be.true; - focusout(); + focusout(focusElement); expect(customElement.hasAttribute('focus-ring')).to.be.false; }); it('should not set the focus-ring attribute when mousedown happens after keydown', () => { keyDownOn(document.body, 9); document.body.dispatchEvent(new MouseEvent('mousedown')); - focusin(); + focusin(focusElement); expect(customElement.hasAttribute('focus-ring')).to.be.false; }); it('should refocus the field', async () => { - customElement.dispatchEvent(new CustomEvent('focusin')); + focusin(customElement); keyDownOn(customElement, 9, 'shift'); // Shift + Tab disables refocusing temporarily, normal behaviour is restored asynchronously. await aTimeout(0); - var spy = sinon.spy(focusElement, 'focus'); - customElement.dispatchEvent(new CustomEvent('focusin')); + const spy = sinon.spy(focusElement, 'focus'); + focusin(customElement); expect(spy.called).to.be.true; }); }); @@ -218,7 +218,7 @@ describe('control-state-mixin', () => { }); it('should set focused attribute on focusin event', () => { - focusElement.dispatchEvent(new CustomEvent('focusin', { composed: true, bubbles: true })); + focusin(focusElement); expect(customElement.hasAttribute('focused')).to.be.true; }); @@ -226,25 +226,20 @@ describe('control-state-mixin', () => { const child = document.createElement('div'); customElement.appendChild(child); - const event = new CustomEvent('focusin', { - composed: true, - bubbles: true - }); - event.relatedTarget = child; - customElement.dispatchEvent(event); + focusin(customElement, child); expect(customElement.hasAttribute('focused')).to.be.false; }); it('should not set focused attribute on focusin event when disabled', () => { customElement.disabled = true; - focusElement.dispatchEvent(new CustomEvent('focusin', { composed: true, bubbles: true })); + focusin(focusElement); expect(customElement.hasAttribute('focused')).to.be.false; }); it('should not set focused attribute on focusin event from other focusable element', () => { const secondFocusable = focusElement.nextElementSibling; - secondFocusable.dispatchEvent(new CustomEvent('focusin', { composed: true, bubbles: true })); + focusin(secondFocusable); expect(customElement.hasAttribute('focused')).to.be.false; }); @@ -259,7 +254,7 @@ describe('control-state-mixin', () => { }); it('should remove focused attribute when disconnected from the DOM', () => { - focusElement.dispatchEvent(new CustomEvent('focusin', { composed: true, bubbles: true })); + focusin(focusElement); customElement.parentNode.removeChild(customElement); expect(customElement.hasAttribute('focused')).to.be.false; }); @@ -310,14 +305,14 @@ describe('control-state-mixin', () => { }); it('should set focused attribute on focusin event dispatched from an element inside focusElement', () => { - focusElement.dispatchEvent(new CustomEvent('focusin', { composed: true, bubbles: true })); + focusin(focusElement); expect(wrapper.hasAttribute('focused')).to.be.true; }); it('should remove focused attribute on focusout event dispatched from an element inside focusElement', () => { - focusElement.dispatchEvent(new CustomEvent('focusin', { composed: true, bubbles: true })); + focusin(focusElement); expect(wrapper.hasAttribute('focused')).to.be.true; - focusElement.dispatchEvent(new CustomEvent('focusout', { composed: true, bubbles: true })); + focusout(focusElement); expect(wrapper.hasAttribute('focused')).to.be.false; }); }); diff --git a/packages/vaadin-custom-field/test/basic.test.js b/packages/vaadin-custom-field/test/basic.test.js index 53ca04b357..1793106521 100644 --- a/packages/vaadin-custom-field/test/basic.test.js +++ b/packages/vaadin-custom-field/test/basic.test.js @@ -1,6 +1,6 @@ import { expect } from '@esm-bundle/chai'; import sinon from 'sinon'; -import { fixtureSync } from '@vaadin/testing-helpers'; +import { fixtureSync, focusin, focusout } from '@vaadin/testing-helpers'; import { dispatchChange } from './common.js'; import '../vaadin-custom-field.js'; @@ -91,13 +91,13 @@ describe('custom field', () => { describe('focused', () => { it('should set focused attribute on input focusin', () => { - customField.inputs[0].dispatchEvent(new CustomEvent('focusin', { composed: true, bubbles: true })); + focusin(customField.inputs[0]); expect(customField.hasAttribute('focused')).to.be.true; }); it('should remove focused attribute on input focusout', () => { - customField.inputs[0].dispatchEvent(new CustomEvent('focusin', { composed: true, bubbles: true })); - customField.inputs[0].dispatchEvent(new CustomEvent('focusout', { composed: true, bubbles: true })); + focusin(customField.inputs[0]); + focusout(customField.inputs[0]); expect(customField.hasAttribute('focused')).to.be.false; }); }); diff --git a/packages/vaadin-grid-pro/test/edit-column-overlay.test.js b/packages/vaadin-grid-pro/test/edit-column-overlay.test.js index 58ca78715c..8de0025e20 100644 --- a/packages/vaadin-grid-pro/test/edit-column-overlay.test.js +++ b/packages/vaadin-grid-pro/test/edit-column-overlay.test.js @@ -1,5 +1,5 @@ import { expect } from '@esm-bundle/chai'; -import { fixtureSync, enter, nextFrame } from '@vaadin/testing-helpers'; +import { fixtureSync, focusin, focusout, enter, nextFrame } from '@vaadin/testing-helpers'; import '@vaadin/vaadin-date-picker/vaadin-date-picker.js'; import '@vaadin/vaadin-dialog/vaadin-dialog.js'; import '@vaadin/vaadin-template-renderer'; @@ -8,14 +8,12 @@ import '../vaadin-grid-pro.js'; import '../vaadin-grid-pro-edit-column.js'; async function clickOverlay(element) { - const focusout = new CustomEvent('focusout', { bubbles: true, composed: true }); - element.dispatchEvent(focusout); + focusout(element); // add a microTask in between await Promise.resolve(); - const focusin = new CustomEvent('focusin', { bubbles: true, composed: true }); - element.$.overlay.dispatchEvent(focusin); + focusin(element.$.overlay); } const fixtures = { @@ -102,11 +100,8 @@ const fixtures = { const datePicker = getCellEditor(dateCell).querySelector('vaadin-date-picker'); // Mimic clicking the dialog overlay - const evt = new CustomEvent('focusout', { bubbles: true, composed: true }); - datePicker.dispatchEvent(evt); - - const focusin = new CustomEvent('focusin', { bubbles: true, composed: true }); - dialog.$.overlay.dispatchEvent(focusin); + focusout(datePicker); + focusin(dialog.$.overlay); grid._debouncerStopEdit && grid._debouncerStopEdit.flush(); expect(getCellEditor(dateCell)).to.be.not.ok; diff --git a/packages/vaadin-grid-pro/test/edit-column-renderer.test.js b/packages/vaadin-grid-pro/test/edit-column-renderer.test.js index b2978589db..b9ec713a56 100644 --- a/packages/vaadin-grid-pro/test/edit-column-renderer.test.js +++ b/packages/vaadin-grid-pro/test/edit-column-renderer.test.js @@ -1,6 +1,6 @@ import { expect } from '@esm-bundle/chai'; import sinon from 'sinon'; -import { enter, esc, fixtureSync, space } from '@vaadin/testing-helpers'; +import { enter, esc, fixtureSync, focusout, space } from '@vaadin/testing-helpers'; import { PolymerElement, html } from '@polymer/polymer/polymer-element.js'; import '@vaadin/vaadin-template-renderer'; import { @@ -206,7 +206,7 @@ describe('edit column renderer', () => { dblclick(cell._content); editor = getCellEditor(cell); editor.value = 'Foo'; - editor.dispatchEvent(new CustomEvent('focusout', { bubbles: true, composed: true })); + focusout(editor); grid._flushStopEdit(); expect(getCellEditor(cell)).to.not.be.ok; expect(cell._content.textContent).to.equal('Foo'); diff --git a/packages/vaadin-grid-pro/test/edit-column-type.test.js b/packages/vaadin-grid-pro/test/edit-column-type.test.js index 90a6e08f49..5e32004e87 100644 --- a/packages/vaadin-grid-pro/test/edit-column-type.test.js +++ b/packages/vaadin-grid-pro/test/edit-column-type.test.js @@ -1,6 +1,16 @@ import { expect } from '@esm-bundle/chai'; import sinon from 'sinon'; -import { arrowDown, arrowUp, enter, fixtureSync, keyDownChar, nextRender, space } from '@vaadin/testing-helpers'; +import { + arrowDown, + arrowUp, + enter, + fixtureSync, + focusin, + focusout, + keyDownChar, + nextRender, + space +} from '@vaadin/testing-helpers'; import { TextFieldElement } from '@vaadin/vaadin-text-field/src/vaadin-text-field.js'; import { SelectElement } from '@vaadin/vaadin-select/src/vaadin-select.js'; import { CheckboxElement } from '@vaadin/vaadin-checkbox/src/vaadin-checkbox.js'; @@ -141,10 +151,8 @@ describe('edit column editor type', () => { it('should open the select and stop focusout on editor click', async () => { editor.opened = false; editor.focusElement.click(); - const focusout = new CustomEvent('focusout', { bubbles: true, composed: true }); - editor.dispatchEvent(focusout); - const focusin = new CustomEvent('focusin', { bubbles: true, composed: true }); - editor._overlayElement.querySelector('vaadin-item').dispatchEvent(focusin); + focusout(editor); + focusin(editor._overlayElement.querySelector('vaadin-item')); grid._flushStopEdit(); await nextRender(editor._menuElement); expect(editor.opened).to.equal(true); @@ -235,8 +243,7 @@ describe('edit column editor type', () => { }); it('should not throw when moving focus out of the select', () => { - const evt = new CustomEvent('focusout', { bubbles: true, composed: true }); - editor.dispatchEvent(evt); + focusout(editor); grid._debouncerStopEdit && grid._debouncerStopEdit.flush(); expect(column._getEditorComponent(cell)).to.not.be.ok; }); diff --git a/packages/vaadin-grid-pro/test/edit-column.test.js b/packages/vaadin-grid-pro/test/edit-column.test.js index 0316a818b5..36fcd5eb93 100644 --- a/packages/vaadin-grid-pro/test/edit-column.test.js +++ b/packages/vaadin-grid-pro/test/edit-column.test.js @@ -1,6 +1,6 @@ import { expect } from '@esm-bundle/chai'; import sinon from 'sinon'; -import { enter, esc, fixtureSync, isIOS, tab } from '@vaadin/testing-helpers'; +import { enter, esc, fixtureSync, focusin, focusout, isIOS, tab } from '@vaadin/testing-helpers'; import '@vaadin/vaadin-template-renderer'; import { createItems, @@ -400,8 +400,8 @@ describe('edit column', () => { expect(inputWrapper).to.be.ok; - inputs[0].dispatchEvent(new CustomEvent('focusout', { bubbles: true, composed: true })); - inputs[1].dispatchEvent(new CustomEvent('focusin', { bubbles: true, composed: true })); + focusout(inputs[0]); + focusin(inputs[1]); grid._debouncerStopEdit && grid._debouncerStopEdit.flush(); expect(getCellEditor(customCell)).to.be.ok; @@ -607,10 +607,10 @@ describe('edit column', () => { expect(grid.hasAttribute('navigating')).to.be.true; cell.focus(); - cell.dispatchEvent(new CustomEvent('focusout', { bubbles: true, composed: true })); + focusout(cell); expect(grid.hasAttribute('navigating')).to.be.true; - cell.dispatchEvent(new CustomEvent('focusin', { bubbles: true, composed: true })); + focusin(cell); expect(grid.hasAttribute('navigating')).to.be.true; }); @@ -621,10 +621,10 @@ describe('edit column', () => { expect(grid.hasAttribute('navigating')).to.be.false; cell.focus(); - cell.dispatchEvent(new CustomEvent('focusout', { bubbles: true, composed: true })); + focusout(cell); expect(grid.hasAttribute('navigating')).to.be.false; - cell.dispatchEvent(new CustomEvent('focusin', { bubbles: true, composed: true })); + focusin(cell); expect(grid.hasAttribute('navigating')).to.be.false; }); }); diff --git a/packages/vaadin-grid/test/keyboard-navigation.test.js b/packages/vaadin-grid/test/keyboard-navigation.test.js index eff1ffa818..2601be97ab 100644 --- a/packages/vaadin-grid/test/keyboard-navigation.test.js +++ b/packages/vaadin-grid/test/keyboard-navigation.test.js @@ -4,6 +4,7 @@ import { aTimeout, down as mouseDown, fixtureSync, + focusin, keyDownOn, keyUpOn, keyboardEventFor, @@ -578,9 +579,7 @@ describe('keyboard navigation', () => { const tabbableElements = getTabbableElements(grid.shadowRoot); // focusin on table element — same as tab from above the grid - const event = new CustomEvent('focusin', { bubbles: true, composed: true }); - event.relatedTarget = focusable; - tabbableElements[0].dispatchEvent(event); + focusin(tabbableElements[0], focusable); // Expect programmatic focus on header cell expect(grid.shadowRoot.activeElement).to.equal(tabbableElements[1]); @@ -590,9 +589,7 @@ describe('keyboard navigation', () => { const tabbableElements = getTabbableElements(grid.shadowRoot); // focusin on focusexit element — same as shift+tab from below the grid - const event = new CustomEvent('focusin', { bubbles: true, composed: true }); - event.relatedTarget = focusable; - tabbableElements[4].dispatchEvent(event); + focusin(tabbableElements[4], focusable); // Expect programmatic focus on footer cell expect(grid.shadowRoot.activeElement).to.equal(tabbableElements[3]); diff --git a/packages/vaadin-menu-bar/test/menu-bar.test.js b/packages/vaadin-menu-bar/test/menu-bar.test.js index 9ae5a67ff6..8b77982f7f 100644 --- a/packages/vaadin-menu-bar/test/menu-bar.test.js +++ b/packages/vaadin-menu-bar/test/menu-bar.test.js @@ -1,6 +1,6 @@ import { expect } from '@esm-bundle/chai'; import sinon from 'sinon'; -import { arrowLeft, arrowRight, end, fixtureSync, home, nextRender } from '@vaadin/testing-helpers'; +import { arrowLeft, arrowRight, end, fixtureSync, focusin, home, nextRender } from '@vaadin/testing-helpers'; import './not-animated-styles.js'; import '../vaadin-menu-bar.js'; @@ -66,7 +66,7 @@ describe('root menu layout', () => { }); it('should set tabindex to -1 to all the buttons except first one', () => { - menu.dispatchEvent(new CustomEvent('focusin', { bubbles: true, composed: true })); + focusin(menu); expect(buttons[0].getAttribute('tabindex')).to.equal('0'); buttons.slice(1).forEach((btn) => { expect(btn.focusElement.getAttribute('tabindex')).to.equal('-1'); diff --git a/packages/vaadin-rich-text-editor/test/a11y.test.js b/packages/vaadin-rich-text-editor/test/a11y.test.js index 2b077b0e3b..5d3cc6f75d 100644 --- a/packages/vaadin-rich-text-editor/test/a11y.test.js +++ b/packages/vaadin-rich-text-editor/test/a11y.test.js @@ -1,6 +1,6 @@ import { expect } from '@esm-bundle/chai'; import sinon from 'sinon'; -import { down, fixtureSync, isFirefox, keyboardEventFor } from '@vaadin/testing-helpers'; +import { down, fixtureSync, focusin, isFirefox, keyboardEventFor } from '@vaadin/testing-helpers'; import '../vaadin-rich-text-editor.js'; describe('accessibility', () => { @@ -179,8 +179,7 @@ describe('accessibility', () => { expect(style.top).to.equal(document.documentElement.scrollTop + 'px'); done(); }); - const e = new CustomEvent('focusin', { bubbles: true }); - content.dispatchEvent(e); + focusin(content); }); (isFirefox ? it : it.skip)('should focus the fake target on mousedown when content is not focused', (done) => { diff --git a/packages/vaadin-rich-text-editor/test/basic.test.js b/packages/vaadin-rich-text-editor/test/basic.test.js index a6331f7dfc..4aee7ad33f 100644 --- a/packages/vaadin-rich-text-editor/test/basic.test.js +++ b/packages/vaadin-rich-text-editor/test/basic.test.js @@ -1,6 +1,6 @@ import { expect } from '@esm-bundle/chai'; import sinon from 'sinon'; -import { fixtureSync, isDesktopSafari, isFirefox, nextRender } from '@vaadin/testing-helpers'; +import { fixtureSync, focusout, isDesktopSafari, isFirefox, nextRender } from '@vaadin/testing-helpers'; import { createImage } from './helpers.js'; import '../vaadin-rich-text-editor.js'; @@ -51,7 +51,7 @@ describe('rich text editor', () => { (isFirefox || isSafari ? it.skip : it)(`should apply ${fmt} formatting to the selected text on click`, () => { btn = getButton(fmt); btn.dispatchEvent(new MouseEvent('mousedown', { bubbles: true })); - editor.root.dispatchEvent(new CustomEvent('focusout', { bubbles: true })); + focusout(editor.root); document.body.focus(); btn.dispatchEvent(new MouseEvent('mouseup', { bubbles: true })); btn.click(); @@ -469,7 +469,7 @@ describe('rich text editor', () => { // Setting selection range to null in Quill // Needed for proper hasFocus() check content.blur(); - content.dispatchEvent(new CustomEvent('focusout')); + focusout(content); expect(spy.calledOnce).to.be.true; }); @@ -481,7 +481,7 @@ describe('rich text editor', () => { rte.value = JSON.stringify([{ insert: 'Foo\n' }]); editor.focus(); content.blur(); - content.dispatchEvent(new CustomEvent('focusout')); + focusout(content); expect(spy.called).to.be.false; }); @@ -500,10 +500,8 @@ describe('rich text editor', () => { const btn = getButton('bold'); btn.dispatchEvent(new MouseEvent('mousedown', { bubbles: true })); - const evt = new CustomEvent('focusout'); - evt.relatedTarget = btn; content.blur(); - content.dispatchEvent(evt); + focusout(content, btn); btn.click(); flushValueDebouncer(); @@ -562,7 +560,7 @@ describe('rich text editor', () => { btn.click(); content.blur(); - content.dispatchEvent(new CustomEvent('focusout')); + focusout(content); expect(spy.called).to.be.false; }); diff --git a/packages/vaadin-time-picker/test/form-input.test.js b/packages/vaadin-time-picker/test/form-input.test.js index 303edc2a68..a66c02fb2a 100644 --- a/packages/vaadin-time-picker/test/form-input.test.js +++ b/packages/vaadin-time-picker/test/form-input.test.js @@ -1,5 +1,5 @@ import { expect } from '@esm-bundle/chai'; -import { fixtureSync } from '@vaadin/testing-helpers'; +import { fixtureSync, focusout } from '@vaadin/testing-helpers'; import { TimePickerElement } from '../src/vaadin-time-picker.js'; class TimePicker20Element extends TimePickerElement { @@ -11,7 +11,7 @@ class TimePicker20Element extends TimePickerElement { customElements.define('vaadin-time-picker-20', TimePicker20Element); describe('form input', () => { - let timePicker, inputElement; + let timePicker, dropdown, inputElement; function inputValue(value) { const input = inputElement.inputElement; @@ -19,13 +19,10 @@ describe('form input', () => { input.dispatchEvent(new CustomEvent('input', { bubbles: true, composed: true })); } - function blurInput() { - timePicker.__dropdownElement.dispatchEvent(new CustomEvent('focusout', { bubbles: true, composed: true })); - } - describe('default validator', () => { beforeEach(() => { timePicker = fixtureSync(``); + dropdown = timePicker.__dropdownElement; inputElement = timePicker.__inputElement; }); @@ -160,20 +157,20 @@ describe('form input', () => { it('should validate keyboard input (invalid)', () => { inputValue('foo'); expect(timePicker.invalid).to.be.equal(false); - blurInput(); + focusout(dropdown); expect(timePicker.invalid).to.be.equal(true); }); it('should validate keyboard input (valid)', () => { inputValue('12:00'); - blurInput(); + focusout(dropdown); expect(timePicker.invalid).to.be.equal(false); }); it('should validate keyboard input (disallowed value)', () => { inputValue('99:00'); expect(timePicker.invalid).to.be.equal(false); - blurInput(); + focusout(dropdown); expect(timePicker.invalid).to.be.equal(true); }); });