Skip to content

Commit 9f502c3

Browse files
chore: Modified timeouts to address flaky tests (#1284)
Closes muxinc/devextravaganza#216 Changes to try to reduce test flakiness for Webkit runs. For example on: https://github.com/muxinc/media-chrome/actions/runs/23017090932/job/66843131347 Also added a step to try to improve run time on job reruns, since they sometimes take more than 20 mins Before changes (`Run npx playwright install-deps` step) : <img width="728" height="141" alt="image" src="https://github.com/user-attachments/assets/9d866db3-29cc-4dfb-afeb-7dcf943accd5" /> After changes: <img width="780" height="195" alt="image" src="https://github.com/user-attachments/assets/8b3c280c-1b46-4207-af74-16a6237c96fa" /> Note: changes inspired by these two posts [microsoft/playwright - [Question] Speed up installing browsers in GitHub Actions](microsoft/playwright#14434) and related [actions/runner - man-db trigger severely stalls package installation on ubuntu-24.04 runners #4030](actions/runner#4030) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: changes are limited to CI/CD workflow steps and test timing/await logic; main risk is longer test timeouts potentially masking legitimate hangs. > > **Overview** > **Stabilizes Playwright-driven unit tests and speeds up GitHub Actions runs.** CI and CD workflows now remove `man-db` before Playwright dependency installs to reduce `apt` delays on Ubuntu runners. > > Updates flaky tests to rely on `waitUntil` (with longer per-suite timeouts and explicit failure messages) instead of fixed `aTimeout` sleeps, and adds `preload="auto"` to the test video fixture to make state assertions more deterministic (notably on WebKit). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2aedbfd. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Manuel Calleriza <mcalleriza@mux.com>
1 parent 3b1014b commit 9f502c3

4 files changed

Lines changed: 37 additions & 19 deletions

File tree

.github/workflows/cd.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ jobs:
7171
path: ~/.cache/ms-playwright
7272
key: playwright-browsers-${{ env.PLAYWRIGHT_VERSION }}
7373

74+
- name: Remove man-db to speed up apt installs
75+
run: sudo apt-get remove -y man-db
7476
- run: npx playwright install --with-deps
7577
if: steps.cache-playwright-browsers.outputs.cache-hit != 'true'
7678
- run: npx playwright install-deps

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ jobs:
3131
path: ~/.cache/ms-playwright
3232
key: playwright-browsers-${{ env.PLAYWRIGHT_VERSION }}
3333

34+
- name: Remove man-db to speed up apt installs
35+
run: sudo apt-get remove -y man-db
3436
- run: npx playwright install --with-deps
3537
if: steps.cache-playwright-browsers.outputs.cache-hit != 'true'
3638
- run: npx playwright install-deps

test/unit/media-controller.spec.ts

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
aTimeout,
32
assert,
43
fixture,
54
nextFrame,
@@ -304,7 +303,8 @@ describe('<media-controller>', () => {
304303
});
305304
});
306305

