Skip to content

Commit

Permalink
Add presentation mode test
Browse files Browse the repository at this point in the history
  • Loading branch information
tvanlaerhoven committed Oct 24, 2024
1 parent a1c61a1 commit 7445e87
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 42 deletions.
6 changes: 3 additions & 3 deletions e2e/src/tests/Ads.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TestScope } from 'cavy';
import { AdDescription, AdEventType, PlayerEventType, SourceDescription } from 'react-native-theoplayer';
import { AdDescription, AdEventType, PlayerEventType, SourceDescription, AdEvent } from 'react-native-theoplayer';
import hls from '../res/hls.json';
import ads from '../res/ads.json';
import { getTestPlayer } from '../components/TestableTHEOplayerView';
Expand All @@ -16,8 +16,8 @@ export default function (spec: TestScope) {
const playEventsPromise = waitForPlayerEventTypes(player, [PlayerEventType.SOURCE_CHANGE, PlayerEventType.PLAY, PlayerEventType.PLAYING]);

const adEventsPromise = waitForPlayerEvents(player, [
{ type: PlayerEventType.AD_EVENT, subType: AdEventType.AD_BREAK_BEGIN },
{ type: PlayerEventType.AD_EVENT, subType: AdEventType.AD_BEGIN },
{ type: PlayerEventType.AD_EVENT, subType: AdEventType.AD_BREAK_BEGIN } as AdEvent,
{ type: PlayerEventType.AD_EVENT, subType: AdEventType.AD_BEGIN } as AdEvent,
]);

// Start autoplay
Expand Down
27 changes: 4 additions & 23 deletions e2e/src/tests/Basic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,10 @@ import { PlayerEventType, SourceDescription } from 'react-native-theoplayer';
import dash from '../res/dash.json';
import hls from '../res/hls.json';
import mp4 from '../res/mp4.json';
import { getTestPlayer } from '../components/TestableTHEOplayerView';
import { expect, waitForPlayerEventType, waitForPlayerEventTypes } from '../utils/Actions';
import { expect, preparePlayerWithSource, waitForPlayerEventType, waitForPlayerEventTypes } from '../utils/Actions';

const SEEK_THRESHOLD = 1e-1;

async function preparePlayerWithSource(source: SourceDescription, autoplay: boolean) {
const player = await getTestPlayer();
const eventsPromise = waitForPlayerEventType(player, PlayerEventType.SOURCE_CHANGE);
const eventsPromiseAutoPlay = waitForPlayerEventTypes(player, [PlayerEventType.SOURCE_CHANGE, PlayerEventType.PLAY, PlayerEventType.PLAYING]);

// Start autoplay
player.autoplay = autoplay;
player.source = source;

// Wait for `sourcechange`, `play` and `playing` events.
if (autoplay) {
await eventsPromiseAutoPlay;
} else {
await eventsPromise;
}
return player;
}

function testBasicPlayout(spec: TestScope, title: string, source: SourceDescription) {
spec.describe(title, function () {
spec.it('dispatches sourcechange event on setting a source without autoplay', async function () {
Expand All @@ -39,15 +20,15 @@ function testBasicPlayout(spec: TestScope, title: string, source: SourceDescript

spec.it('dispatches sourcechange, play and playing events in order on setting a source with autoplay', async function () {
// Set source and wait for playback
const player = await preparePlayerWithSource(source, true);
const player = await preparePlayerWithSource(source);

// Still playing
expect(player.paused).toBeFalsy();
});

spec.it('dispatches a seeked event after seeking', async function () {
// Set source and wait for playback
const player = await preparePlayerWithSource(source, true);
const player = await preparePlayerWithSource(source);

// Seek
const seekPromise = waitForPlayerEventType(player, PlayerEventType.SEEKED);
Expand All @@ -63,7 +44,7 @@ function testBasicPlayout(spec: TestScope, title: string, source: SourceDescript

spec.it('dispatches paused, play and playing events after pausing & resuming playback', async function () {
// Set source and wait for playback
const player = await preparePlayerWithSource(source, true);
const player = await preparePlayerWithSource(source);

// Pause play-out.
const pausePromise = waitForPlayerEventType(player, PlayerEventType.PAUSE);
Expand Down
24 changes: 11 additions & 13 deletions e2e/src/tests/Connector.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ type PlayerFn = (player: THEOplayer) => Promise<void> | void;
const NoOpPlayerFn: PlayerFn = (_player: THEOplayer) => {};

function testConnector(spec: TestScope, onCreate: PlayerFn, onUseAPI: PlayerFn, onDestroy: PlayerFn) {
spec.it('successfully creates the connector and connects to the player', async function () {
await onCreate(await getTestPlayer());
});

spec.it('handles sourcechange, play and playing events on play-out', async function () {
spec.it('successfully creates the connector, connects to the player, uses API, and cleans up and destroys.', async function () {
const player = await getTestPlayer();

// Create connector.
await onCreate(player);

const eventsPromise = waitForPlayerEventTypes(player, [PlayerEventType.SOURCE_CHANGE, PlayerEventType.PLAY, PlayerEventType.PLAYING]);

// Start autoplay
Expand All @@ -28,16 +28,14 @@ function testConnector(spec: TestScope, onCreate: PlayerFn, onUseAPI: PlayerFn,

// Expect events.
await eventsPromise;
});

if (onUseAPI !== NoOpPlayerFn) {
spec.it('successfully uses connector API', async function () {
await onUseAPI(await getTestPlayer());
});
}
// Use connector API
if (onUseAPI !== NoOpPlayerFn) {
await onUseAPI(player);
}

spec.it('successfully cleans up on destroy', async function () {
await onDestroy(await getTestPlayer());
// Clean-up and destroy connector.
await onDestroy(player);
});
}

Expand Down
42 changes: 42 additions & 0 deletions e2e/src/tests/PresentationMode.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { TestScope } from 'cavy';
import { PlayerEventType, PresentationMode, PresentationModeChangeEvent } from 'react-native-theoplayer';
import hls from '../res/hls.json';
import { expect, preparePlayerWithSource, waitForPlayerEvent } from '../utils/Actions';
import { sleep } from '../utils/TimeUtils';

export default function (spec: TestScope) {
spec.describe('Switches between presentation modes.', function () {
spec.it('dispatches presentationmodechange events between inline and fullscreen.', async function () {
const player = await preparePlayerWithSource(hls[0]);

// Switch to fullscreen.
const fullscreenPromise = waitForPlayerEvent(player, {
type: PlayerEventType.PRESENTATIONMODE_CHANGE,
presentationMode: PresentationMode.fullscreen,
previousPresentationMode: PresentationMode.inline,
} as PresentationModeChangeEvent);
player.presentationMode = PresentationMode.fullscreen;

// Wait for 'presentationmodechange' event.
await fullscreenPromise;

// Play-out should not pause.
await sleep(500);
expect(player.paused).toBeFalsy();

// Switch back to inline.
const inlinePromise = waitForPlayerEvent(player, {
type: PlayerEventType.PRESENTATIONMODE_CHANGE,
presentationMode: PresentationMode.inline,
previousPresentationMode: PresentationMode.inline,
} as PresentationModeChangeEvent);
player.presentationMode = PresentationMode.inline;

// Wait for 'presentationmodechange' event.
await inlinePromise;

// Play-out should not pause.
expect(player.paused).toBeFalsy();
});
});
}
5 changes: 3 additions & 2 deletions e2e/src/tests/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Basic from './Basic.spec';
import Ads from './Ads.spec';
import Basic from './Basic.spec';
import Connector from './Connector.spec';
import PresentationMode from './PresentationMode.spec';

export default [Basic, Ads, Connector];
export default [Basic, Ads, Connector, PresentationMode];
21 changes: 20 additions & 1 deletion e2e/src/utils/Actions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// noinspection JSUnusedGlobalSymbols

import { ErrorEvent, type Event, PlayerEventType, THEOplayer } from 'react-native-theoplayer';
import { ErrorEvent, type Event, PlayerEventType, SourceDescription, THEOplayer } from 'react-native-theoplayer';
import { getTestPlayer } from '../components/TestableTHEOplayerView';

export interface TestOptions {
timeout: number;
Expand All @@ -10,6 +11,24 @@ export const defaultTestOptions: TestOptions = {
timeout: 10000,
};

export async function preparePlayerWithSource(source: SourceDescription, autoplay: boolean = true): Promise<THEOplayer> {
const player = await getTestPlayer();
const eventsPromise = waitForPlayerEventType(player, PlayerEventType.SOURCE_CHANGE);
const eventsPromiseAutoPlay = waitForPlayerEventTypes(player, [PlayerEventType.SOURCE_CHANGE, PlayerEventType.PLAY, PlayerEventType.PLAYING]);

// Start autoplay
player.autoplay = autoplay;
player.source = source;

// Wait for `sourcechange`, `play` and `playing` events.
if (autoplay) {
await eventsPromiseAutoPlay;
} else {
await eventsPromise;
}
return player;
}

export const waitForPlayerEventType = async (
player: THEOplayer,
type: PlayerEventType,
Expand Down

0 comments on commit 7445e87

Please sign in to comment.