-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve player testing setup #350
Changes from all commits
d977d88
2e6fc90
d3643a6
e9ee5c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,8 +6,12 @@ | |
"android": "react-native run-android", | ||
"ios": "react-native run-ios", | ||
"start": "react-native start", | ||
"test:android": "yarn cavy run-android", | ||
"test:ios": "yarn cavy run-ios", | ||
"stop-test:android": "adb shell am force-stop com.bitmovin.player.reactnative.integrationtest", | ||
"stop-test:ios": "xcrun simctl list devices available -e -j | jq --raw-output '.devices.[].[] | select( .state == \"Booted\" and (.deviceTypeIdentifier | contains(\"iPhone\"))).udid' | xargs -I UDID xcrun simctl terminate UDID com.bitmovin.player.reactnative.IntegrationTest 2> /dev/null; exit 0", | ||
Comment on lines
+9
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These will stop already running instance of the integration test app to prevent it executing tests while rebuilding. |
||
"start-test:android": "yarn cavy run-android", | ||
"start-test:ios": "yarn cavy run-ios --simulator \"$(xcrun simctl list devices available -e -j | jq --raw-output -s '[.[].devices.[].[] | select( .deviceTypeIdentifier | contains(\"iPhone\") )|.name] | first')\"", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Auto-detect iOS simulator to run on |
||
"test:android": "yarn stop-test:android && yarn start-test:android", | ||
"test:ios": "yarn stop-test:ios && yarn start-test:ios", | ||
"pods": "yarn pods-install || yarn pods-update", | ||
"pods-install": "yarn pod-install", | ||
"pods-update": "pod update --silent" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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(); | ||
|
||
Comment on lines
-75
to
-78
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved this as it caused missing initial events from the player. |
||
await fn().finally(() => { | ||
player.destroy(); | ||
this.isFinished_ = true; | ||
|
@@ -85,7 +83,7 @@ export default class PlayerTestWorld { | |
}; | ||
|
||
callPlayer = async <T>(fn: (player: Player) => Promise<T>): Promise<T> => { | ||
return await fn(this.ensurePlayer()); | ||
return await fn(await this.ensurePlayer()); | ||
}; | ||
|
||
expectEvent = async <T extends Event>( | ||
|
@@ -110,7 +108,7 @@ export default class PlayerTestWorld { | |
return await this.expectEventCalling<E>( | ||
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<TimeChangedEvent> => { | ||
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<Player> => { | ||
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 <T extends Event>( | ||
expectationConvertible: SingleEventExpectation | EventType, | ||
timeoutSeconds: number, | ||
afterListenerAttached: () => void = () => {} | ||
afterListenerAttached: () => Promise<void> = async () => Promise.resolve() | ||
): Promise<T> => { | ||
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<void> = async () => Promise.resolve() | ||
): Promise<Event[]> => { | ||
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<void> => { | ||
if (!this.isPlayerInitialized) { | ||
// Trick to make sure the player is initialized, | ||
// otherwise method calls might have no effect. | ||
await new Promise((resolve) => setTimeout(resolve, 150)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How come the change to the fixed wait time? Why not use the same trick as before with Unrelated to this PR but it would be very nice if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was trial and error, Agree, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, that's unfortunate. Out of interest what happened? Did it await for ever? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually the opposite, it was not waiting long enough. I will double-check it with using the latest changes from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, it didn't help. Initial events are missed somehow. |
||
this.isPlayerInitialized = true; | ||
} | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now detected automatically