From 0de0ff13e70023dfdf578b44d2fab0da4e32f753 Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Tue, 17 Dec 2024 11:25:11 +0400 Subject: [PATCH 1/5] chore: upgrade playwright to 1.48.2 --- package.json | 3 +++ yarn.lock | 61 ++++++++++++++++------------------------------------ 2 files changed, 22 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index 4449fe18fc..6b1ab3bfa1 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,9 @@ "stylelint-config-vaadin": "^1.0.0-alpha.2", "typescript": "^5.5.2" }, + "resolutions": { + "playwright": "^1.48.2" + }, "lint-staged": { "*.{js,ts}": [ "eslint --fix", diff --git a/yarn.lock b/yarn.lock index cb1fc3711c..1f51d1bec5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6235,6 +6235,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@2.3.2, fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + fsevents@^1.2.7: version "1.2.13" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" @@ -6243,11 +6248,6 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - function-bind@^1.1.1, function-bind@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" @@ -10457,17 +10457,19 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -playwright-core@1.24.2: - version "1.24.2" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.24.2.tgz#47bc5adf3dcfcc297a5a7a332449c9009987db26" - integrity sha512-zfAoDoPY/0sDLsgSgLZwWmSCevIg1ym7CppBwllguVBNiHeixZkc1AdMuYUPZC6AdEYc4CxWEyLMBTw2YcmRrA== +playwright-core@1.49.1: + version "1.49.1" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.49.1.tgz#32c62f046e950f586ff9e35ed490a424f2248015" + integrity sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg== -playwright@^1.22.2: - version "1.24.2" - resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.24.2.tgz#51e60f128b386023e5ee83deca23453aaf73ba6d" - integrity sha512-iMWDLgaFRT+7dXsNeYwgl8nhLHsUrzFyaRVC+ftr++P1dVs70mPrFKBZrGp1fOKigHV9d1syC03IpPbqLKlPsg== +playwright@^1.22.2, playwright@^1.48.2: + version "1.49.1" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.49.1.tgz#830266dbca3008022afa7b4783565db9944ded7c" + integrity sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA== dependencies: - playwright-core "1.24.2" + playwright-core "1.49.1" + optionalDependencies: + fsevents "2.3.2" plexer@^2.0.0: version "2.0.0" @@ -12018,7 +12020,7 @@ string-argv@~0.3.2: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== -"string-width-cjs@npm:string-width@^4.2.0": +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12036,15 +12038,6 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" @@ -12129,7 +12122,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -12143,13 +12136,6 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -13392,7 +13378,7 @@ wordwrapjs@^5.1.0: resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-5.1.0.tgz#4c4d20446dcc670b14fa115ef4f8fd9947af2b3a" integrity sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -13418,15 +13404,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From ce5770e9ecd19a79a2e758923bcb74d170b78c5c Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Tue, 17 Dec 2024 11:30:32 +0400 Subject: [PATCH 2/5] update CI config to install new playwright --- .github/workflows/unit-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index c0069372b6..72c1c60d36 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -43,7 +43,7 @@ jobs: run: yarn --frozen-lockfile --no-progress --non-interactive - name: Install Playwright - run: npx playwright install-deps firefox + run: npx playwright install firefox --with-deps - name: Test run: yarn test:firefox @@ -65,7 +65,7 @@ jobs: run: yarn --frozen-lockfile --no-progress --non-interactive - name: Install Playwright - run: npx playwright install-deps webkit + run: npx playwright install webkit --with-deps - name: Test run: yarn test:webkit From 2b17c2d610408f2df8d5400bdabf280fbc0c607d Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Wed, 18 Dec 2024 12:52:13 +0400 Subject: [PATCH 3/5] fix focusout issue --- web-test-runner-firefox.config.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/web-test-runner-firefox.config.js b/web-test-runner-firefox.config.js index 56571b70a6..70a2d968d3 100644 --- a/web-test-runner-firefox.config.js +++ b/web-test-runner-firefox.config.js @@ -4,7 +4,14 @@ const { createUnitTestsConfig } = require('./wtr-utils.js'); const devServerConfig = require('./web-dev-server.config.js'); const unitTestsConfig = createUnitTestsConfig({ - browsers: [playwrightLauncher({ product: 'firefox' })], + browsers: [ + playwrightLauncher({ + product: 'firefox', + launchOptions: { + firefoxUserPrefs: { 'dom.disable_tab_focus_to_root_element': false }, + }, + }), + ], }); module.exports = { From 12384a95da1aecc0aec3a07718cd1af07a96572e Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Wed, 18 Dec 2024 13:47:46 +0400 Subject: [PATCH 4/5] fix tab tests --- packages/combo-box/test/interactions.common.js | 2 ++ packages/combo-box/test/keyboard.common.js | 6 ++++-- packages/date-picker/test/dropdown.common.js | 2 ++ .../field-base/test/virtual-keyboard-controller.test.js | 2 ++ packages/multi-select-combo-box/test/readonly.common.js | 8 +++++--- .../test/radio-group-keyboard-navigation.common.js | 2 ++ packages/select/src/vaadin-select-base-mixin.js | 1 + packages/select/test/validation.common.js | 2 ++ 8 files changed, 20 insertions(+), 5 deletions(-) diff --git a/packages/combo-box/test/interactions.common.js b/packages/combo-box/test/interactions.common.js index b587b31136..8ef041e975 100644 --- a/packages/combo-box/test/interactions.common.js +++ b/packages/combo-box/test/interactions.common.js @@ -250,7 +250,9 @@ describe('interactions', () => { comboBox.open(); comboBox.close(); await aTimeout(0); + await sendKeys({ down: 'Shift' }); await sendKeys({ press: 'Tab' }); + await sendKeys({ up: 'Shift' }); expect(input.inputMode).to.equal(''); }); }); diff --git a/packages/combo-box/test/keyboard.common.js b/packages/combo-box/test/keyboard.common.js index a643089a6b..41e2d66608 100644 --- a/packages/combo-box/test/keyboard.common.js +++ b/packages/combo-box/test/keyboard.common.js @@ -126,10 +126,12 @@ describe('keyboard', () => { expect(getFocusedIndex()).to.equal(0); }); - it('should tab to the next focusable', async () => { + it('should tab to the prev focusable', async () => { + await sendKeys({ down: 'Shift' }); await sendKeys({ press: 'Tab' }); + await sendKeys({ up: 'Shift' }); - expect(document.activeElement).to.equal(document.body); + expect(document.activeElement).to.be.oneOf([document.body, document.documentElement]); }); describe('focusable items content', () => { diff --git a/packages/date-picker/test/dropdown.common.js b/packages/date-picker/test/dropdown.common.js index c7eeba4087..de9b8d51ed 100644 --- a/packages/date-picker/test/dropdown.common.js +++ b/packages/date-picker/test/dropdown.common.js @@ -309,7 +309,9 @@ describe('dropdown', () => { it('should re-enable virtual keyboard on blur', async () => { await open(datePicker); datePicker.close(); + await sendKeys({ down: 'Shift' }); await sendKeys({ press: 'Tab' }); + await sendKeys({ up: 'Shift' }); expect(input.inputMode).to.equal(''); }); }); diff --git a/packages/field-base/test/virtual-keyboard-controller.test.js b/packages/field-base/test/virtual-keyboard-controller.test.js index 66ff3711cc..9429fef5b3 100644 --- a/packages/field-base/test/virtual-keyboard-controller.test.js +++ b/packages/field-base/test/virtual-keyboard-controller.test.js @@ -59,7 +59,9 @@ describe('virtual-keyboard-controller', () => { element.close(); element.tabIndex = 1; element.focus(); + await sendKeys({ down: 'Shift' }); await sendKeys({ press: 'Tab' }); + await sendKeys({ up: 'Shift' }); expect(input.inputMode).to.equal(''); }); }); diff --git a/packages/multi-select-combo-box/test/readonly.common.js b/packages/multi-select-combo-box/test/readonly.common.js index 8917f4a3af..26a6f43b97 100644 --- a/packages/multi-select-combo-box/test/readonly.common.js +++ b/packages/multi-select-combo-box/test/readonly.common.js @@ -33,9 +33,11 @@ describe('readonly', () => { expect(internal.opened).to.be.true; }); - it('should close the dropdown on Tab when readonly', async () => { - await sendKeys({ down: 'ArrowDown' }); - await sendKeys({ down: 'Tab' }); + it('should close the dropdown on Shift+Tab when readonly', async () => { + await sendKeys({ press: 'ArrowDown' }); + await sendKeys({ down: 'Shift' }); + await sendKeys({ press: 'Tab' }); + await sendKeys({ up: 'Shift' }); expect(internal.opened).to.be.false; }); diff --git a/packages/radio-group/test/radio-group-keyboard-navigation.common.js b/packages/radio-group/test/radio-group-keyboard-navigation.common.js index a9eea4b10a..6df7b478c4 100644 --- a/packages/radio-group/test/radio-group-keyboard-navigation.common.js +++ b/packages/radio-group/test/radio-group-keyboard-navigation.common.js @@ -43,7 +43,9 @@ describe('keyboard navigation', () => { expect(buttons[2].hasAttribute('focused')).to.be.false; // Move focus out of the group. + await sendKeys({ down: 'Shift' }); await sendKeys({ press: 'Tab' }); + await sendKeys({ up: 'Shift' }); expect(buttons[0].hasAttribute('focused')).to.be.false; expect(buttons[1].hasAttribute('focused')).to.be.false; expect(buttons[2].hasAttribute('focused')).to.be.false; diff --git a/packages/select/src/vaadin-select-base-mixin.js b/packages/select/src/vaadin-select-base-mixin.js index cc160fe5f7..a28237f139 100644 --- a/packages/select/src/vaadin-select-base-mixin.js +++ b/packages/select/src/vaadin-select-base-mixin.js @@ -65,6 +65,7 @@ export const SelectBaseMixin = (superClass) => notify: true, reflectToAttribute: true, observer: '_openedChanged', + sync: true, }, /** diff --git a/packages/select/test/validation.common.js b/packages/select/test/validation.common.js index 8aaccc63ae..1674dc9c07 100644 --- a/packages/select/test/validation.common.js +++ b/packages/select/test/validation.common.js @@ -60,7 +60,9 @@ describe('validation', () => { select.click(); await nextRender(); + await sendKeys({ down: 'Shift' }); await sendKeys({ press: 'Tab' }); + await sendKeys({ up: 'Shift' }); await nextUpdate(select); expect(validateSpy.calledOnce).to.be.true; }); From 4577f458f7216a8229bdff411bccbd2b0d41895b Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Mon, 23 Dec 2024 14:05:15 +0400 Subject: [PATCH 5/5] test: replace onceResized with nextResize (#8387) --- packages/app-layout/test/app-layout.common.js | 34 ++------ .../app-layout/test/not-animated-styles.js | 10 +++ .../avatar-group/test/avatar-group.common.js | 43 +++-------- packages/board/test/helpers.js | 24 +----- packages/board/test/redraw.test.js | 12 +-- packages/charts/test/chart-element.test.js | 27 +------ .../test/overflow-controller.test.js | 46 ++++------- .../component-base/test/resize-mixin.test.js | 35 ++------- .../dashboard/test/dashboard-keyboard.test.ts | 5 +- .../dashboard/test/dashboard-layout.test.ts | 69 ++++++++--------- .../test/dashboard-widget-reordering.test.ts | 15 ++-- .../test/dashboard-widget-resizing.test.ts | 11 ++- packages/dashboard/test/dashboard.test.ts | 11 ++- packages/dashboard/test/helpers.ts | 17 ---- packages/dialog/test/header-footer.common.js | 8 +- .../form-layout/test/form-layout.common.js | 36 ++------- packages/grid/test/column-groups.common.js | 3 +- packages/grid/test/column-rendering.common.js | 12 +-- packages/grid/test/frozen-columns.common.js | 17 ++-- packages/grid/test/helpers.js | 16 ---- packages/grid/test/min-height.common.js | 4 +- packages/grid/test/resizing.common.js | 3 +- packages/grid/test/scrolling-mode.common.js | 16 +++- packages/icon/test/icon-font.common.js | 37 ++------- packages/menu-bar/test/overflow.common.js | 77 +++++++------------ .../test/chips.common.js | 8 +- packages/tabs/test/tabs.common.js | 27 +------ packages/text-area/test/text-area.common.js | 24 +----- 28 files changed, 194 insertions(+), 453 deletions(-) create mode 100644 packages/app-layout/test/not-animated-styles.js diff --git a/packages/app-layout/test/app-layout.common.js b/packages/app-layout/test/app-layout.common.js index a16689aed2..0e34278a43 100644 --- a/packages/app-layout/test/app-layout.common.js +++ b/packages/app-layout/test/app-layout.common.js @@ -6,29 +6,11 @@ import { makeSoloTouchEvent, nextFrame, nextRender, + nextResize, oneEvent, } from '@vaadin/testing-helpers'; import sinon from 'sinon'; - -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName) { - return new Promise((resolve) => { - sinon.replace(object, functionName, (...args) => { - sinon.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -/** - * Resolves once the ResizeObserver has processed a resize. - */ -async function onceResized(layout) { - await onceInvoked(layout, '_updateOffsetSize'); -} +import './not-animated-styles.js'; describe('vaadin-app-layout', () => { let layout; @@ -108,12 +90,12 @@ describe('vaadin-app-layout', () => { navbarContent.style.height = '100px'; navbarContent.setAttribute('slot', 'navbar'); layout.appendChild(navbarContent); - await onceResized(layout); + await nextResize(layout); const initialOffset = parseInt(getComputedStyle(layout).getPropertyValue('padding-top')); expect(initialOffset).to.be.greaterThan(0); // Increase navbar content size and measure increase navbarContent.style.height = '200px'; - await onceResized(layout); + await nextResize(layout); const updatedOffset = parseInt(getComputedStyle(layout).getPropertyValue('padding-top')); expect(updatedOffset).to.equal(initialOffset + 100); }); @@ -162,12 +144,12 @@ describe('vaadin-app-layout', () => { navbarContent.style.height = '100px'; navbarContent.setAttribute('slot', 'navbar touch-optimized'); layout.appendChild(navbarContent); - await onceResized(layout); + await nextResize(layout); const initialOffset = parseInt(getComputedStyle(layout).getPropertyValue('padding-bottom')); expect(initialOffset).to.be.greaterThan(0); // Increase navbar content size and measure increase navbarContent.style.height = '200px'; - await onceResized(layout); + await nextResize(layout); const updatedOffset = parseInt(getComputedStyle(layout).getPropertyValue('padding-bottom')); expect(updatedOffset).to.equal(initialOffset + 100); }); @@ -196,7 +178,7 @@ describe('vaadin-app-layout', () => { drawer = layout.shadowRoot.querySelector('[part=drawer]'); backdrop = layout.shadowRoot.querySelector('[part=backdrop]'); // Wait for the initial resize observer callback - await onceResized(layout); + await nextResize(layout); await nextFrame(); } @@ -289,7 +271,7 @@ describe('vaadin-app-layout', () => { it('should only update offset size once during the drawer transition', async () => { layout.primarySection = 'drawer'; - await onceResized(layout); + await nextResize(layout); await nextRender(); layout.style.setProperty('--vaadin-app-layout-transition', '100ms'); diff --git a/packages/app-layout/test/not-animated-styles.js b/packages/app-layout/test/not-animated-styles.js new file mode 100644 index 0000000000..5d98ef6ac0 --- /dev/null +++ b/packages/app-layout/test/not-animated-styles.js @@ -0,0 +1,10 @@ +import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; + +registerStyles( + 'vaadin-app-layout', + css` + :host { + transition: none !important; + } + `, +); diff --git a/packages/avatar-group/test/avatar-group.common.js b/packages/avatar-group/test/avatar-group.common.js index 5fca683d71..5a1f6817f2 100644 --- a/packages/avatar-group/test/avatar-group.common.js +++ b/packages/avatar-group/test/avatar-group.common.js @@ -5,32 +5,13 @@ import { fixtureSync, nextFrame, nextRender, + nextResize, oneEvent, spaceKeyDown, tabKeyDown, } from '@vaadin/testing-helpers'; import sinon from 'sinon'; -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName) { - return new Promise((resolve) => { - sinon.replace(object, functionName, (...args) => { - sinon.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -/** - * Resolves once the ResizeObserver in AvatarGroup has processed a resize. - */ -async function onceResized(group) { - await onceInvoked(group, '__setItemsInView'); -} - describe('avatar-group', () => { let group; @@ -190,7 +171,7 @@ describe('avatar-group', () => { it('should consider element width when maxItemsVisible is set', async () => { group.style.width = '100px'; - await onceResized(group); + await nextResize(group); const items = group.querySelectorAll('vaadin-avatar'); expect(items.length).to.equal(3); @@ -198,7 +179,7 @@ describe('avatar-group', () => { it('should set abbr property correctly if maxItemsVisible and width are set', async () => { group.style.width = '100px'; - await onceResized(group); + await nextResize(group); const overflow = group._overflow; expect(overflow.abbr).to.equal('+3'); @@ -218,7 +199,7 @@ describe('avatar-group', () => { it('should render avatars to fit width on resize', async () => { group.style.width = '110px'; - await onceResized(group); + await nextResize(group); const items = group.querySelectorAll('vaadin-avatar'); expect(items.length).to.equal(3); expect(overflow.abbr).to.equal('+3'); @@ -227,27 +208,27 @@ describe('avatar-group', () => { it('should always show at least two avatars', async () => { group.items = group.items.slice(0, 2); group.style.width = '50px'; - await onceResized(group); + await nextResize(group); const items = group.querySelectorAll('vaadin-avatar:not([hidden])'); expect(items.length).to.equal(2); }); it('should not show overlay with only one avatar', async () => { group.style.width = '170px'; - await onceResized(group); + await nextResize(group); expect(overflow.hasAttribute('hidden')).to.be.true; }); it('should re-render avatars on items change', async () => { group.style.width = '110px'; group.items = group.items.slice(0, 2); - await onceResized(group); + await nextResize(group); expect(overflow.hasAttribute('hidden')).to.be.true; }); it('should render avatars in the menu items', async () => { group.style.width = '110px'; - await onceResized(group); + await nextResize(group); overflow.click(); await oneEvent(overlay, 'vaadin-overlay-open'); @@ -258,13 +239,13 @@ describe('avatar-group', () => { it('should re-render overflowing avatars on resize', async () => { group.style.width = '110px'; - await onceResized(group); + await nextResize(group); overflow.click(); await oneEvent(overlay, 'vaadin-overlay-open'); group.style.width = '75px'; - await onceResized(group); + await nextResize(group); const items = overlay.querySelectorAll('vaadin-avatar-group-menu-item'); expect(items.length).to.equal(4); @@ -272,13 +253,13 @@ describe('avatar-group', () => { it('should close overlay on resize when all avatars fit', async () => { group.style.width = '110px'; - await onceResized(group); + await nextResize(group); overflow.click(); await oneEvent(overlay, 'vaadin-overlay-open'); group.style.width = ''; - await onceResized(group); + await nextResize(group); expect(overlay.opened).to.be.false; }); diff --git a/packages/board/test/helpers.js b/packages/board/test/helpers.js index c87111574c..8172229274 100644 --- a/packages/board/test/helpers.js +++ b/packages/board/test/helpers.js @@ -1,28 +1,8 @@ -import sinon from 'sinon'; - -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName) { - return new Promise((resolve) => { - const stub = sinon.stub(object, functionName).callsFake((...args) => { - stub.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -/** - * Resolves once the ResizeObserver in BoardRow has processed a resize. - */ -export async function onceResized(boardRow) { - await onceInvoked(boardRow, '_onResize'); -} +import { nextResize } from '@vaadin/testing-helpers'; /** * Resolves once the ResizeObserver in all the BoardRows has processed a resize. */ export function allResized(boardRows) { - return Promise.all(boardRows.map((boardRow) => onceResized(boardRow))); + return Promise.all(boardRows.map((boardRow) => nextResize(boardRow))); } diff --git a/packages/board/test/redraw.test.js b/packages/board/test/redraw.test.js index 1e93e8c06b..eceff24b25 100644 --- a/packages/board/test/redraw.test.js +++ b/packages/board/test/redraw.test.js @@ -1,7 +1,7 @@ import { expect } from '@vaadin/chai-plugins'; -import { aTimeout, fixtureSync } from '@vaadin/testing-helpers'; +import { aTimeout, fixtureSync, nextResize } from '@vaadin/testing-helpers'; import '../vaadin-board.js'; -import { allResized, onceResized } from './helpers.js'; +import { allResized } from './helpers.js'; describe('redraw', () => { describe('board', () => { @@ -19,7 +19,7 @@ describe('redraw', () => { `); row = board.firstElementChild; - await onceResized(row); + await nextResize(row); }); it('should trigger layout after board style is changed', () => { @@ -49,7 +49,7 @@ describe('redraw', () => {
top D
`); - await onceResized(row); + await nextResize(row); }); it('should trigger layout after board row style is changed', () => { @@ -85,7 +85,7 @@ describe('redraw', () => { `); row = board.querySelector('#nested'); - await onceResized(row); + await nextResize(row); }); it('should trigger layout for nested rows after board style is changed', () => { @@ -199,7 +199,7 @@ describe('redraw', () => { expect(first.className).to.equal(''); container.style.width = '1001px'; - await onceResized(first); + await nextResize(first); expect(first.className).to.equal('large'); }); diff --git a/packages/charts/test/chart-element.test.js b/packages/charts/test/chart-element.test.js index 44f228475b..197f7d2f93 100644 --- a/packages/charts/test/chart-element.test.js +++ b/packages/charts/test/chart-element.test.js @@ -1,29 +1,8 @@ import { expect } from '@vaadin/chai-plugins'; -import { aTimeout, fixtureSync, nextFrame, nextRender, oneEvent } from '@vaadin/testing-helpers'; +import { aTimeout, fixtureSync, nextFrame, nextRender, nextResize, oneEvent } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import '../vaadin-chart.js'; -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName) { - return new Promise((resolve) => { - sinon.replace(object, functionName, (...args) => { - sinon.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -/** - * Resolves once the ResizeObserver in AvatarGroup has processed a resize. - */ -async function onceResized(el) { - // Wait for the _onResize function to be invoked by the ResizeObserver - await onceInvoked(el, '_onResize'); -} - describe('vaadin-chart', () => { describe('custom element definition', () => { let chart, tagName; @@ -346,7 +325,7 @@ describe('vaadin-chart', () => { expect(charts[1].configuration.chartWidth).to.be.equal(500); layout.style.width = '500px'; - await onceResized(charts[0]); + await nextResize(charts[0]); expect(layout.getBoundingClientRect().width).to.be.equal(500); expect(charts[0].configuration.chartWidth).to.be.equal(250); @@ -359,7 +338,7 @@ describe('vaadin-chart', () => { expect(charts[1].configuration.chartHeight).to.be.equal(300); layout.style.height = '200px'; - await onceResized(charts[0]); + await nextResize(charts[0]); expect(layout.getBoundingClientRect().height).to.be.equal(200); expect(charts[0].configuration.chartHeight).to.be.equal(200); diff --git a/packages/component-base/test/overflow-controller.test.js b/packages/component-base/test/overflow-controller.test.js index 61ae8792d5..624b7e5fb9 100644 --- a/packages/component-base/test/overflow-controller.test.js +++ b/packages/component-base/test/overflow-controller.test.js @@ -1,30 +1,9 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync, nextFrame, nextRender } from '@vaadin/testing-helpers'; -import sinon from 'sinon'; +import { fixtureSync, nextFrame, nextRender, nextResize } from '@vaadin/testing-helpers'; import { html, PolymerElement } from '@polymer/polymer/polymer-element.js'; import { ControllerMixin } from '../src/controller-mixin.js'; import { OverflowController } from '../src/overflow-controller.js'; -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName) { - return new Promise((resolve) => { - sinon.replace(object, functionName, (...args) => { - sinon.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -/** - * Resolves once the ResizeObserver has processed a resize. - */ -async function onceResized(controller) { - await onceInvoked(controller, '__updateOverflow'); -} - customElements.define( 'overflow-element', class OverflowElement extends ControllerMixin(PolymerElement) { @@ -124,7 +103,7 @@ describe('overflow-controller', () => { describe(`small viewport ${dir}`, () => { beforeEach(async () => { element.style.width = '80px'; - await onceResized(controller); + await nextResize(element); await nextFrame(); }); @@ -147,7 +126,8 @@ describe('overflow-controller', () => { it(`should update overflow attribute on host resize with ${dir}`, async () => { element.style.width = 'auto'; - await onceResized(controller); + await nextResize(element); + await nextFrame(); expect(element.hasAttribute('overflow')).to.be.false; }); @@ -155,7 +135,8 @@ describe('overflow-controller', () => { items.forEach((item) => { item.style.minWidth = '20px'; }); - await onceResized(controller); + await Promise.all(items.map((item) => nextResize(item))); + await nextFrame(); expect(element.hasAttribute('overflow')).to.be.false; }); @@ -177,7 +158,8 @@ describe('overflow-controller', () => { await nextFrame(); div.style.minWidth = '30px'; - await onceResized(controller); + await nextResize(div); + await nextFrame(); expect(element.hasAttribute('overflow')).to.be.true; }); }); @@ -211,7 +193,7 @@ describe('overflow-controller', () => { describe('small viewport', () => { beforeEach(async () => { element.style.height = '80px'; - await onceResized(controller); + await nextResize(element); await nextFrame(); }); @@ -234,7 +216,8 @@ describe('overflow-controller', () => { it('should update overflow attribute on host element resize', async () => { element.style.height = 'auto'; - await onceResized(controller); + await nextResize(element); + await nextFrame(); expect(element.hasAttribute('overflow')).to.be.false; }); @@ -242,7 +225,8 @@ describe('overflow-controller', () => { items.forEach((item) => { item.style.height = '15px'; }); - await onceResized(controller); + await Promise.all(items.map((item) => nextResize(item))); + await nextFrame(); expect(element.hasAttribute('overflow')).to.be.false; }); @@ -280,7 +264,7 @@ describe('overflow-controller', () => { beforeEach(async () => { element.style.width = '80px'; scroller.style.display = 'flex'; - await onceResized(controller); + await nextResize(element); await nextFrame(); }); @@ -294,7 +278,7 @@ describe('overflow-controller', () => { describe('vertical scroller', () => { beforeEach(async () => { element.style.height = '80px'; - await onceResized(controller); + await nextResize(element); await nextFrame(); }); diff --git a/packages/component-base/test/resize-mixin.test.js b/packages/component-base/test/resize-mixin.test.js index 5743eb99f1..b964848195 100644 --- a/packages/component-base/test/resize-mixin.test.js +++ b/packages/component-base/test/resize-mixin.test.js @@ -1,30 +1,9 @@ import { expect } from '@vaadin/chai-plugins'; -import { aTimeout, fixtureSync, nextFrame } from '@vaadin/testing-helpers'; +import { aTimeout, fixtureSync, nextFrame, nextResize } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import { html, PolymerElement } from '@polymer/polymer/polymer-element.js'; import { ResizeMixin } from '../src/resize-mixin.js'; -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName) { - return new Promise((resolve) => { - sinon.replace(object, functionName, (...args) => { - sinon.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -/** - * Resolves once the ResizeObserver in AvatarGroup has processed a resize. - */ -async function onceResized(el) { - // Wait for the _onResize function to be invoked by the ResizeObserver - await onceInvoked(el, '_onResize'); -} - describe('resize-mixin', () => { let element, observeParent; @@ -53,13 +32,13 @@ describe('resize-mixin', () => { beforeEach(async () => { element = fixtureSync(``); // Wait for the initial resize. - await onceResized(element); + await nextResize(element); }); it('should notify resize', async () => { const spy = sinon.spy(element, '_onResize'); element.style.width = '100px'; - await onceResized(element); + await nextResize(element); expect(spy.calledOnce).to.be.true; }); @@ -83,13 +62,13 @@ describe('resize-mixin', () => { beforeEach(async () => { parent.appendChild(element); // Wait for the initial resize. - await onceResized(element); + await nextResize(parent); }); it('should notify parent element resize', async () => { const spy = sinon.spy(element, '_onResize'); parent.style.width = '100px'; - await onceResized(element); + await nextResize(parent); expect(spy.calledOnce).to.be.true; }); @@ -130,13 +109,13 @@ describe('resize-mixin', () => { parent.attachShadow({ mode: 'open' }); parent.shadowRoot.appendChild(element); // Wait for the initial resize. - await onceResized(element); + await nextResize(parent); }); it('should notify shadow host resize', async () => { const spy = sinon.spy(element, '_onResize'); parent.style.width = '100px'; - await onceResized(element); + await nextResize(parent); expect(spy.calledOnce).to.be.true; }); }); diff --git a/packages/dashboard/test/dashboard-keyboard.test.ts b/packages/dashboard/test/dashboard-keyboard.test.ts index a91d583865..0b60a8bc03 100644 --- a/packages/dashboard/test/dashboard-keyboard.test.ts +++ b/packages/dashboard/test/dashboard-keyboard.test.ts @@ -1,5 +1,5 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync, isChrome, isFirefox, nextFrame } from '@vaadin/testing-helpers'; +import { fixtureSync, isChrome, isFirefox, nextFrame, nextResize } from '@vaadin/testing-helpers'; import { sendKeys } from '@web/test-runner-commands'; import sinon from 'sinon'; import '../vaadin-dashboard.js'; @@ -17,7 +17,6 @@ import { getResizeHandle, getResizeShrinkHeightButton, getResizeShrinkWidthButton, - onceResized, setMaximumColumnCount, setMaximumColumnWidth, setMinimumColumnWidth, @@ -56,7 +55,7 @@ describe('dashboard - keyboard interaction', () => { }; dashboard.style.width = `${columnWidth * 2}px`; - await onceResized(dashboard); + await nextResize(dashboard); // Make sure the following tab goes back to the first widget (needed for Firefox) const widget = getElementFromCell(dashboard, 0, 0)!; diff --git a/packages/dashboard/test/dashboard-layout.test.ts b/packages/dashboard/test/dashboard-layout.test.ts index 10b9afe832..dc355e288f 100644 --- a/packages/dashboard/test/dashboard-layout.test.ts +++ b/packages/dashboard/test/dashboard-layout.test.ts @@ -1,5 +1,5 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync, nextFrame } from '@vaadin/testing-helpers'; +import { fixtureSync, nextFrame, nextResize } from '@vaadin/testing-helpers'; import '../vaadin-dashboard-layout.js'; import '../vaadin-dashboard-section.js'; import '@vaadin/vaadin-lumo-styles/spacing.js'; @@ -11,7 +11,6 @@ import { getRowHeights, getScrollingContainer, getTitleElement, - onceResized, setColspan, setMaximumColumnCount, setMaximumColumnWidth, @@ -55,7 +54,7 @@ describe('dashboard layout', () => { // Make the dashboard wide enough to fit all items on a single row dashboard.style.width = `${columnWidth * dashboard.childElementCount}px`; - await onceResized(dashboard); + await nextResize(dashboard); expect(getColumnWidths(dashboard)).to.eql([columnWidth, columnWidth]); /* prettier-ignore */ @@ -73,7 +72,7 @@ describe('dashboard layout', () => { it('should be responsive', async () => { // Narrow down the component to fit one column dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); /* prettier-ignore */ expectLayout(dashboard, [ @@ -86,7 +85,7 @@ describe('dashboard layout', () => { dashboard.style.width = `${columnWidth}px`; const rowHeight = Math.ceil(getRowHeights(dashboard)[0]); dashboard.style.height = `${rowHeight}px`; - await onceResized(dashboard); + await nextResize(dashboard); const scrollingContainer = getScrollingContainer(dashboard); expect(getComputedStyle(scrollingContainer).overflowY).to.eql('auto'); @@ -98,7 +97,7 @@ describe('dashboard layout', () => { it('should scroll horizontally when content overflows', async () => { dashboard.style.width = `${columnWidth / 2}px`; - await onceResized(dashboard); + await nextResize(dashboard); const scrollingContainer = getScrollingContainer(dashboard); expect(getComputedStyle(scrollingContainer).overflowX).to.eql('auto'); @@ -118,7 +117,7 @@ describe('dashboard layout', () => { setMinimumColumnWidth(dashboard, undefined); // Narrow down the component to have the width of 0 dashboard.style.width = '0'; - await onceResized(dashboard); + await nextResize(dashboard); // Expect the column width to equal the default minimum column width expect(getColumnWidths(dashboard)).to.eql([defaultMinimumColumnWidth]); }); @@ -126,7 +125,7 @@ describe('dashboard layout', () => { it('should have one overflown column if narrowed below minimum column width', async () => { // Narrow down the component to have the width of half a column dashboard.style.width = `${columnWidth / 2}px`; - await onceResized(dashboard); + await nextResize(dashboard); // Expect the column width to still be the same (overflown) expect(getColumnWidths(dashboard)).to.eql([columnWidth]); }); @@ -136,7 +135,7 @@ describe('dashboard layout', () => { setMinimumColumnWidth(dashboard, columnWidth / 2); // Narrow down the component to have the width of half a column dashboard.style.width = `${columnWidth / 2}px`; - await onceResized(dashboard); + await nextResize(dashboard); // Expect the column width to equal the min column width expect(getColumnWidths(dashboard)).to.eql([columnWidth / 2]); }); @@ -162,15 +161,15 @@ describe('dashboard layout', () => { expect(getColumnWidths(dashboard)).to.eql([columnWidth, columnWidth]); // Widen the component to have the width of 2.5 columns dashboard.style.width = `${columnWidth * 2.5}px`; - await onceResized(dashboard); + await nextResize(dashboard); expect(getColumnWidths(dashboard)).to.eql([columnWidth * 1.25, columnWidth * 1.25]); // Widen the component to have the width of 3 columns dashboard.style.width = `${columnWidth * 3}px`; - await onceResized(dashboard); + await nextResize(dashboard); expect(getColumnWidths(dashboard)).to.eql([columnWidth, columnWidth, columnWidth]); // Shrink the component to have the width of 1.5 columns dashboard.style.width = `${columnWidth * 1.5}px`; - await onceResized(dashboard); + await nextResize(dashboard); expect(getColumnWidths(dashboard)).to.eql([columnWidth * 1.5]); }); @@ -213,7 +212,7 @@ describe('dashboard layout', () => { it('should use minimum row height for all rows', async () => { dashboard.style.width = `${columnWidth}px`; setMinimumRowHeight(dashboard, rowHeight); - await onceResized(dashboard); + await nextResize(dashboard); expect(getRowHeights(dashboard)).to.eql([rowHeight, rowHeight]); }); }); @@ -235,7 +234,7 @@ describe('dashboard layout', () => { await nextFrame(); dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); /* prettier-ignore */ expectLayout(dashboard, [ @@ -249,7 +248,7 @@ describe('dashboard layout', () => { await nextFrame(); dashboard.style.width = `${columnWidth * 3}px`; - await onceResized(dashboard); + await nextResize(dashboard); /* prettier-ignore */ expectLayout(dashboard, [ @@ -275,7 +274,7 @@ describe('dashboard layout', () => { // Expect widget 1 to still have the same width expect(childElements[1].offsetWidth).to.eql(widget1Width); - await onceResized(dashboard); + await nextResize(dashboard); /* prettier-ignore */ expectLayout(dashboard, [ @@ -307,7 +306,7 @@ describe('dashboard layout', () => { await nextFrame(); dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); /* prettier-ignore */ expectLayout(dashboard, [ @@ -324,7 +323,7 @@ describe('dashboard layout', () => { setSpacing(dashboard, undefined); // Increase the width of the dashboard to fit two items, paddings and a gap dashboard.style.width = `calc(${columnWidth}px * 2 + ${defaultSpacing * 3}px)`; - await onceResized(dashboard); + await nextResize(dashboard); const { right: item0Right } = childElements[0].getBoundingClientRect(); const { left: item1Left } = childElements[1].getBoundingClientRect(); @@ -337,7 +336,7 @@ describe('dashboard layout', () => { setSpacing(dashboard, customSpacing); // Increase the width of the dashboard to fit two items, paddings and a gap dashboard.style.width = `${columnWidth * 2 + customSpacing * 3}px`; - await onceResized(dashboard); + await nextResize(dashboard); const { right: item0Right } = childElements[0].getBoundingClientRect(); const { left: item1Left } = childElements[1].getBoundingClientRect(); @@ -349,7 +348,7 @@ describe('dashboard layout', () => { const customSpacing = 10; setSpacing(dashboard, customSpacing); dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); const { bottom: item0Bottom } = childElements[0].getBoundingClientRect(); const { top: item1Top } = childElements[1].getBoundingClientRect(); @@ -362,7 +361,7 @@ describe('dashboard layout', () => { it('should have default padding', async () => { // Clear the padding used in the tests setSpacing(dashboard, undefined); - await onceResized(dashboard); + await nextResize(dashboard); const { left: itemLeft } = childElements[0].getBoundingClientRect(); const { left: dashbboardLeft } = dashboard.getBoundingClientRect(); @@ -373,7 +372,7 @@ describe('dashboard layout', () => { it('should have custom gap between items horizontally', async () => { const customSpacing = 10; setSpacing(dashboard, customSpacing); - await onceResized(dashboard); + await nextResize(dashboard); const { left: itemLeft } = childElements[0].getBoundingClientRect(); const { left: dashbboardLeft } = dashboard.getBoundingClientRect(); @@ -385,21 +384,21 @@ describe('dashboard layout', () => { describe('maximum column count', () => { it('should not limit column count by default', async () => { dashboard.style.width = `${columnWidth * 100}px`; - await onceResized(dashboard); + await nextResize(dashboard); expect(getColumnWidths(dashboard).length).to.eql(100); }); it('should limit column count to custom value', async () => { setMaximumColumnCount(dashboard, 5); dashboard.style.width = `${columnWidth * 100}px`; - await onceResized(dashboard); + await nextResize(dashboard); expect(getColumnWidths(dashboard).length).to.eql(5); }); it('should limit column count to one', async () => { setMaximumColumnCount(dashboard, 1); dashboard.style.width = `${columnWidth * 10}px`; - await onceResized(dashboard); + await nextResize(dashboard); /* prettier-ignore */ expectLayout(dashboard, [ [0], @@ -410,7 +409,7 @@ describe('dashboard layout', () => { it('should allow fewer columns', async () => { setMaximumColumnCount(dashboard, 2); dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); /* prettier-ignore */ expectLayout(dashboard, [ [0], @@ -432,7 +431,7 @@ describe('dashboard layout', () => { it('should increase max column count dynamically', async () => { setMaximumColumnCount(dashboard, 2); dashboard.style.width = `${columnWidth * 100}px`; - await onceResized(dashboard); + await nextResize(dashboard); expect(getColumnWidths(dashboard).length).to.eql(2); setMaximumColumnCount(dashboard, 20); @@ -466,7 +465,7 @@ describe('dashboard layout', () => { it('should be on its own row', async () => { dashboard.style.width = `${columnWidth * 4}px`; - await onceResized(dashboard); + await nextResize(dashboard); /* prettier-ignore */ expectLayout(dashboard, [ @@ -478,7 +477,7 @@ describe('dashboard layout', () => { it('following items should end up in the next row', async () => { dashboard.style.width = `${columnWidth * 4}px`; dashboard.appendChild(fixtureSync('
Item 4
')); - await onceResized(dashboard); + await nextResize(dashboard); /* prettier-ignore */ expectLayout(dashboard, [ @@ -490,7 +489,7 @@ describe('dashboard layout', () => { it('should be capped to currently available columns', async () => { dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); /* prettier-ignore */ expectLayout(dashboard, [ @@ -504,7 +503,7 @@ describe('dashboard layout', () => { it('should span multiple columns inside a section', async () => { dashboard.style.width = `${columnWidth * 3}px`; setColspan(childElements[2], 2); - await onceResized(dashboard); + await nextResize(dashboard); /* prettier-ignore */ expectLayout(dashboard, [ @@ -530,7 +529,7 @@ describe('dashboard layout', () => { it('should use minimum row height for all section rows', async () => { dashboard.style.width = `${columnWidth}px`; setMinimumRowHeight(dashboard, 300); - await onceResized(dashboard); + await nextResize(dashboard); expect(childElements[2].offsetHeight).to.eql(300); expect(childElements[3].offsetHeight).to.eql(300); @@ -554,7 +553,7 @@ describe('dashboard layout', () => { setSpacing(dashboard, undefined); // Increase the width of the dashboard to fit two items, paddings and a gap dashboard.style.width = `calc(${columnWidth}px * 2 + ${defaultSpacing * 3}px)`; - await onceResized(dashboard); + await nextResize(dashboard); const { right: item2Right } = childElements[2].getBoundingClientRect(); const { left: item3Left } = childElements[3].getBoundingClientRect(); @@ -567,7 +566,7 @@ describe('dashboard layout', () => { setSpacing(dashboard, customSpacing); // Increase the width of the dashboard to fit two items, paddings and a gap dashboard.style.width = `${columnWidth * 2 + customSpacing * 3}px`; - await onceResized(dashboard); + await nextResize(dashboard); const { right: item2Right } = childElements[2].getBoundingClientRect(); const { left: item3Left } = childElements[3].getBoundingClientRect(); @@ -579,7 +578,7 @@ describe('dashboard layout', () => { const customSpacing = 10; setSpacing(dashboard, customSpacing); dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); const { bottom: item2Bottom } = childElements[2].getBoundingClientRect(); const { top: item3Top } = childElements[3].getBoundingClientRect(); diff --git a/packages/dashboard/test/dashboard-widget-reordering.test.ts b/packages/dashboard/test/dashboard-widget-reordering.test.ts index 70c9ea05e3..a8e3b0c8c9 100644 --- a/packages/dashboard/test/dashboard-widget-reordering.test.ts +++ b/packages/dashboard/test/dashboard-widget-reordering.test.ts @@ -1,5 +1,5 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync, isFirefox, nextFrame } from '@vaadin/testing-helpers'; +import { fixtureSync, isFirefox, nextFrame, nextResize } from '@vaadin/testing-helpers'; import { resetMouse, sendMouse } from '@web/test-runner-commands'; import sinon from 'sinon'; import '../vaadin-dashboard.js'; @@ -15,7 +15,6 @@ import { getDraggable, getElementFromCell, getParentSection, - onceResized, resetReorderTimeout, setMaximumColumnWidth, setMinimumColumnWidth, @@ -51,7 +50,7 @@ describe('dashboard - widget reordering', () => { root.appendChild(widget); }; dashboard.style.width = `${columnWidth * 2}px`; - await onceResized(dashboard); + await nextResize(dashboard); // prettier-ignore expectLayout(dashboard, [ @@ -95,7 +94,7 @@ describe('dashboard - widget reordering', () => { it('should reorder the widgets while dragging (top -> bottom)', async () => { dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); // prettier-ignore expectLayout(dashboard, [ @@ -118,7 +117,7 @@ describe('dashboard - widget reordering', () => { it('should reorder the widgets while dragging (bottom -> top)', async () => { dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); // prettier-ignore expectLayout(dashboard, [ @@ -293,7 +292,7 @@ describe('dashboard - widget reordering', () => { dashboard.style.width = `${columnWidth * 4}px`; (dashboard.items[1] as TestDashboardItem).colspan = 2; dashboard.items = [...dashboard.items, { id: 2 }]; - await onceResized(dashboard); + await nextResize(dashboard); // prettier-ignore expectLayout(dashboard, [ @@ -319,7 +318,7 @@ describe('dashboard - widget reordering', () => { // Add a third widget dashboard.style.width = `${columnWidth * 3}px`; dashboard.items = [...dashboard.items, { id: 2 }]; - await onceResized(dashboard); + await nextResize(dashboard); // prettier-ignore expectLayout(dashboard, [ [0, 1, 2], @@ -344,7 +343,7 @@ describe('dashboard - widget reordering', () => { // Add a third widget dashboard.style.width = `${columnWidth * 2}px`; dashboard.items = [...dashboard.items, { id: 2 }]; - await onceResized(dashboard); + await nextResize(dashboard); // prettier-ignore expectLayout(dashboard, [ [0, 1], diff --git a/packages/dashboard/test/dashboard-widget-resizing.test.ts b/packages/dashboard/test/dashboard-widget-resizing.test.ts index c19c610211..882f0bb417 100644 --- a/packages/dashboard/test/dashboard-widget-resizing.test.ts +++ b/packages/dashboard/test/dashboard-widget-resizing.test.ts @@ -1,5 +1,5 @@ import { expect } from '@vaadin/chai-plugins'; -import { fire, fixtureSync, nextFrame } from '@vaadin/testing-helpers'; +import { fire, fixtureSync, nextFrame, nextResize } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import '../vaadin-dashboard.js'; import { isSafari } from '@vaadin/component-base/src/browser-utils.js'; @@ -13,7 +13,6 @@ import { getElementFromCell, getEventCoordinates, getResizeHandle, - onceResized, setMaximumColumnWidth, setMinimumColumnWidth, setMinimumRowHeight, @@ -48,7 +47,7 @@ describe('dashboard - widget resizing', () => { root.appendChild(widget); }; dashboard.style.width = `${columnWidth * 2}px`; - await onceResized(dashboard); + await nextResize(dashboard); // prettier-ignore expectLayout(dashboard, [ @@ -321,7 +320,7 @@ describe('dashboard - widget resizing', () => { // Narrow the dashboard to have only one column dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); // prettier-ignore expectLayout(dashboard, [ [0], @@ -510,7 +509,7 @@ describe('dashboard - widget resizing', () => { it('should not throw with a lazy renderer while resizing', async () => { dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); // prettier-ignore expectLayout(dashboard, [ [0], @@ -553,7 +552,7 @@ describe('dashboard - widget resizing', () => { it('should take gap into account when resizing', async () => { dashboard.style.width = `${columnWidth * 3}px`; setSpacing(dashboard, 20); - await onceResized(dashboard); + await nextResize(dashboard); // prettier-ignore expectLayout(dashboard, [ diff --git a/packages/dashboard/test/dashboard.test.ts b/packages/dashboard/test/dashboard.test.ts index 57d3776112..74a13e0050 100644 --- a/packages/dashboard/test/dashboard.test.ts +++ b/packages/dashboard/test/dashboard.test.ts @@ -1,5 +1,5 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync } from '@vaadin/testing-helpers'; +import { fixtureSync, nextResize } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import '../vaadin-dashboard.js'; import type { CustomElementType } from '@vaadin/component-base/src/define.js'; @@ -15,7 +15,6 @@ import { getRemoveButton, getResizeHandle, getScrollingContainer, - onceResized, setMaximumColumnWidth, setMinimumColumnWidth, setMinimumRowHeight, @@ -163,7 +162,7 @@ describe('dashboard', () => { describe('row span', () => { it('should span one row by default', async () => { dashboard.style.width = `${columnWidth}px`; - await onceResized(dashboard); + await nextResize(dashboard); const widgets = [getElementFromCell(dashboard, 0, 0), getElementFromCell(dashboard, 1, 0)]; expect(widgets[0]).to.not.equal(widgets[1]); }); @@ -171,7 +170,7 @@ describe('dashboard', () => { it('should span multiple rows', async () => { dashboard.style.width = `${columnWidth}px`; dashboard.items = [{ rowspan: 2, id: '0' }]; - await onceResized(dashboard); + await nextResize(dashboard); const widget = getElementFromCell(dashboard, 0, 0); expect(widget).to.have.property('widgetTitle', 'Item 0 title'); @@ -596,7 +595,7 @@ describe('dashboard', () => { it('should scroll the focused item outside dashboard viewport back into view', async () => { // Limit the dashboard height to force scrolling dashboard.style.height = '300px'; - await onceResized(dashboard); + await nextResize(dashboard); // Focus the first item getElementFromCell(dashboard, 0, 0)!.focus(); @@ -614,7 +613,7 @@ describe('dashboard', () => { it('should not scroll the focused item into view if it is partially visible', async () => { // Limit the dashboard height to force scrolling dashboard.style.height = '300px'; - await onceResized(dashboard); + await nextResize(dashboard); // Focus the first item getElementFromCell(dashboard, 0, 0)!.focus(); diff --git a/packages/dashboard/test/helpers.ts b/packages/dashboard/test/helpers.ts index d052b2f5f7..844ccf512c 100644 --- a/packages/dashboard/test/helpers.ts +++ b/packages/dashboard/test/helpers.ts @@ -359,23 +359,6 @@ export function getResizeGrowHeightButton(element: HTMLElement): HTMLElement { return element.shadowRoot!.querySelector('[part~="resize-grow-height-button"]') as HTMLElement; } -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName): Promise { - return new Promise((resolve) => { - sinon.replace(object, functionName, (...args) => { - sinon.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -export async function onceResized(dashboard: HTMLElement): Promise { - await onceInvoked(dashboard, '_onResize'); -} - export async function updateComplete(dashboard: HTMLElement): Promise { await nextUpdate(dashboard); diff --git a/packages/dialog/test/header-footer.common.js b/packages/dialog/test/header-footer.common.js index 04869336c7..9e7e9bd91d 100644 --- a/packages/dialog/test/header-footer.common.js +++ b/packages/dialog/test/header-footer.common.js @@ -1,5 +1,5 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync, nextRender, nextUpdate } from '@vaadin/testing-helpers'; +import { fixtureSync, nextRender, nextResize, nextUpdate } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import { createRenderer } from './helpers.js'; @@ -489,12 +489,6 @@ describe('header/footer feature', () => { }); describe('resize', () => { - const nextResize = (target) => { - return new Promise((resolve) => { - new ResizeObserver(() => setTimeout(resolve)).observe(target); - }); - }; - it('should not set overflow attribute when content has no scrollbar', () => { expect(overlay.hasAttribute('overflow')).to.be.false; }); diff --git a/packages/form-layout/test/form-layout.common.js b/packages/form-layout/test/form-layout.common.js index 94bb17cad8..280ab3056a 100644 --- a/packages/form-layout/test/form-layout.common.js +++ b/packages/form-layout/test/form-layout.common.js @@ -1,29 +1,9 @@ import { expect } from '@vaadin/chai-plugins'; -import { aTimeout, fixtureSync, nextFrame, nextRender } from '@vaadin/testing-helpers'; +import { aTimeout, fixtureSync, nextFrame, nextRender, nextResize } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import '@polymer/polymer/lib/elements/dom-repeat.js'; import { html, PolymerElement } from '@polymer/polymer/polymer-element.js'; -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName) { - return new Promise((resolve) => { - sinon.replace(object, functionName, (...args) => { - sinon.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -/** - * Resolves once the ResizeObserver in FormLayout has processed a resize. - */ -async function onceResized(layout) { - await onceInvoked(layout, '_updateLayout'); -} - customElements.define( 'mutable-layout', class extends PolymerElement { @@ -147,7 +127,7 @@ describe('form layout', () => { it('should apply default column-spacing', async () => { // Override to not depend on the theme changes layout.style.setProperty('--lumo-space-l', '2rem'); - await onceResized(layout); + await nextResize(layout); expect(getParsedWidth(layout.firstElementChild).spacing).to.equal('1rem'); expect(getComputedStyle(layout.firstElementChild).getPropertyValue('margin-left')).to.equal('0px'); // Zero because it's first expect(getComputedStyle(layout.firstElementChild).getPropertyValue('margin-right')).to.equal('16px'); // 0.5 * 2rem in px @@ -350,17 +330,17 @@ describe('form layout', () => { it('should be responsive by default', async () => { document.body.style.width = '10em'; - await onceResized(layout); + await nextResize(layout); expect(estimateEffectiveColumnCount(layout)).to.be.closeTo(1, 0.1); expect(layout.children[2].getAttribute('label-position')).to.equal('top'); document.body.style.width = '20em'; - await onceResized(layout); + await nextResize(layout); expect(estimateEffectiveColumnCount(layout)).to.be.closeTo(1, 0.1); expect(layout.children[2].getAttribute('label-position')).to.be.null; document.body.style.width = '40em'; - await onceResized(layout); + await nextResize(layout); expect(estimateEffectiveColumnCount(layout)).to.be.closeTo(2, 0.1); expect(layout.children[2].getAttribute('label-position')).to.be.null; }); @@ -392,17 +372,17 @@ describe('form layout', () => { ]; document.body.style.width = '10em'; - await onceResized(layout); + await nextResize(layout); expect(estimateEffectiveColumnCount(layout)).to.be.closeTo(1, 0.1); expect(layout.children[2].getAttribute('label-position')).to.be.null; document.body.style.width = '20em'; - await onceResized(layout); + await nextResize(layout); expect(estimateEffectiveColumnCount(layout)).to.be.closeTo(2, 0.1); expect(layout.children[2].getAttribute('label-position')).to.equal('top'); document.body.style.width = '40em'; - await onceResized(layout); + await nextResize(layout); expect(estimateEffectiveColumnCount(layout)).to.be.closeTo(5, 0.1); expect(layout.children[2].getAttribute('label-position')).to.be.null; }); diff --git a/packages/grid/test/column-groups.common.js b/packages/grid/test/column-groups.common.js index be47950c48..56956acd71 100644 --- a/packages/grid/test/column-groups.common.js +++ b/packages/grid/test/column-groups.common.js @@ -1,5 +1,5 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync, nextFrame, nextRender } from '@vaadin/testing-helpers'; +import { fixtureSync, nextFrame, nextRender, nextResize } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import { attributeRenderer, @@ -9,7 +9,6 @@ import { getRowCells, getRows, infiniteDataProvider, - nextResize, scrollToEnd, } from './helpers.js'; diff --git a/packages/grid/test/column-rendering.common.js b/packages/grid/test/column-rendering.common.js index fb20302330..7b125bfb93 100644 --- a/packages/grid/test/column-rendering.common.js +++ b/packages/grid/test/column-rendering.common.js @@ -1,7 +1,7 @@ import { expect } from '@vaadin/chai-plugins'; -import { aTimeout, fixtureSync, keyDownOn, nextFrame, oneEvent } from '@vaadin/testing-helpers'; +import { aTimeout, fixtureSync, keyDownOn, nextFrame, nextResize, oneEvent } from '@vaadin/testing-helpers'; import Sinon from 'sinon'; -import { flushGrid, getCellContent, getHeaderCellContent, onceResized } from './helpers.js'; +import { flushGrid, getCellContent, getHeaderCellContent } from './helpers.js'; ['ltr', 'rtl'].forEach((dir) => { describe(`lazy column rendering - ${dir}`, () => { @@ -99,7 +99,7 @@ import { flushGrid, getCellContent, getHeaderCellContent, onceResized } from './ grid.columnRendering = 'lazy'; // Wait for the initial resize observer callback - await onceResized(grid); + await nextResize(grid); flushGrid(grid); }); @@ -141,7 +141,7 @@ import { flushGrid, getCellContent, getHeaderCellContent, onceResized } from './ it('should render columns revealed columns on resize', async () => { grid.style.width = `${grid.$.table.scrollWidth}px`; - await onceResized(grid); + await nextResize(grid); expectBodyCellUpdated(getLastVisibleColumnIndex()); expectBodyCellUpdated(columns.length - 1); }); @@ -222,7 +222,7 @@ import { flushGrid, getCellContent, getHeaderCellContent, onceResized } from './ `); grid.items = [{ name: `Item 1` }]; - await onceResized(grid); + await nextResize(grid); flushGrid(grid); const newColumn = document.createElement('vaadin-grid-column'); @@ -278,7 +278,7 @@ import { flushGrid, getCellContent, getHeaderCellContent, onceResized } from './ it('should render columns revealed columns on resize', async () => { grid.style.width = `${grid.$.table.scrollWidth}px`; - await onceResized(grid); + await nextResize(grid); expectBodyCellUpdated(0); expectBodyCellUpdated(1); }); diff --git a/packages/grid/test/frozen-columns.common.js b/packages/grid/test/frozen-columns.common.js index 5daae787eb..90ce1eb94a 100644 --- a/packages/grid/test/frozen-columns.common.js +++ b/packages/grid/test/frozen-columns.common.js @@ -1,17 +1,10 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync, listenOnce, nextRender } from '@vaadin/testing-helpers'; +import { fixtureSync, listenOnce, nextRender, nextResize } from '@vaadin/testing-helpers'; import { resetMouse, sendMouse } from '@web/test-runner-commands'; import sinon from 'sinon'; import { isElementFocused } from '@vaadin/a11y-base/src/focus-utils.js'; import { setNormalizedScrollLeft } from '@vaadin/component-base/src/dir-utils.js'; -import { - flushGrid, - getRowCells, - getRows, - infiniteDataProvider, - isWithinParentConstraints, - onceResized, -} from './helpers.js'; +import { flushGrid, getRowCells, getRows, infiniteDataProvider, isWithinParentConstraints } from './helpers.js'; // Returns true if the element's computed transform style matches with the // computed transform style of a div element with the given transform applied @@ -296,7 +289,7 @@ const frozenGridFixture = (frozen, frozenToEnd) => { const x = cells[2].getBoundingClientRect().x; grid.style.width = '300px'; - await onceResized(grid); + await nextResize(grid); expect(cells[2].getBoundingClientRect().x).to.equal(isRTL ? x - 100 : x + 100); }); @@ -326,7 +319,7 @@ const frozenGridFixture = (frozen, frozenToEnd) => { grid._columnTree[0][frozenToEndColumnIndex].flexGrow = 0; grid.style.width = '400px'; - await onceResized(grid); + await nextResize(grid); const initBoundingClientRect = getRowCells(containerRows[0])[2].getBoundingClientRect(); @@ -347,7 +340,7 @@ const frozenGridFixture = (frozen, frozenToEnd) => { grid._columnTree[0][frozenToEndColumnIndex].flexGrow = 0; grid.style.width = '400px'; - await onceResized(grid); + await nextResize(grid); for (let i = 0; i < 2; i++) { if (frozenToEndColumnIndex === i) { diff --git a/packages/grid/test/helpers.js b/packages/grid/test/helpers.js index 3a6b2f8a5e..32abc7bbfb 100644 --- a/packages/grid/test/helpers.js +++ b/packages/grid/test/helpers.js @@ -1,4 +1,3 @@ -import { aTimeout } from '@vaadin/testing-helpers'; import sinon from 'sinon'; export const flushGrid = (grid) => { @@ -270,12 +269,6 @@ export const makeSoloTouchEvent = (type, xy, node) => { return event; }; -export const nextResize = (target) => { - return new Promise((resolve) => { - new ResizeObserver(() => setTimeout(resolve)).observe(target); - }); -}; - /** * Resolves once the function is invoked on the given object. */ @@ -289,15 +282,6 @@ export function onceInvoked(object, functionName) { }); } -/** - * Resolves once the ResizeObserver in grid has processed a resize. - */ -export async function onceResized(grid) { - await onceInvoked(grid, '_onResize'); - // Grid's resize observer uses setTimeout - await aTimeout(0); -} - export const shiftClick = (node) => { node.dispatchEvent(new MouseEvent('click', { shiftKey: true })); }; diff --git a/packages/grid/test/min-height.common.js b/packages/grid/test/min-height.common.js index 0e3af294a7..61f5e12f67 100644 --- a/packages/grid/test/min-height.common.js +++ b/packages/grid/test/min-height.common.js @@ -1,6 +1,6 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync } from '@vaadin/testing-helpers'; -import { flushGrid, infiniteDataProvider, nextResize } from './helpers.js'; +import { fixtureSync, nextResize } from '@vaadin/testing-helpers'; +import { flushGrid, infiniteDataProvider } from './helpers.js'; describe('min-height', () => { const rowHeight = 36; diff --git a/packages/grid/test/resizing.common.js b/packages/grid/test/resizing.common.js index 9a4cd214d4..34a8c168c9 100644 --- a/packages/grid/test/resizing.common.js +++ b/packages/grid/test/resizing.common.js @@ -1,5 +1,5 @@ import { expect } from '@vaadin/chai-plugins'; -import { aTimeout, fixtureSync, nextFrame, oneEvent } from '@vaadin/testing-helpers'; +import { aTimeout, fixtureSync, nextFrame, nextResize, oneEvent } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import { html, PolymerElement } from '@polymer/polymer/polymer-element.js'; import { @@ -11,7 +11,6 @@ import { getRowCells, getRows, infiniteDataProvider, - nextResize, scrollToEnd, } from './helpers.js'; diff --git a/packages/grid/test/scrolling-mode.common.js b/packages/grid/test/scrolling-mode.common.js index 77fcd7bb7c..705b989539 100644 --- a/packages/grid/test/scrolling-mode.common.js +++ b/packages/grid/test/scrolling-mode.common.js @@ -1,6 +1,14 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync, isDesktopSafari, isFirefox, listenOnce, nextFrame, nextRender } from '@vaadin/testing-helpers'; -import { flushGrid, infiniteDataProvider, onceResized, scrollToEnd } from './helpers.js'; +import { + fixtureSync, + isDesktopSafari, + isFirefox, + listenOnce, + nextFrame, + nextRender, + nextResize, +} from '@vaadin/testing-helpers'; +import { flushGrid, infiniteDataProvider, scrollToEnd } from './helpers.js'; describe('scrolling mode', () => { let grid; @@ -105,12 +113,12 @@ describe('scrolling mode', () => { // but not as often as in WebKit. (isDesktopSafari || isFirefox ? it.skip : it)('update on resize', async () => { grid.style.width = '200px'; - await onceResized(grid); + await nextResize(grid); await nextFrame(); expect(grid.getAttribute('overflow')).to.equal('bottom'); grid.style.width = '50px'; - await onceResized(grid); + await nextResize(grid); await nextFrame(); expect(grid.getAttribute('overflow')).to.equal('bottom end right'); }); diff --git a/packages/icon/test/icon-font.common.js b/packages/icon/test/icon-font.common.js index 8f610d18e7..b49a066e8a 100644 --- a/packages/icon/test/icon-font.common.js +++ b/packages/icon/test/icon-font.common.js @@ -1,31 +1,8 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync, isChrome, nextFrame } from '@vaadin/testing-helpers'; -import sinon from 'sinon'; +import { fixtureSync, isChrome, nextFrame, nextResize } from '@vaadin/testing-helpers'; import { needsFontIconSizingFallback, supportsCQUnitsForPseudoElements } from '../src/vaadin-icon-helpers.js'; import { iconFontCss } from './test-icon-font.js'; -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName) { - return new Promise((resolve) => { - sinon.replace(object, functionName, (...args) => { - sinon.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -/** - * Resolves once the icon resize is complete. - */ -async function onceResized(icon) { - if (needsFontIconSizingFallback()) { - await onceInvoked(icon, '_onResize'); - } -} - describe('vaadin-icon - icon fonts', () => { beforeEach(() => { fixtureSync(` @@ -40,7 +17,7 @@ describe('vaadin-icon - icon fonts', () => { beforeEach(async () => { icon = fixtureSync(''); - await onceResized(icon); + await nextResize(icon); }); it('should have the same height as the host', () => { @@ -51,7 +28,7 @@ describe('vaadin-icon - icon fonts', () => { it('should resize with the host', async () => { icon.style.width = '100px'; icon.style.height = '100px'; - await onceResized(icon); + await nextResize(icon); const fontIconStyle = getComputedStyle(icon, ':before'); expect(parseInt(fontIconStyle.height)).to.be.closeTo(100, 1); }); @@ -59,7 +36,7 @@ describe('vaadin-icon - icon fonts', () => { it('should not overflow host - wider icon', async () => { icon.style.width = '150px'; icon.style.height = '100px'; - await onceResized(icon); + await nextResize(icon); const fontIconStyle = getComputedStyle(icon, ':before'); expect(parseInt(fontIconStyle.height)).to.be.closeTo(100, 1); }); @@ -71,11 +48,11 @@ describe('vaadin-icon - icon fonts', () => { it('should subtract vertical padding from height', async () => { icon.style.padding = '5px'; - await onceResized(icon); + await nextResize(icon); expect(parseInt(getComputedStyle(icon, ':before').height)).to.be.closeTo(14, 1); icon.style.padding = '7px'; - await onceResized(icon); + await nextResize(icon); expect(parseInt(getComputedStyle(icon, ':before').height)).to.be.closeTo(10, 1); }); }); @@ -333,7 +310,7 @@ describe('vaadin-icon - icon fonts', () => { await nextFrame(); icon.style.width = '100px'; icon.style.height = '100px'; - await onceResized(icon); + await nextResize(icon); expect(icon.style.getPropertyValue('--_vaadin-font-icon-size')).to.equal('100px'); }); diff --git a/packages/menu-bar/test/overflow.common.js b/packages/menu-bar/test/overflow.common.js index c5a3d5da41..092f712d6e 100644 --- a/packages/menu-bar/test/overflow.common.js +++ b/packages/menu-bar/test/overflow.common.js @@ -1,6 +1,5 @@ import { expect } from '@vaadin/chai-plugins'; -import { arrowRight, fixtureSync, nextFrame, nextRender, nextUpdate } from '@vaadin/testing-helpers'; -import sinon from 'sinon'; +import { arrowRight, fixtureSync, nextFrame, nextRender, nextResize, nextUpdate } from '@vaadin/testing-helpers'; // Utility function to assert a menu item is not visible const assertHidden = (elem) => { @@ -16,26 +15,6 @@ const assertVisible = (elem) => { expect(style.position).to.not.equal('absolute'); }; -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName) { - return new Promise((resolve) => { - sinon.replace(object, functionName, (...args) => { - sinon.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -/** - * Resolves once the ResizeObserver has processed a resize. - */ -async function onceResized(menu) { - await onceInvoked(menu, '__setOverflowItems'); -} - describe('overflow', () => { describe('overflow button', () => { let wrapper, menu, buttons, overflow; @@ -86,7 +65,7 @@ describe('overflow', () => { it('should show buttons and update overflow items when width increased', async () => { menu.style.width = '350px'; - await onceResized(menu); + await nextResize(menu); assertVisible(buttons[2]); expect(buttons[2].disabled).to.not.be.true; assertVisible(buttons[3]); @@ -98,7 +77,7 @@ describe('overflow', () => { it('should show buttons and update overflow items when width increased in RTL', async () => { menu.setAttribute('dir', 'rtl'); menu.style.width = '350px'; - await onceResized(menu); + await nextResize(menu); assertVisible(buttons[2]); expect(buttons[2].disabled).to.not.be.true; assertVisible(buttons[3]); @@ -109,7 +88,7 @@ describe('overflow', () => { it('should hide buttons and update overflow items when width decreased', async () => { menu.style.width = '150px'; - await onceResized(menu); + await nextResize(menu); assertHidden(buttons[1]); expect(buttons[1].disabled).to.be.true; expect(overflow.item.children.length).to.equal(4); @@ -122,7 +101,7 @@ describe('overflow', () => { it('should hide buttons and update overflow items when width decreased in RTL', async () => { menu.setAttribute('dir', 'rtl'); menu.style.width = '150px'; - await onceResized(menu); + await nextResize(menu); assertHidden(buttons[1]); expect(buttons[1].disabled).to.be.true; expect(overflow.item.children.length).to.equal(4); @@ -134,7 +113,7 @@ describe('overflow', () => { it('should hide overflow button and reset its items when all buttons fit', async () => { menu.style.width = 'auto'; - await onceResized(menu); + await nextResize(menu); assertVisible(buttons[2]); expect(buttons[2].disabled).to.not.be.true; assertVisible(buttons[3]); @@ -159,7 +138,7 @@ describe('overflow', () => { it('should show overflow button when theme makes buttons do not fit', async () => { menu.style.width = '400px'; - await onceResized(menu); + await nextResize(menu); expect(overflow.hasAttribute('hidden')).to.be.true; menu.setAttribute('theme', 'big'); await nextUpdate(menu); @@ -176,7 +155,7 @@ describe('overflow', () => { expect(buttons[1].getAttribute('tabindex')).to.equal('0'); menu.style.width = '150px'; - await onceResized(menu); + await nextResize(menu); expect(buttons[0].getAttribute('tabindex')).to.equal('0'); expect(buttons[1].getAttribute('tabindex')).to.equal('-1'); @@ -191,7 +170,7 @@ describe('overflow', () => { expect(buttons[1].getAttribute('tabindex')).to.equal('0'); menu.style.width = '150px'; - await onceResized(menu); + await nextResize(menu); expect(buttons[0].getAttribute('tabindex')).to.equal('0'); expect(buttons[1].getAttribute('tabindex')).to.equal('-1'); @@ -271,7 +250,7 @@ describe('overflow', () => { it('should not set when one button and overflow are only visible', async () => { menu.style.width = '150px'; - await onceResized(menu); + await nextResize(menu); assertVisible(buttons[0]); assertHidden(buttons[1]); expect(overflow.hasAttribute('hidden')).to.be.false; @@ -280,7 +259,7 @@ describe('overflow', () => { it('should set when only overflow button is visible', async () => { menu.style.width = '100px'; - await onceResized(menu); + await nextResize(menu); assertHidden(buttons[0]); assertHidden(buttons[1]); expect(menu.hasAttribute('has-single-button')).to.be.true; @@ -288,16 +267,16 @@ describe('overflow', () => { it('should remove when buttons become visible after size increases', async () => { menu.style.width = '100px'; - await onceResized(menu); + await nextResize(menu); menu.style.width = '150px'; - await onceResized(menu); + await nextResize(menu); expect(menu.hasAttribute('has-single-button')).to.be.false; }); it('should set when theme attribute makes other buttons not fit', async () => { menu.style.width = '150px'; - await onceResized(menu); + await nextResize(menu); menu.setAttribute('theme', 'big'); await nextUpdate(menu); @@ -312,7 +291,7 @@ describe('overflow', () => { it('should not remove after changing items to not overflow', async () => { menu.style.width = '100px'; - await onceResized(menu); + await nextResize(menu); menu.items = [{ text: 'Actions' }]; await nextUpdate(menu); @@ -358,14 +337,14 @@ describe('overflow', () => { // see https://github.com/vaadin/vaadin-menu-bar/issues/130 menu.style.minWidth = '0'; container.style.width = '150px'; - await onceResized(menu); + await nextResize(menu); assertHidden(buttons[2]); expect(buttons[2].disabled).to.be.true; assertHidden(buttons[3]); expect(buttons[3].disabled).to.be.true; container.style.width = '400px'; - await onceResized(menu); + await nextResize(menu); assertVisible(buttons[2]); expect(buttons[2].disabled).to.not.be.true; assertVisible(buttons[3]); @@ -380,7 +359,7 @@ describe('overflow', () => { menu.disabled = true; await nextUpdate(menu); container.style.width = '150px'; - await onceResized(menu); + await nextResize(menu); buttons.forEach((btn) => { expect(btn.disabled).to.be.true; }); @@ -402,7 +381,7 @@ describe('overflow', () => { describe('container', () => { beforeEach(async () => { container.append(text, menu); - await onceResized(menu); + await nextResize(menu); buttons = menu._buttons; }); @@ -411,7 +390,7 @@ describe('overflow', () => { assertHidden(buttons[3]); container.style.maxWidth = '400px'; - await onceResized(menu); + await nextResize(menu); assertVisible(buttons[2]); assertVisible(buttons[3]); @@ -425,7 +404,7 @@ describe('overflow', () => { other.append(text, menu); other.style.maxWidth = '400px'; - await onceResized(menu); + await nextResize(menu); assertVisible(buttons[2]); assertVisible(buttons[3]); @@ -436,7 +415,7 @@ describe('overflow', () => { beforeEach(async () => { container.attachShadow({ mode: 'open' }); container.shadowRoot.append(text, menu); - await onceResized(menu); + await nextResize(menu); buttons = menu._buttons; }); @@ -445,7 +424,7 @@ describe('overflow', () => { assertHidden(buttons[3]); container.style.maxWidth = '400px'; - await onceResized(menu); + await nextResize(menu); assertVisible(buttons[2]); assertVisible(buttons[3]); @@ -479,14 +458,14 @@ describe('overflow', () => { subMenu = menu._subMenu; menu.style.width = '250px'; - await onceResized(menu); + await nextResize(menu); }); it('should close the overflow sub-menu on menu-bar resize', async () => { overflow.click(); await nextRender(subMenu); menu.style.width = 'auto'; - await onceResized(menu); + await nextResize(menu); expect(subMenu.opened).to.be.false; }); @@ -509,7 +488,7 @@ describe('overflow', () => { subMenu.close(); await nextUpdate(menu); menu.style.width = 'auto'; - await onceResized(menu); + await nextResize(menu); const item = buttons[2].firstChild; expect(item).to.equal(buttons[2].item.component); expect(item.getAttribute('role')).to.not.equal('menuitem'); @@ -523,7 +502,7 @@ describe('overflow', () => { subMenu.close(); await nextUpdate(menu); menu.style.width = 'auto'; - await onceResized(menu); + await nextResize(menu); expect(item.getAttributeNames()).to.have.members(itemAttributes); }); @@ -536,7 +515,7 @@ describe('overflow', () => { subMenu.close(); await nextUpdate(menu); menu.style.width = 'auto'; - await onceResized(menu); + await nextResize(menu); expect(item.classList.contains('test-class-1')).to.be.true; }); }); diff --git a/packages/multi-select-combo-box/test/chips.common.js b/packages/multi-select-combo-box/test/chips.common.js index 6ac4e05db4..019ea74103 100644 --- a/packages/multi-select-combo-box/test/chips.common.js +++ b/packages/multi-select-combo-box/test/chips.common.js @@ -1,5 +1,5 @@ import { expect } from '@vaadin/chai-plugins'; -import { fixtureSync, nextRender, nextUpdate } from '@vaadin/testing-helpers'; +import { fixtureSync, nextRender, nextResize, nextUpdate } from '@vaadin/testing-helpers'; import { sendKeys } from '@web/test-runner-commands'; describe('chips', () => { @@ -9,12 +9,6 @@ describe('chips', () => { const getChipContent = (chip) => chip.shadowRoot.querySelector('[part="label"]').textContent; - const nextResize = (target) => { - return new Promise((resolve) => { - new ResizeObserver(() => setTimeout(resolve)).observe(target); - }); - }; - beforeEach(async () => { comboBox = fixtureSync(``); comboBox.items = ['apple', 'banana', 'lemon', 'orange']; diff --git a/packages/tabs/test/tabs.common.js b/packages/tabs/test/tabs.common.js index 457ecd9ad7..22ad556d26 100644 --- a/packages/tabs/test/tabs.common.js +++ b/packages/tabs/test/tabs.common.js @@ -7,30 +7,11 @@ import { listenOnce, nextFrame, nextRender, + nextResize, space, } from '@vaadin/testing-helpers'; import sinon from 'sinon'; -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName) { - return new Promise((resolve) => { - sinon.replace(object, functionName, (...args) => { - sinon.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -/** - * Resolves once the ResizeObserver has processed a resize. - */ -async function onceResized(tabs) { - await onceInvoked(tabs, '_updateOverflow'); -} - describe('tabs', () => { let tabs; @@ -120,7 +101,7 @@ describe('tabs', () => { } else { tabs.style.height = '100px'; } - await onceResized(tabs); + await nextResize(tabs); await nextFrame(); }); @@ -182,7 +163,7 @@ describe('tabs', () => { it('should update overflow on resize', async () => { tabs.style.width = 'auto'; tabs.style.height = 'auto'; - await onceResized(tabs); + await nextResize(tabs); expect(tabs.hasAttribute('overflow')).to.be.false; }); @@ -193,7 +174,7 @@ describe('tabs', () => { item.style.minHeight = '1px'; item.style.minWidth = '1px'; }); - await onceResized(tabs); + await nextResize(tabs); expect(tabs.hasAttribute('overflow')).to.be.false; }); diff --git a/packages/text-area/test/text-area.common.js b/packages/text-area/test/text-area.common.js index 403916806b..19d6d6cfc5 100644 --- a/packages/text-area/test/text-area.common.js +++ b/packages/text-area/test/text-area.common.js @@ -1,27 +1,7 @@ import { expect } from '@vaadin/chai-plugins'; -import { fire, fixtureSync, nextFrame, nextRender, nextUpdate, oneEvent } from '@vaadin/testing-helpers'; +import { fire, fixtureSync, nextFrame, nextRender, nextResize, nextUpdate, oneEvent } from '@vaadin/testing-helpers'; import sinon from 'sinon'; -/** - * Resolves once the function is invoked on the given object. - */ -function onceInvoked(object, functionName) { - return new Promise((resolve) => { - sinon.replace(object, functionName, (...args) => { - sinon.restore(); - object[functionName](...args); - resolve(); - }); - }); -} - -/** - * Resolves once the ResizeObserver has processed a resize. - */ -async function onceResized(element) { - await onceInvoked(element, '_onResize'); -} - describe('text-area', () => { let textArea; @@ -303,7 +283,7 @@ describe('text-area', () => { // Decrease the width textArea.style.width = '400px'; - await onceResized(textArea); + await nextResize(textArea); // Expect the height to have increased expect(textArea.offsetHeight).to.be.above(height);