307-
describe('receiving state / dispatching (bubbling) events', () => {
306+
describe('receiving state / dispatching (bubbling) events', function () {
307+
this.timeout(30000);
308308
let mediaController: MediaController;
309309
let video: HTMLVideoElement;
310310
let div: HTMLDivElement;
@@ -318,12 +318,14 @@ describe('receiving state / dispatching (bubbling) events', () => {
318318
muted
319319
crossorigin
320320
playsinline
321+
preload="auto"
321322
></video>
322323
<div></div>
323324
</media-controller>
324325
`);
325326
video = mediaController.querySelector('video') as HTMLVideoElement;
326327
div = mediaController.querySelector('div') as HTMLDivElement;
328+
327329
});
328330

329331
it('receives state as attributes from the media', async () => {
@@ -350,8 +352,6 @@ describe('receiving state / dispatching (bubbling) events', () => {
350352
MediaUIAttributes.MEDIA_VOLUME_LEVEL
351353
);
352354

353-
await aTimeout(200);
354-
355355
await video.play();
356356

357357
assert(!mediaController.hasAttribute(MediaUIAttributes.MEDIA_PAUSED));
@@ -364,9 +364,12 @@ describe('receiving state / dispatching (bubbling) events', () => {
364364
div.dispatchEvent(
365365
new Event(MediaUIEvents.MEDIA_PLAY_REQUEST, { bubbles: true })
366366
);
367-
await aTimeout(10);
368367

369-
assert(!video.paused, 'video.paused is false');
368+
await waitUntil(() => !video.paused, 'video.paused is false');
369+
await waitUntil(() =>
370+
!mediaController.hasAttribute(MediaUIAttributes.MEDIA_PAUSED),
371+
'has no mediapaused'
372+
);
370373
assert(
371374
!mediaController.hasAttribute(MediaUIAttributes.MEDIA_PAUSED),
372375
'has no mediapaused'
@@ -375,9 +378,12 @@ describe('receiving state / dispatching (bubbling) events', () => {
375378
div.dispatchEvent(
376379
new Event(MediaUIEvents.MEDIA_PAUSE_REQUEST, { bubbles: true })
377380
);
378-
await aTimeout(10);
379381

380-
assert(video.paused, 'video.paused is true');
382+
await waitUntil(() => video.paused);
383+
await waitUntil(() =>
384+
mediaController.hasAttribute(MediaUIAttributes.MEDIA_PAUSED),
385+
'has mediapaused'
386+
);
381387
assert(
382388
mediaController.hasAttribute(MediaUIAttributes.MEDIA_PAUSED),
383389
'has mediapaused'
@@ -390,9 +396,12 @@ describe('receiving state / dispatching (bubbling) events', () => {
390396
div.dispatchEvent(
391397
new Event(MediaUIEvents.MEDIA_UNMUTE_REQUEST, { bubbles: true })
392398
);
393-
await aTimeout(10);
394399

395-
assert(!video.muted, 'video.muted is false');
400+
await waitUntil(() => !video.muted, 'video.muted is false');
401+
await waitUntil(() =>
402+
!mediaController.hasAttribute(MediaUIAttributes.MEDIA_MUTED),
403+
'has no mediamuted'
404+
);
396405
assert(
397406
!mediaController.hasAttribute(MediaUIAttributes.MEDIA_MUTED),
398407
'has no mediamuted'
@@ -401,9 +410,12 @@ describe('receiving state / dispatching (bubbling) events', () => {
401410
div.dispatchEvent(
402411
new Event(MediaUIEvents.MEDIA_MUTE_REQUEST, { bubbles: true })
403412
);
404-
await aTimeout(10);
405413

406-
assert(video.muted, 'video.muted is true');
414+
await waitUntil(() => video.muted, 'video.muted is true');
415+
await waitUntil(() =>
416+
mediaController.hasAttribute(MediaUIAttributes.MEDIA_MUTED),
417+
'has mediamuted'
418+
);
407419
assert(
408420
mediaController.hasAttribute(MediaUIAttributes.MEDIA_MUTED),
409421
'has mediamuted'
@@ -423,7 +435,9 @@ describe('receiving state / dispatching (bubbling) events', () => {
423435
await waitUntil(
424436
() =>
425437
// @ts-ignore
426-
mediaController.getAttribute(MediaUIAttributes.MEDIA_CURRENT_TIME) >= 2
438+
mediaController.getAttribute(MediaUIAttributes.MEDIA_CURRENT_TIME) >= 2,
439+
'mediacurrenttime did not reach 2',
440+
{ timeout: 29000 }
427441
);
428442
assert(true, 'mediacurrenttime is 2');
429443
});
@@ -440,8 +454,8 @@ describe('receiving state / dispatching (bubbling) events', () => {
440454
() =>
441455
// @ts-ignore
442456
mediaController.getAttribute(MediaUIAttributes.MEDIA_VOLUME) == 0.73,
443-
// @ts-ignore
444-
10000
457+
'mediavolume did not reach 0.73',
458+
{ timeout: 29000 }
445459
);
446460
assert(true, 'mediavolume is 0.73');
447461
});

test/unit/media-theme.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import '../../src/js/index.js';
44
import '../../src/js/media-theme-element.js';
55
import { MediaThemeElement } from '../../src/js/media-theme-element.js';
66

7-
describe('<media-theme>', () => {
7+
describe('<media-theme>', function () {
8+
this.timeout(15000);
89
it(`<media-theme> with template attribute works w/ delayed document append`, async () => {
910
const template: HTMLTemplateElement = document.createElement('template');
1011
template.id = 'not-yet';
@@ -29,8 +30,6 @@ describe('<media-theme>', () => {
2930
});
3031

3132
it(`<media-theme> w/ template HTML file URL doesn't duplicate fetch/render `, async function () {
32-
this.timeout(5000);
33-
3433
const theme = document.createElement('media-theme');
3534
theme.setAttribute(
3635
'template',
@@ -39,7 +38,8 @@ describe('<media-theme>', () => {
3938

4039
await waitUntil(
4140
() => theme!.shadowRoot!.querySelector('media-controller'),
42-
5000 as any
41+
'media-controller not found in shadow root',
42+
{ timeout: 10000 }
4343
);
4444
const mediaController =
4545
theme!.shadowRoot!.querySelector('media-controller');

0 commit comments

Comments
 (0)