From 2e6fc90b50dc14ec5f57f83d32cad3dfa0387a46 Mon Sep 17 00:00:00 2001 From: Roland Kakonyi Date: Thu, 7 Dec 2023 15:59:42 +0100 Subject: [PATCH] chore: reduce possible race-conditions when running tests and calling player methods --- .../playertesting/PlayerTestWorld.ts | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/integration_test/playertesting/PlayerTestWorld.ts b/integration_test/playertesting/PlayerTestWorld.ts index 6005bbdd..13f208c3 100644 --- a/integration_test/playertesting/PlayerTestWorld.ts +++ b/integration_test/playertesting/PlayerTestWorld.ts @@ -24,6 +24,7 @@ export default class PlayerTestWorld { private player_: Player | undefined; private isFinished_: boolean = false; private eventListeners: { [key: string]: (event: Event) => void } = {}; + private isPlayerInitialized: boolean = false; static get shared(): PlayerTestWorld { if (PlayerTestWorld.shared_ === undefined) { @@ -42,6 +43,7 @@ export default class PlayerTestWorld { private set player(player: Player | undefined) { this.player_ = player; + this.isPlayerInitialized = false; this.reRender(); } @@ -72,10 +74,6 @@ export default class PlayerTestWorld { player.initialize(); this.player = player; - // Trick to wait for the player to be initialized - // otherwise initial events might be missed - await player.isPlaying(); - await fn().finally(() => { player.destroy(); this.isFinished_ = true; @@ -85,7 +83,7 @@ export default class PlayerTestWorld { }; callPlayer = async (fn: (player: Player) => Promise): Promise => { - return await fn(this.ensurePlayer()); + return await fn(await this.ensurePlayer()); }; expectEvent = async ( @@ -110,7 +108,7 @@ export default class PlayerTestWorld { return await this.expectEventCalling( expectationConvertible, timeoutSeconds, - () => fn(this.ensurePlayer()) + async () => fn(await this.ensurePlayer()) ); }; @@ -122,7 +120,7 @@ export default class PlayerTestWorld { return await this.expectEventsCalling( expectationsConvertible, timeoutSeconds, - () => fn(this.ensurePlayer()) + async () => fn(await this.ensurePlayer()) ); }; @@ -143,7 +141,8 @@ export default class PlayerTestWorld { time: number, timeoutSeconds: number ): Promise => { - const currentTime = await this.ensurePlayer().getCurrentTime(); + const player = await this.ensurePlayer(); + const currentTime = await player.getCurrentTime(); const targetTime = currentTime + time; return await this.playUntil(targetTime, timeoutSeconds); }; @@ -164,13 +163,14 @@ export default class PlayerTestWorld { ); }; - private ensurePlayer = (): Player => { + private ensurePlayer = async (): Promise => { if (this.player !== undefined) { if (this.player.isDestroyed) { throw new Error( 'Player was destroyed. Did you forget to call "startPlayerTest" again?' ); } + await this.ensurePlayerInitialized(); return this.player; } throw new Error("It seems you forgot to call 'startPlayerTest' first."); @@ -186,7 +186,7 @@ export default class PlayerTestWorld { private expectEventCalling = async ( expectationConvertible: SingleEventExpectation | EventType, timeoutSeconds: number, - afterListenerAttached: () => void = () => {} + afterListenerAttached: () => Promise = async () => Promise.resolve() ): Promise => { let actualExpectation: SingleEventExpectation; if (expectationConvertible instanceof SingleEventExpectation) { @@ -211,7 +211,7 @@ export default class PlayerTestWorld { reject(new Error(`Expectation was not met: ${actualExpectation}`)); } }, timeoutSeconds * 1000); - afterListenerAttached(); + await afterListenerAttached(); return future.then((event) => { clearTimeout(timeoutHandle); removeListener(); @@ -222,7 +222,7 @@ export default class PlayerTestWorld { private expectEventsCalling = async ( expectationsConvertible: MultipleEventsExpectation | EventType[], timeoutSeconds: number, - afterListenerAttached: () => void = () => {} + afterListenerAttached: () => Promise = async () => Promise.resolve() ): Promise => { let actualExpectation: MultipleEventsExpectation; if (expectationsConvertible instanceof MultipleEventsExpectation) { @@ -259,7 +259,7 @@ export default class PlayerTestWorld { reject(new Error(`Expectation was not met: ${actualExpectation}`)); } }, timeoutSeconds * 1000); - afterListenerAttached(); + await afterListenerAttached(); return future.then((events) => { clearTimeout(timeoutHandle); removeListener(); @@ -276,4 +276,13 @@ export default class PlayerTestWorld { delete this.eventListeners[key]; }; }; + + private ensurePlayerInitialized = async (): Promise => { + if (this.isPlayerInitialized === false) { + // Trick to make sure the player is initialized, + // otherwise method calls might have no effect. + await new Promise((resolve) => setTimeout(resolve, 150)); + this.isPlayerInitialized = true; + } + }; }