Skip to content

Commit 5fc77a5

Browse files
authored
fix: flaky tests (#2768)
<!-- ## Title: Please consider adding the [skip chromatic] flag to the PR title in case you dont need chromatic testing your changes. --> ## Description: This PR tries to fix some tests that create inconsistencies in our pipelines. ## Definition of Reviewable: <!-- *PR notes: Irrelevant elements should be removed.* --> - [ ] Documentation is created/updated - [ ] Migration Guide is created/updated <!-- *PR notes: If this PR includes a BREAKING CHANGE, a migration guide is needed to explain how users can migrate between versions. * --> - [ ] E2E tests (features, a11y, bug fixes) are created/updated <!-- *If this PR includes a bug fix, an E2E test is necessary to verify the change. If the fix is purely visual, ensuring it is captured within our chromatic screenshot tests is sufficient.* --> - [ ] Stories (features, a11y) are created/updated - [ ] relevant tickets are linked
1 parent 6f60e0f commit 5fc77a5

8 files changed

Lines changed: 39 additions & 9 deletions

File tree

.changeset/deep-shrimps-invite.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@solid-design-system/components': patch
3+
---
4+
5+
Fixes flaky tests on `sd-dropdown`, `sd-audio`, `sd-video` and `sd-carousel`.

.changeset/olive-chefs-share.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@solid-design-system/docs': patch
3+
---
4+
5+
Added safeguard to prevent `sd-icon` tests from timing out during Playwright testing.

packages/components/src/components/audio/audio.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import '../../../dist/solid-components';
22
import { expect, fixture, html } from '@open-wc/testing';
3+
import { sendMouse } from '@web/test-runner-commands';
34
import base64Audio from './base64Audio';
45
import sinon from 'sinon';
56
import type SdAudio from './audio';
@@ -24,6 +25,8 @@ describe('<sd-audio>', () => {
2425
const spy = sinon.spy();
2526
el.addEventListener('sd-playback-start', spy);
2627

28+
// Simulate a real user gesture to allow media playback
29+
await sendMouse({ type: 'click', position: [0, 0] });
2730
(playButton as HTMLElement).click();
2831

2932
expect(spy.calledOnce).to.be.true;

packages/components/src/components/carousel/carousel.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import '../../../dist/solid-components';
2-
import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing';
2+
import { aTimeout, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
33
import { clickOnElement } from '../../internal/test.js';
44
import sinon from 'sinon';
55
import type SdCarousel from './carousel';
@@ -598,15 +598,15 @@ describe('<sd-carousel>', () => {
598598
el.goToSlide(2, 'smooth');
599599
await oneEvent(el.scrollContainer, 'scroll');
600600
await el.updateComplete;
601+
await waitUntil(() => el.scrollContainer.getAttribute('aria-busy') === 'true');
601602
// Assert
602603
expect(el.scrollContainer).to.have.attribute('aria-busy', 'true');
603604

604605
await oneEvent(el.scrollContainer, 'scrollend');
605606
await el.updateComplete;
606-
607607
// It takes a moment for the scrollend event to be fired.
608608
await aTimeout(100);
609-
609+
await waitUntil(() => el.scrollContainer.getAttribute('aria-busy') === 'false');
610610
expect(el.scrollContainer).to.have.attribute('aria-busy', 'false');
611611
});
612612
});

packages/components/src/components/dropdown/dropdown.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ describe('<sd-dropdown>', () => {
391391
// navigate down
392392
await sendKeys({ press: 'ArrowDown' });
393393
await firstItem.updateComplete;
394-
394+
await waitUntil(() => firstItem.classList.contains('menu-item-focus'));
395395
expect(firstItem.classList.contains('menu-item-focus')).to.be.true;
396396
});
397397

@@ -425,13 +425,15 @@ describe('<sd-dropdown>', () => {
425425
await sendKeys({ press: 'ArrowDown' });
426426
await firstItem.updateComplete;
427427

428+
await waitUntil(() => firstItem.classList.contains('menu-item-focus'));
428429
expect(firstItem.classList.contains('menu-item-focus')).to.be.true;
429430

430431
// click outside
431432
document.body.dispatchEvent(new MouseEvent('click', { bubbles: true, composed: true }));
432433
await el.updateComplete;
433434

434435
// check all menu items have lost focus
436+
await waitUntil(() => Array.from(items).every(item => !item.classList.contains('menu-item-focus')));
435437
items.forEach(item => {
436438
expect(item.classList.contains('menu-item-focus')).to.be.false;
437439
});

packages/components/src/components/video/video.test.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import '../../../dist/solid-components';
22
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
3-
import { sendKeys } from '@web/test-runner-commands';
3+
import { sendKeys, sendMouse } from '@web/test-runner-commands';
44
import sinon from 'sinon';
55
import type SdVideo from './video';
66

@@ -64,12 +64,15 @@ describe('<sd-video>', () => {
6464
const el: SdVideo = await fixture(variants.default);
6565
const playSpy = sinon.spy();
6666
el.addEventListener('sd-play', playSpy);
67+
// Simulate a real user gesture to allow media playback
68+
await sendMouse({ type: 'click', position: [0, 0] });
6769
el.shadowRoot?.querySelector('button')?.click();
6870
expect(playSpy.calledOnce).to.be.true;
6971
});
7072

7173
it('toggles playing property', async () => {
7274
const el: SdVideo = await fixture(variants.default);
75+
await sendMouse({ type: 'click', position: [0, 0] });
7376
el.shadowRoot?.querySelector('button')?.click();
7477
expect(el.playing).to.be.true;
7578
});
@@ -81,12 +84,14 @@ describe('<sd-video>', () => {
8184
const el: SdVideo = await fixture(variants.default);
8285
const playSpy = sinon.spy();
8386
el.addEventListener('sd-play', playSpy);
87+
await sendMouse({ type: 'click', position: [0, 0] });
8488
el.shadowRoot?.querySelector('button')?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
8589
expect(playSpy.calledOnce).to.be.true;
8690
});
8791

8892
it('toggles playing property', async () => {
8993
const el: SdVideo = await fixture(variants.default);
94+
await sendMouse({ type: 'click', position: [0, 0] });
9095
el.shadowRoot?.querySelector('button')?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
9196
expect(el.playing).to.be.true;
9297
});
@@ -110,6 +115,7 @@ describe('<sd-video>', () => {
110115
it('video is focusable after played', async () => {
111116
const el: SdVideo = await fixture(variants.all);
112117

118+
await sendMouse({ type: 'click', position: [0, 0] });
113119
el.shadowRoot?.querySelector('button')?.click();
114120

115121
await sendKeys({ press: tabKey });
@@ -130,6 +136,7 @@ describe('<sd-video>', () => {
130136
return getComputedStyle(imgElement).opacity === '0';
131137
});
132138

139+
await sendMouse({ type: 'click', position: [0, 0] });
133140
el.shadowRoot?.querySelector('button')?.click();
134141

135142
await transitionEndPromise; // Wait for the transitionend event

packages/docs/scripts/test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ async function previewAndTest() {
3939
prefixColor: 'magenta'
4040
},
4141
{
42-
command: `wait-on -v -t 5s tcp:127.0.0.1:${PORT} && ${testCommand}`,
42+
command: `wait-on -v -t 10s tcp:127.0.0.1:${PORT} && ${testCommand}`,
4343
name: 'Testing',
4444
prefixColor: 'blue'
4545
}
4646
],
4747
{
48-
killOthers: ['failure', 'success'],
48+
killOthersOn: ['failure', 'success'],
4949
successCondition: 'first',
5050
raw: true
5151
}

packages/docs/src/stories/components/icon.default.stories.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ export const LibraryDefaultContent = {
4141
y: {
4242
type: 'attribute',
4343
name: 'name',
44-
values: (iconsFromCdn as { content: string[] }).content.map(icon => `content/${icon}`)
44+
values: Array.isArray(iconsFromCdn?.content)
45+
? iconsFromCdn.content
46+
.filter((icon: string): icon is string => typeof icon === 'string' && icon.length > 0)
47+
.map((icon: string) => `content/${icon}`)
48+
: []
4549
}
4650
},
4751
constants: [{ type: 'attribute', name: 'library', value: '' }],
@@ -75,7 +79,11 @@ export const LibraryDefaultSystem = {
7579
y: {
7680
type: 'attribute',
7781
name: 'name',
78-
values: (iconsFromCdn as { system: string[] }).system.map(icon => `system/${icon}`)
82+
values: Array.isArray(iconsFromCdn?.system)
83+
? iconsFromCdn.system
84+
.filter((icon: string): icon is string => typeof icon === 'string' && icon.length > 0)
85+
.map((icon: string) => `system/${icon}`)
86+
: []
7987
}
8088
},
8189
constants: [{ type: 'attribute', name: 'library', value: '' }],

0 commit comments

Comments
 (0)