Tooltip can have different transition styles, which may be overridden by changing `transitionStyle`.
From b883cb315a3c841c4d58a5094ff94f3ec9da6633 Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Wed, 22 Feb 2023 17:40:32 +0700
Subject: [PATCH 02/16] fix(tooltip): add native ResizeObserver detection and
polyfill fallback
---
packages/core/src/elements/ResponsiveElement.ts | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/packages/core/src/elements/ResponsiveElement.ts b/packages/core/src/elements/ResponsiveElement.ts
index e6bb324c07..3c34094f4a 100644
--- a/packages/core/src/elements/ResponsiveElement.ts
+++ b/packages/core/src/elements/ResponsiveElement.ts
@@ -1,5 +1,6 @@
import { BasicElement } from './BasicElement.js';
-import { ResizeObserver, ResizeObserverEntry } from '@juggle/resize-observer';
+// If ResizeObserver native API works fine, this package should be removed in future
+import { ResizeObserver as PolyfillResizeObserver } from '@juggle/resize-observer';
export type ElementSize = {
width: number;
@@ -48,13 +49,21 @@ const triggerResize = (entry: ResizeObserverEntry): void => {
entry.target.dispatchEvent(event);
};
+/**
+ * Trigger Resize all entries from ResizeObserver
+ * @param entries array of ResizeObserverEntry
+ * @returns {void}
+ */
+const entriesResize = (entries: ResizeObserverEntry[]): void => {
+ entries.forEach(entry => triggerResize(entry));
+};
+
/**
* Global resize observer,
* used to watch changes in element dimensions
*/
-const resizeObserver = new ResizeObserver(entries => {
- entries.forEach(entry => triggerResize(entry));
-});
+const resizeObserver = typeof ResizeObserver === 'function' ? new ResizeObserver(entriesResize) : new PolyfillResizeObserver(entriesResize);
+
/**
* Responsive element base class.
From 272b499ec2d65977cb0a3e0667b95140c2c2d28a Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Thu, 16 Mar 2023 15:57:39 +0700
Subject: [PATCH 03/16] feat(test-helpers): add frame count param to nextFrame
& inNear util
---
.../__test__/test-helpers.test.js | 54 ++++++++++++++++++-
packages/test-helpers/src/test-helpers.ts | 33 +++++++++++-
2 files changed, 85 insertions(+), 2 deletions(-)
diff --git a/packages/test-helpers/__test__/test-helpers.test.js b/packages/test-helpers/__test__/test-helpers.test.js
index 32a2e6416b..43e93758e6 100644
--- a/packages/test-helpers/__test__/test-helpers.test.js
+++ b/packages/test-helpers/__test__/test-helpers.test.js
@@ -1,4 +1,5 @@
-import { fixture, expect, keyboardEvent, oneEvent } from '../lib/test-helpers';
+import { fixture, expect, keyboardEvent, oneEvent, isNear, nextFrame } from '../lib/test-helpers';
+import { createSandbox } from 'sinon';
describe('TestHelpersTest', () => {
@@ -48,4 +49,55 @@ describe('TestHelpersTest', () => {
});
});
+ describe('Test nextFrame helper', () => {
+ const sandbox = createSandbox();
+
+ beforeEach(async () => {
+ sandbox.spy(window, "requestAnimationFrame");
+ });
+
+ afterEach(() => {
+ sandbox.restore();
+ });
+
+ it('Calling nextFrame without param', async () => {
+ await nextFrame();
+ expect(window.requestAnimationFrame.calledOnce).to.equal(true, 'requestAnimationFrame should be called once');
+ });
+ it('Calling nextFrame with 1 as param', async () => {
+ await nextFrame(1);
+ expect(window.requestAnimationFrame.calledOnce).to.equal(true, 'requestAnimationFrame should be called once');
+ });
+ it('Calling nextFrame with 2 as param', async () => {
+ await nextFrame(2);
+ expect(window.requestAnimationFrame.calledTwice).to.equal(true, 'requestAnimationFrame should be called twice');
+ });
+ });
+
+ describe('Test isNear helper', () => {
+ it('Calling isNear with numbers & distance', async () => {
+ expect(isNear(10, 10, 0)).to.equal(true, 'isNear at boundary distance of 0 should be true');
+ expect(isNear(10, 10.1, 0)).to.equal(false, 'isNear beyond boundary distance of 0 should be false');
+ expect(isNear(10, 14.9, 5)).to.equal(true, 'isNear within boundary distance greater than 0 should be true');
+ expect(isNear(10, 15, 5)).to.equal(true, 'isNear at boundary distance greater than 0 should be true');
+ expect(isNear(10, 15.1, 5)).to.equal(false, 'isNear beyond boundary distance greater than 0 should be true');
+ });
+
+ it('Calling isNear with numbers, distance & inclusive as true', async () => {
+ expect(isNear(10, 10, 0, true)).to.equal(true, 'isNear at boundary distance of 0 should be true');
+ expect(isNear(10, 10.1, 0, true)).to.equal(false, 'isNear beyond boundary distance of 0 should be false');
+ expect(isNear(10, 14.9, 5, true)).to.equal(true, 'isNear within boundary distance greater than 0 should be true');
+ expect(isNear(10, 15, 5, true)).to.equal(true, 'isNear at boundary distance greater than 0 should be true');
+ expect(isNear(10, 15.1, 5, true)).to.equal(false, 'isNear beyond boundary distance greater than 0 should be true');
+ });
+
+ it('Calling isNear with numbers, distance & inclusive as false', async () => {
+ expect(isNear(10, 10, 0, false)).to.equal(true, 'isNear at boundary distance of 0 should be true');
+ expect(isNear(10, 10.1, 0, false)).to.equal(false, 'isNear beyond boundary distance of 0 should be false');
+ expect(isNear(10, 14.9, 5, false)).to.equal(true, 'isNear within boundary distance greater than 0 should be true');
+ expect(isNear(10, 15, 5, false)).to.equal(false, 'isNear at boundary distance greater than 0 should be true');
+ expect(isNear(10, 15.1, 5, false)).to.equal(false, 'isNear beyond boundary distance greater than 0 should be true');
+ });
+ });
+
});
diff --git a/packages/test-helpers/src/test-helpers.ts b/packages/test-helpers/src/test-helpers.ts
index c2b1672bbe..717e510508 100644
--- a/packages/test-helpers/src/test-helpers.ts
+++ b/packages/test-helpers/src/test-helpers.ts
@@ -14,7 +14,6 @@ export {
defineCE,
aTimeout,
waitUntil,
- nextFrame,
litFixture,
litFixtureSync,
fixture,
@@ -22,6 +21,7 @@ export {
fixtureCleanup,
elementUpdated
} from '@open-wc/testing';
+import { nextFrame as _nextFrame } from '@open-wc/testing';
export interface CustomKeyboardEvent extends CustomEvent {
key: string;
@@ -56,3 +56,34 @@ export const keyboardEvent = (type: string, init: KeyboardEventInit = {}): Keybo
return event;
};
+
+/**
+ * Resolves after requestAnimationFrame.
+ * @param [frameCount = 1] number of animationFrame to be requested
+ *
+ * @returns {Promise} Promise that resolved after requestAnimationFrame
+ */
+export const nextFrame = async (frameCount = 1): Promise => {
+ for (let i = 0; i < frameCount; i++) {
+ await _nextFrame();
+ }
+};
+
+/**
+ * Check value difference between 2 number.
+ * If it's within `distance` value, they are near.
+ * @param a 1 of the 2 numbers to be checked
+ * @param b 1 of the 2 numbers to be checked
+ * @param distance maximum value difference of `a` & `b` to be considered near, must equal or greater than 0
+ * @param [inclusive = true] `true`: value difference must be smaller or equal to `distance` , `false`: value difference must be smaller than `distance`
+ * If `distance` is 0, inclusive would be overwritten as `true`.
+ *
+ * @returns {boolean} equality result
+ */
+export const isNear = (a: number, b: number, distance: number, inclusive = true): boolean => {
+ if (distance === 0) {
+ inclusive = true;
+ }
+ const diff = Math.abs(a - b);
+ return inclusive ? diff <= distance : diff < distance;
+};
From 029443f86bd655f5bb2770bf512650834a805372 Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Thu, 16 Mar 2023 15:59:31 +0700
Subject: [PATCH 04/16] test(canvas): add wait another frame
---
packages/elements/src/canvas/__test__/canvas.test.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/packages/elements/src/canvas/__test__/canvas.test.js b/packages/elements/src/canvas/__test__/canvas.test.js
index 562d863871..292b3254ba 100644
--- a/packages/elements/src/canvas/__test__/canvas.test.js
+++ b/packages/elements/src/canvas/__test__/canvas.test.js
@@ -45,7 +45,7 @@ describe('canvas/Canvas', () => {
Object.defineProperty(window, 'devicePixelRatio', {
value: null
});
- await nextFrame();
+ await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete canvas rendering
expect(el.canvas.width).equal(Math.floor(el.width * dpr));
expect(el.canvas.height).equal(Math.floor(el.height * dpr));
});
@@ -55,7 +55,7 @@ describe('canvas/Canvas', () => {
Object.defineProperty(window, 'devicePixelRatio', {
value: 3
});
- await nextFrame();
+ await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete canvas rendering
expect(el.canvas.width).equal(Math.floor(el.width * devicePixelRatio));
expect(el.canvas.height).equal(Math.floor(el.height * devicePixelRatio));
Object.defineProperty(window, 'devicePixelRatio', {
@@ -70,7 +70,7 @@ describe('canvas/Canvas', () => {
it('Handles fractional pixelation', async () => {
el.style.width = '300.5px';
- await elementUpdated();
+ await elementUpdated(el);
const listener = function () {
el.removeEventListener('resize', listener);
expect(el.style.width, 'ef-canvas\'s width should be fractional').equal('300.5px');
From 0688252e6e52c6e9559cde1773dc40a5bc110a11 Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Thu, 16 Mar 2023 17:24:41 +0700
Subject: [PATCH 05/16] test: fix incorrect param of nextFrame
---
packages/elements/src/datetime-field/__test__/utils.js | 2 +-
packages/elements/src/select/__test__/select.events.test.js | 2 +-
packages/translate/__test__/elf-translate-element.test.js | 6 +++---
packages/translate/__test__/elf-translate.navigator.test.js | 4 ++--
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/packages/elements/src/datetime-field/__test__/utils.js b/packages/elements/src/datetime-field/__test__/utils.js
index 826620bb12..8f366b6414 100644
--- a/packages/elements/src/datetime-field/__test__/utils.js
+++ b/packages/elements/src/datetime-field/__test__/utils.js
@@ -4,7 +4,7 @@ const inputValue = (el) => el.inputValue; // Access private property
const inputElement = (el) => el.inputElement; // Access private property
const focusInput = async (el) => {
await triggerFocusFor(inputElement(el));
- await nextFrame(el);
+ await nextFrame();
};
const arrowRight = async (el) => {
diff --git a/packages/elements/src/select/__test__/select.events.test.js b/packages/elements/src/select/__test__/select.events.test.js
index c76441ef7d..5f5c921771 100644
--- a/packages/elements/src/select/__test__/select.events.test.js
+++ b/packages/elements/src/select/__test__/select.events.test.js
@@ -110,7 +110,7 @@ describe('select/Events', () => {
it('opened-changed event on keyboard pressed', async () => {
const el = await fixture(`${getOptions()}`);
el.focus();
- await nextFrame(el);
+ await nextFrame();
let counter = 0;
let opened = false;
diff --git a/packages/translate/__test__/elf-translate-element.test.js b/packages/translate/__test__/elf-translate-element.test.js
index 3017ba5904..0538472864 100644
--- a/packages/translate/__test__/elf-translate-element.test.js
+++ b/packages/translate/__test__/elf-translate-element.test.js
@@ -47,7 +47,7 @@ describe('Elf Translate Element Lang Test', () => {
expect(el.defaultEl.innerText).to.equal('Региональные настройки: ru');
el.lang = 'en';
await elementUpdated(el);
- await nextFrame(el); // need for IE11
+ await nextFrame(); // need for IE11
expect(el.defaultEl.innerText).to.equal('This is en locale');
});
@@ -56,11 +56,11 @@ describe('Elf Translate Element Lang Test', () => {
expect(el.numberEl.innerText).to.equal('Long number: 0');
el.number = 1000;
await elementUpdated(el);
- await nextFrame(el);
+ await nextFrame();
expect(el.numberEl.innerText).to.equal('Long number: 1,000');
el.number = 1000000;
await elementUpdated(el);
- await nextFrame(el);
+ await nextFrame();
expect(el.numberEl.innerText).to.equal('Long number: 1,000,000');
});
diff --git a/packages/translate/__test__/elf-translate.navigator.test.js b/packages/translate/__test__/elf-translate.navigator.test.js
index 42460baf66..f56bcc8f07 100644
--- a/packages/translate/__test__/elf-translate.navigator.test.js
+++ b/packages/translate/__test__/elf-translate.navigator.test.js
@@ -20,13 +20,13 @@ describe('Elf Translate Navigator Test', () => {
}
document.documentElement.lang = 'en-US';
- await nextFrame(el);
+ await nextFrame();
expect(el.defaultEl.innerText).to.equal('This is en-US locale', 'Document locale should take priority over navigator');
el.lang = 'en-GB';
await elementUpdated(el);
- await nextFrame(el); // need for IE11
+ await nextFrame(); // need for IE11
expect(el.defaultEl.innerText).to.equal('This is en locale', 'Element locale should take priority over document locale');
});
});
From 79d5f2e73099bed051d6bd64318ce1691b1fcebd Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Thu, 16 Mar 2023 17:48:26 +0700
Subject: [PATCH 06/16] test(clock): wait one more frame to complete rendering
---
.../src/clock/__test__/clock.analogue.test.js | 12 ++++++------
packages/elements/src/clock/__test__/clock.test.js | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/packages/elements/src/clock/__test__/clock.analogue.test.js b/packages/elements/src/clock/__test__/clock.analogue.test.js
index ad305b48cf..e165b8ebe8 100644
--- a/packages/elements/src/clock/__test__/clock.analogue.test.js
+++ b/packages/elements/src/clock/__test__/clock.analogue.test.js
@@ -48,11 +48,11 @@ describe('clock/Analogue', () => {
it('Shows small size clock when width is less than 130px', async () => {
expect(el.shadowRoot.querySelector('[part="digital"]'), 'digital clock should display inside a default analog clock').not.to.be.null;
-
+
// make size smaller than defined break point
el.style.width = '129px';
await elementUpdated(el);
- await nextFrame();
+ await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete rendering
expect(el.shadowRoot.querySelector('[part="digital"]'), 'digital clock should not display inside small clock').to.be.null;
expect(el.amPm, 'am-pm should be hidden by default on small clock').to.be.equal(false);
@@ -63,18 +63,18 @@ describe('clock/Analogue', () => {
el.style.width = '129px';
await elementUpdated(el);
await nextFrame();
-
+
// test default behavior
expect(el.hasAttribute('am-pm')).to.be.equal(false);
expect(el.amPm).to.be.equal(false);
expect(el.shadowRoot.querySelector('[part="segment am-pm"]')).to.be.null;
-
+
// test when it has am-pm attribute
el = await fixture('');
el.style.width = '129px';
await elementUpdated(el);
await nextFrame();
-
+
expect(el.amPm, 'amPm property should be true if am-pm attribute is set').to.be.equal(true);
expect(el.shadowRoot.querySelector('[part="segment am-pm"]'), 'AM/PM should display on clock').not.to.be.null;
@@ -92,7 +92,7 @@ describe('clock/Analogue', () => {
await nextFrame();
expect(el.hasAttribute('size'), 'size attribute should not show if not analog').to.be.equal(false);
-
+
el.style.width = '129px';
await elementUpdated(el);
await nextFrame();
diff --git a/packages/elements/src/clock/__test__/clock.test.js b/packages/elements/src/clock/__test__/clock.test.js
index 2dbc0ac110..dca0ce0c0d 100644
--- a/packages/elements/src/clock/__test__/clock.test.js
+++ b/packages/elements/src/clock/__test__/clock.test.js
@@ -25,7 +25,7 @@ describe('clock/Clock', () => {
el = await fixture('');
el.style.width = '129px';
await elementUpdated(el);
- await nextFrame();
+ await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete rendering
expect(el).shadowDom.to.equalSnapshot();
});
From 62a91e25e6789d10157c31f4b9087eb8b3264d86 Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Thu, 16 Mar 2023 17:53:32 +0700
Subject: [PATCH 07/16] test(interactive-chart): add wait for element update &
a few more frames
---
.../__test__/interactive-chart.test.js | 36 ++++++++++---------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/packages/elements/src/interactive-chart/__test__/interactive-chart.test.js b/packages/elements/src/interactive-chart/__test__/interactive-chart.test.js
index 6998d1dc85..7ac5088005 100644
--- a/packages/elements/src/interactive-chart/__test__/interactive-chart.test.js
+++ b/packages/elements/src/interactive-chart/__test__/interactive-chart.test.js
@@ -833,8 +833,8 @@ describe('interactive-chart/InteractiveChart', () => {
it('Should has dynamic left position in legend when the chart set y axis at left', async () => {
el.config = linePositionLeft;
- await elementUpdated();
- await nextFrame();
+ await elementUpdated(el);
+ await nextFrame(3); // Chrome 111 & Firefox 111 requires 3 frames to complete rendering
expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
@@ -846,8 +846,8 @@ describe('interactive-chart/InteractiveChart', () => {
it('Should has dynamic left position in legend when the chart set y axis at both edge', async () => {
el.config = twoPriceScales;
- await elementUpdated();
- await nextFrame();
+ await elementUpdated(el);
+ await nextFrame(3); // Chrome 111 & Firefox 111 requires 3 frames to complete rendering
expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
@@ -859,8 +859,8 @@ describe('interactive-chart/InteractiveChart', () => {
it('Should has fixed left position in legend when the chart set y axis at right edge', async () => {
el.config = line;
- await elementUpdated();
- await nextFrame();
+ await elementUpdated(el);
+ await nextFrame(3); // Chrome 111 & Firefox 111 requires 3 frames to complete rendering
expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
@@ -873,32 +873,36 @@ describe('interactive-chart/InteractiveChart', () => {
describe('Test deprecated attribute', () => {
it('Switch attribute legendstyle horizontal to vertical, it should display vertical style', async () => {
el = await fixture('');
-
+
el.config = line;
- await elementUpdated();
+ await elementUpdated(el);
+ await nextFrame(2); // Chrome 111 & Firefox 111 requires 2 frames to complete rendering
+
expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
-
+
el.setAttribute('legendstyle','vertical');
-
+
await nextFrame();
- await elementUpdated();
+ await elementUpdated(el);
expect(el.getAttribute('legend-style')).to.null;
expect(el.shadowRoot.querySelector('[part=legend]').className).to.not.include('horizontal');
});
it('Set legend-style to vertical when legendstyle horizontal, it should display vertical style', async () => {
el = await fixture('');
-
+
el.config = line;
- await elementUpdated();
+ await elementUpdated(el);
+ await nextFrame(2); // Chrome 111 & Firefox 111 requires 2 frames to complete rendering
+
expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
expect(el.getAttribute('legendstyle')).to.equal('horizontal');
-
+
el.setAttribute('legend-style','vertical');
-
+
await nextFrame();
- await elementUpdated();
+ await elementUpdated(el);
expect(el.shadowRoot.querySelector('[part=legend]').className).to.not.include('horizontal');
});
});
From 248f30b2f3b85d1c331595dc48160d8ca1478fe8 Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Thu, 16 Mar 2023 18:02:31 +0700
Subject: [PATCH 08/16] test(tab-bar): wait a frame for rendering
---
.../elements/src/tab-bar/__test__/tab-bar.template.test.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/packages/elements/src/tab-bar/__test__/tab-bar.template.test.js b/packages/elements/src/tab-bar/__test__/tab-bar.template.test.js
index c4f9da444d..4fa769c30c 100644
--- a/packages/elements/src/tab-bar/__test__/tab-bar.template.test.js
+++ b/packages/elements/src/tab-bar/__test__/tab-bar.template.test.js
@@ -1,4 +1,4 @@
-import { fixture, expect, elementUpdated, aTimeout } from '@refinitiv-ui/test-helpers';
+import { fixture, expect, elementUpdated, aTimeout, nextFrame } from '@refinitiv-ui/test-helpers';
import '@refinitiv-ui/elements/tab-bar';
import '@refinitiv-ui/elemental-theme/light/ef-tab-bar';
@@ -100,6 +100,7 @@ describe('tab-bar/TabBar', () => {
});
it('Should show only right scroll button', async () => {
+ await nextFrame(); // wait for rendering
expect(getElementStyle(leftScrollBtn, 'display')).equal('none');
expect(getElementStyle(rightScrollBtn, 'display')).equal('flex');
});
From e83801947137c32ff7c0100d60939fdd70adf17a Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Thu, 16 Mar 2023 18:04:04 +0700
Subject: [PATCH 09/16] test(tree-select): wait for element update
---
.../src/tree-select/__test__/tree-select.interaction.test.js | 2 +-
packages/elements/src/tree-select/__test__/utils.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/elements/src/tree-select/__test__/tree-select.interaction.test.js b/packages/elements/src/tree-select/__test__/tree-select.interaction.test.js
index 38d25f8b4a..02c9fa6ff4 100644
--- a/packages/elements/src/tree-select/__test__/tree-select.interaction.test.js
+++ b/packages/elements/src/tree-select/__test__/tree-select.interaction.test.js
@@ -153,7 +153,7 @@ describe('tree-select/Interaction', () => {
el.data = flatData;
el.opened = true;
changeItemSelection(el, flatSelection);
- await nextFrame();
+ await openedUpdated(el);
const elementToRemove = [...el.shadowRoot.querySelectorAll('ef-pill')].find(el => el.value === itemToRemove.value); // Austria
elementToRemove.dispatchEvent(new CustomEvent('clear', {
detail: {
diff --git a/packages/elements/src/tree-select/__test__/utils.js b/packages/elements/src/tree-select/__test__/utils.js
index 5c9823ee81..34860b84e0 100644
--- a/packages/elements/src/tree-select/__test__/utils.js
+++ b/packages/elements/src/tree-select/__test__/utils.js
@@ -3,7 +3,7 @@ import { elementUpdated, expect, nextFrame } from '@refinitiv-ui/test-helpers';
/**
* Cross browser function to wait while select element becomes opened/closed and resized
* @param {TreeSelect} el Tree select
- * @returns {void}
+ * @returns {Promise}
*/
export const openedUpdated = async (el) => {
await elementUpdated(el);
From 2af85d54a5719d3c24de0ad17d308e934e2777c5 Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Thu, 16 Mar 2023 18:07:49 +0700
Subject: [PATCH 10/16] test(sparkline): wait for element update & a few more
frame to complete rendering
---
packages/elements/src/sparkline/__test__/sparkline.test.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/packages/elements/src/sparkline/__test__/sparkline.test.js b/packages/elements/src/sparkline/__test__/sparkline.test.js
index e5e8500a42..040cdc72e0 100644
--- a/packages/elements/src/sparkline/__test__/sparkline.test.js
+++ b/packages/elements/src/sparkline/__test__/sparkline.test.js
@@ -1,4 +1,4 @@
-import { fixture, expect, elementUpdated } from '@refinitiv-ui/test-helpers';
+import { fixture, expect, elementUpdated, nextFrame } from '@refinitiv-ui/test-helpers';
// import element and theme
import '@refinitiv-ui/elements/sparkline';
@@ -75,7 +75,8 @@ describe('sparkline/Sparkline', () => {
expect(isCanvasBlank(canvas)).to.be.true;
el.data = data;
- await elementUpdated();
+ await elementUpdated(el);
+ await nextFrame(3); // ensure that the rendering's completed
expect(countDataChanged).to.equal(1);
expect(countDataError).to.equal(0);
expect(isCanvasBlank(canvas)).to.be.false;
From 5441b80d1749de3da5e59b73d5f6741bfde2ea5d Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Fri, 17 Mar 2023 09:23:19 +0700
Subject: [PATCH 11/16] test(led-gauge): fix waiting for element update
---
.../src/led-gauge/__test__/led-gauge.test.js | 26 +++++++++----------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/packages/elements/src/led-gauge/__test__/led-gauge.test.js b/packages/elements/src/led-gauge/__test__/led-gauge.test.js
index 9bdb16b575..43768c5afd 100644
--- a/packages/elements/src/led-gauge/__test__/led-gauge.test.js
+++ b/packages/elements/src/led-gauge/__test__/led-gauge.test.js
@@ -56,7 +56,7 @@ describe('led-gauge/LedGauge', () => {
el.setAttribute('top-label', 'NewTopLabel');
el.setAttribute('bottom-label', 'NewBottomLabel');
- await elementUpdated();
+ await elementUpdated(el);
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');
@@ -72,7 +72,7 @@ describe('led-gauge/LedGauge', () => {
el.topLabel = 'NewTopLabel';
el.bottomLabel = 'NewBottomLabel';
- await elementUpdated();
+ await elementUpdated(el);
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');
@@ -87,7 +87,7 @@ describe('led-gauge/LedGauge', () => {
el.removeAttribute('top-label');
el.removeAttribute('bottom-label');
- await elementUpdated();
+ await elementUpdated(el);
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');
@@ -111,7 +111,7 @@ describe('led-gauge/LedGauge', () => {
it('Should be able to set topValue and bottomValue via property', async () => {
const el = await fixture(full);
- await nextFrame();
+ await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete rendering
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');
let topTextPos = parseInt(window.getComputedStyle(top).getPropertyValue('left'), 10);
@@ -122,7 +122,7 @@ describe('led-gauge/LedGauge', () => {
el.topValue = 50;
el.bottomValue = -50;
- await elementUpdated();
+ await elementUpdated(el);
let newTopTextPos = parseInt(window.getComputedStyle(top).getPropertyValue('left'), 10);
let newBottomTextPos = parseInt(window.getComputedStyle(bottom).getPropertyValue('left'), 10);
@@ -133,7 +133,7 @@ describe('led-gauge/LedGauge', () => {
it('Should be able to set topValue and bottomValue via attribute', async () => {
const el = await fixture(full);
- await nextFrame();
+ await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete rendering
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');
let topTextPos = parseInt(window.getComputedStyle(top).getPropertyValue('left'), 10);
@@ -144,7 +144,7 @@ describe('led-gauge/LedGauge', () => {
el.setAttribute('top-value', '50');
el.setAttribute('bottom-value', '-50');
- await elementUpdated();
+ await elementUpdated(el);
let newTopTextPos = parseInt(window.getComputedStyle(top).getPropertyValue('left'), 10);
let newBottomTextPos = parseInt(window.getComputedStyle(bottom).getPropertyValue('left'), 10);
@@ -161,7 +161,7 @@ describe('led-gauge/LedGauge', () => {
it('Should update range label when range-label changed by attribute', async () => {
const el = await fixture(rangeFixture);
el.setAttribute('range-label', 'NewRangeLabel');
- await elementUpdated();
+ await elementUpdated(el);
range = el.shadowRoot.querySelector('#range');
expect(range).to.not.equal(null);
@@ -171,7 +171,7 @@ describe('led-gauge/LedGauge', () => {
it('Should update range label when range-label changed by property', async () => {
const el = await fixture(rangeFixture);
el.rangeLabel = 'NewRangeLabel';
- await elementUpdated();
+ await elementUpdated(el);
range = el.shadowRoot.querySelector('#range');
expect(range).to.not.equal(null);
@@ -186,7 +186,7 @@ describe('led-gauge/LedGauge', () => {
expect(range).to.not.equal(null);
el.setAttribute('bottom-label', 'Bottom Text');
- await elementUpdated();
+ await elementUpdated(el);
expect(bottom).to.equal(null);
expect(range).to.not.equal(null);
});
@@ -200,20 +200,20 @@ describe('led-gauge/LedGauge', () => {
it('Should have min=0 and max=100 when set zero=left by property', async () => {
const el = await fixture(zero);
el.zero = 'left';
- await elementUpdated();
+ await elementUpdated(el);
expect(el.zero).to.equal('left');
});
it('Should set zero to center when invalid value is set', async () => {
const el = await fixture(zero);
el.zero = 'left';
- await elementUpdated();
+ await elementUpdated(el);
expect(el.zero).to.equal('left');
expect(el.min).to.equal(0);
expect(el.max).to.equal(100);
el.zero = 'invalid';
- await elementUpdated();
+ await elementUpdated(el);
expect(el.zero).to.equal('center');
expect(el.min).to.equal(-100);
expect(el.max).to.equal(100);
From 24aabd7c2636a7cf51176b268c96c35360aa8087 Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Fri, 17 Mar 2023 09:35:19 +0700
Subject: [PATCH 12/16] test(tornado-chart): fix waiting for element update
---
.../elements/src/tornado-chart/__test__/tornado-chart.test.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/elements/src/tornado-chart/__test__/tornado-chart.test.js b/packages/elements/src/tornado-chart/__test__/tornado-chart.test.js
index 56e788efa1..b07c2d5be5 100644
--- a/packages/elements/src/tornado-chart/__test__/tornado-chart.test.js
+++ b/packages/elements/src/tornado-chart/__test__/tornado-chart.test.js
@@ -48,7 +48,7 @@ describe('tornado-chart/TornadoChart', () => {
const legend = element.shadowRoot.querySelector('[part="legend"]');
await oneEvent(element, 'resize');
- await elementUpdated();
+ await elementUpdated(element);
expect(legend.hasAttribute('vertical')).to.equal(true);
});
@@ -62,7 +62,7 @@ describe('tornado-chart/TornadoChart', () => {
);
await oneEvent(element, 'resize');
- await elementUpdated();
+ await elementUpdated(element);
const items = element.querySelectorAll('ef-tornado-item');
items.forEach((item) => {
From acd1ad7587251d09abf3eedac4941a9fa8d3ba7c Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Fri, 17 Mar 2023 09:35:41 +0700
Subject: [PATCH 13/16] test(tornado-chart): align test file to naming
convention
---
.../__test__/{tornado-item.test.js => tornado-chart-item.test.js} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename packages/elements/src/tornado-chart/__test__/{tornado-item.test.js => tornado-chart-item.test.js} (100%)
diff --git a/packages/elements/src/tornado-chart/__test__/tornado-item.test.js b/packages/elements/src/tornado-chart/__test__/tornado-chart-item.test.js
similarity index 100%
rename from packages/elements/src/tornado-chart/__test__/tornado-item.test.js
rename to packages/elements/src/tornado-chart/__test__/tornado-chart-item.test.js
From 012212518dd2d995f09bda3c42dfed1fae451fd5 Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Fri, 17 Mar 2023 10:01:39 +0700
Subject: [PATCH 14/16] test(test-helpers): add unit test for replaceWhitespace
util
---
packages/test-helpers/__test__/test-helpers.test.js | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/packages/test-helpers/__test__/test-helpers.test.js b/packages/test-helpers/__test__/test-helpers.test.js
index 43e93758e6..bca94d8c70 100644
--- a/packages/test-helpers/__test__/test-helpers.test.js
+++ b/packages/test-helpers/__test__/test-helpers.test.js
@@ -1,4 +1,4 @@
-import { fixture, expect, keyboardEvent, oneEvent, isNear, nextFrame } from '../lib/test-helpers';
+import { fixture, expect, keyboardEvent, oneEvent, isNear, nextFrame, replaceWhitespace } from '../lib/test-helpers';
import { createSandbox } from 'sinon';
describe('TestHelpersTest', () => {
@@ -100,4 +100,12 @@ describe('TestHelpersTest', () => {
});
});
+ describe('Test Method helper', () => {
+ it('Replace spacial whitespace to normal whitespace correctly', () => {
+ // Remove whitespace character U+202F from Chrome 111 and U+00A0 from Safari
+ const specialWhitespace = ' ';
+ expect(replaceWhitespace(specialWhitespace)).to.equal(' ', 'Remove whitespace should work correctly');
+ });
+ });
+
});
From 8ace5fd7810e4f304a5beb92226270fcd3efdb3a Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Fri, 17 Mar 2023 10:03:26 +0700
Subject: [PATCH 15/16] refactor(test-helpers): combine import statement +
descope code coverage ignore
---
packages/test-helpers/src/test-helpers.ts | 32 +++++++++++------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/packages/test-helpers/src/test-helpers.ts b/packages/test-helpers/src/test-helpers.ts
index 6b5a643b2b..3a643772ea 100644
--- a/packages/test-helpers/src/test-helpers.ts
+++ b/packages/test-helpers/src/test-helpers.ts
@@ -1,5 +1,4 @@
-/* istanbul ignore file */
-import { isIE } from '@open-wc/testing';
+import { isIE, nextFrame as _nextFrame } from '@open-wc/testing';
export {
html,
@@ -21,7 +20,6 @@ export {
fixtureCleanup,
elementUpdated
} from '@open-wc/testing';
-import { nextFrame as _nextFrame } from '@open-wc/testing';
export interface CustomKeyboardEvent extends CustomEvent {
key: string;
@@ -38,23 +36,25 @@ export interface CustomKeyboardEvent extends CustomEvent {
* @returns {KeyboardEvent|CustomKeyboardEvent} keyboard event
*/
export const keyboardEvent = (type: string, init: KeyboardEventInit = {}): KeyboardEvent|CustomKeyboardEvent => {
+ /* istanbul ignore else */
if (!isIE()) {
return new KeyboardEvent(type, init);
}
+ else {
+ const event = new CustomEvent(type, {
+ detail: 0,
+ bubbles: true,
+ cancelable: true,
+ composed: true
+ }) as CustomKeyboardEvent;
+ event.key = init.key || '';
+ event.shiftKey = init.shiftKey || false;
+ event.altKey = init.altKey || false;
+ event.ctrlKey = init.ctrlKey || false;
+ event.metaKey = init.metaKey || false;
- const event = new CustomEvent(type, {
- detail: 0,
- bubbles: true,
- cancelable: true,
- composed: true
- }) as CustomKeyboardEvent;
- event.key = init.key || '';
- event.shiftKey = init.shiftKey || false;
- event.altKey = init.altKey || false;
- event.ctrlKey = init.ctrlKey || false;
- event.metaKey = init.metaKey || false;
-
- return event;
+ return event;
+ }
};
/**
From 043d737e72b8c53785e91aacfd9db3de52b1416b Mon Sep 17 00:00:00 2001
From: Wattachai Kanawitoon <117723407+wattachai-lseg@users.noreply.github.com>
Date: Tue, 21 Mar 2023 16:04:58 +0700
Subject: [PATCH 16/16] test: clarity nextFrame usage
---
packages/elements/src/canvas/__test__/canvas.test.js | 4 ++--
.../elements/src/clock/__test__/clock.analogue.test.js | 2 +-
packages/elements/src/clock/__test__/clock.test.js | 2 +-
.../__test__/interactive-chart.test.js | 10 +++++-----
.../elements/src/led-gauge/__test__/led-gauge.test.js | 4 ++--
.../elements/src/sparkline/__test__/sparkline.test.js | 2 +-
.../src/tab-bar/__test__/tab-bar.template.test.js | 2 +-
7 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/packages/elements/src/canvas/__test__/canvas.test.js b/packages/elements/src/canvas/__test__/canvas.test.js
index 292b3254ba..3b0e134ccc 100644
--- a/packages/elements/src/canvas/__test__/canvas.test.js
+++ b/packages/elements/src/canvas/__test__/canvas.test.js
@@ -45,7 +45,7 @@ describe('canvas/Canvas', () => {
Object.defineProperty(window, 'devicePixelRatio', {
value: null
});
- await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete canvas rendering
+ await nextFrame(2); // wait for resize observer & rendering completion
expect(el.canvas.width).equal(Math.floor(el.width * dpr));
expect(el.canvas.height).equal(Math.floor(el.height * dpr));
});
@@ -55,7 +55,7 @@ describe('canvas/Canvas', () => {
Object.defineProperty(window, 'devicePixelRatio', {
value: 3
});
- await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete canvas rendering
+ await nextFrame(2); // wait for resize observer & rendering completion
expect(el.canvas.width).equal(Math.floor(el.width * devicePixelRatio));
expect(el.canvas.height).equal(Math.floor(el.height * devicePixelRatio));
Object.defineProperty(window, 'devicePixelRatio', {
diff --git a/packages/elements/src/clock/__test__/clock.analogue.test.js b/packages/elements/src/clock/__test__/clock.analogue.test.js
index e165b8ebe8..fb10e2deb5 100644
--- a/packages/elements/src/clock/__test__/clock.analogue.test.js
+++ b/packages/elements/src/clock/__test__/clock.analogue.test.js
@@ -52,7 +52,7 @@ describe('clock/Analogue', () => {
// make size smaller than defined break point
el.style.width = '129px';
await elementUpdated(el);
- await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete rendering
+ await nextFrame(2); // wait for resize observer & rendering completion
expect(el.shadowRoot.querySelector('[part="digital"]'), 'digital clock should not display inside small clock').to.be.null;
expect(el.amPm, 'am-pm should be hidden by default on small clock').to.be.equal(false);
diff --git a/packages/elements/src/clock/__test__/clock.test.js b/packages/elements/src/clock/__test__/clock.test.js
index dca0ce0c0d..3a96b35e2b 100644
--- a/packages/elements/src/clock/__test__/clock.test.js
+++ b/packages/elements/src/clock/__test__/clock.test.js
@@ -25,7 +25,7 @@ describe('clock/Clock', () => {
el = await fixture('');
el.style.width = '129px';
await elementUpdated(el);
- await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete rendering
+ await nextFrame(2); // wait for resize observer & rendering completion
expect(el).shadowDom.to.equalSnapshot();
});
diff --git a/packages/elements/src/interactive-chart/__test__/interactive-chart.test.js b/packages/elements/src/interactive-chart/__test__/interactive-chart.test.js
index 7ac5088005..60b34fb05a 100644
--- a/packages/elements/src/interactive-chart/__test__/interactive-chart.test.js
+++ b/packages/elements/src/interactive-chart/__test__/interactive-chart.test.js
@@ -834,7 +834,7 @@ describe('interactive-chart/InteractiveChart', () => {
it('Should has dynamic left position in legend when the chart set y axis at left', async () => {
el.config = linePositionLeft;
await elementUpdated(el);
- await nextFrame(3); // Chrome 111 & Firefox 111 requires 3 frames to complete rendering
+ await nextFrame(3); // wait for resize observer & rendering completion
expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
@@ -847,7 +847,7 @@ describe('interactive-chart/InteractiveChart', () => {
it('Should has dynamic left position in legend when the chart set y axis at both edge', async () => {
el.config = twoPriceScales;
await elementUpdated(el);
- await nextFrame(3); // Chrome 111 & Firefox 111 requires 3 frames to complete rendering
+ await nextFrame(3); // wait for resize observer & rendering completion
expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
@@ -860,7 +860,7 @@ describe('interactive-chart/InteractiveChart', () => {
it('Should has fixed left position in legend when the chart set y axis at right edge', async () => {
el.config = line;
await elementUpdated(el);
- await nextFrame(3); // Chrome 111 & Firefox 111 requires 3 frames to complete rendering
+ await nextFrame(3); // wait for resize observer & rendering completion
expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
@@ -876,7 +876,7 @@ describe('interactive-chart/InteractiveChart', () => {
el.config = line;
await elementUpdated(el);
- await nextFrame(2); // Chrome 111 & Firefox 111 requires 2 frames to complete rendering
+ await nextFrame(2); // wait for resize observer & rendering completion
expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
@@ -893,7 +893,7 @@ describe('interactive-chart/InteractiveChart', () => {
el.config = line;
await elementUpdated(el);
- await nextFrame(2); // Chrome 111 & Firefox 111 requires 2 frames to complete rendering
+ await nextFrame(2); // wait for resize observer & rendering completion
expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
diff --git a/packages/elements/src/led-gauge/__test__/led-gauge.test.js b/packages/elements/src/led-gauge/__test__/led-gauge.test.js
index 43768c5afd..684ea23d29 100644
--- a/packages/elements/src/led-gauge/__test__/led-gauge.test.js
+++ b/packages/elements/src/led-gauge/__test__/led-gauge.test.js
@@ -111,7 +111,7 @@ describe('led-gauge/LedGauge', () => {
it('Should be able to set topValue and bottomValue via property', async () => {
const el = await fixture(full);
- await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete rendering
+ await nextFrame(2); // wait for resize observer & rendering completion
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');
let topTextPos = parseInt(window.getComputedStyle(top).getPropertyValue('left'), 10);
@@ -133,7 +133,7 @@ describe('led-gauge/LedGauge', () => {
it('Should be able to set topValue and bottomValue via attribute', async () => {
const el = await fixture(full);
- await nextFrame(2); // Chrome 111 & Firefox 111 needs another frame to complete rendering
+ await nextFrame(2); // wait for resize observer & rendering completion
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');
let topTextPos = parseInt(window.getComputedStyle(top).getPropertyValue('left'), 10);
diff --git a/packages/elements/src/sparkline/__test__/sparkline.test.js b/packages/elements/src/sparkline/__test__/sparkline.test.js
index 040cdc72e0..650cc41479 100644
--- a/packages/elements/src/sparkline/__test__/sparkline.test.js
+++ b/packages/elements/src/sparkline/__test__/sparkline.test.js
@@ -76,7 +76,7 @@ describe('sparkline/Sparkline', () => {
el.data = data;
await elementUpdated(el);
- await nextFrame(3); // ensure that the rendering's completed
+ await nextFrame(2); // wait for rendering completion
expect(countDataChanged).to.equal(1);
expect(countDataError).to.equal(0);
expect(isCanvasBlank(canvas)).to.be.false;
diff --git a/packages/elements/src/tab-bar/__test__/tab-bar.template.test.js b/packages/elements/src/tab-bar/__test__/tab-bar.template.test.js
index 4fa769c30c..a428c66614 100644
--- a/packages/elements/src/tab-bar/__test__/tab-bar.template.test.js
+++ b/packages/elements/src/tab-bar/__test__/tab-bar.template.test.js
@@ -100,7 +100,7 @@ describe('tab-bar/TabBar', () => {
});
it('Should show only right scroll button', async () => {
- await nextFrame(); // wait for rendering
+ await nextFrame(); // wait for resize observer & rendering completion
expect(getElementStyle(leftScrollBtn, 'display')).equal('none');
expect(getElementStyle(rightScrollBtn, 'display')).equal('flex');
});