diff --git a/test/specs/ReactPlayer.js b/test/specs/ReactPlayer.js index 8d38cea0..229cb148 100644 --- a/test/specs/ReactPlayer.js +++ b/test/specs/ReactPlayer.js @@ -45,7 +45,8 @@ const TEST_URLS = [ { name: 'Vidme', url: 'https://vid.me/yvi', - switchTo: 'https://vid.me/GGho' + switchTo: 'https://vid.me/GGho', + error: 'https://vid.me/0000' }, { name: 'Wistia', @@ -62,7 +63,7 @@ const TEST_URLS = [ { name: 'FilePlayer', url: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.ogv', - switchTo: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4', + switchTo: 'http://www.sample-videos.com/audio/mp3/crowd-cheering.mp3', error: 'http://example.com/error.ogv', onSeek: true }, @@ -93,7 +94,40 @@ const TEST_URLS = [ ] describe('ReactPlayer', () => { - let div + let div // Top level div to render into + let player // Top level player var that will always contain the latest player instance + + // Test util for rendering a player + function renderPlayer (props, onMount) { + const ref = p => { + if (p) { + player = p + if (onMount) { + onMount() + } + } + } + // Note that playing is set to true by default + render(, div) + } + + // Test util for rendering a player and then changing props after a short time + function renderPlayerChange (props, changeProps, onChange) { + renderPlayer({ + ...props, + onProgress: p => { + if (changeProps && p.playedSeconds > 1) { + renderPlayer({ ...props, ...changeProps }) + if (onChange) { + onChange() + } + } + if (props.onProgress) { + props.onProgress(p) + } + } + }) + } beforeEach(() => { div = document.createElement('div') @@ -123,343 +157,152 @@ describe('ReactPlayer', () => { done() } } - let player - render( - { player = p || player }} - url={test.url} - playing - onReady={() => bump('onReady')} - onStart={() => bump('onStart')} - onPlay={() => bump('onPlay')} - onDuration={secs => bump('onDuration')} - onProgress={progress => bump('onProgress')} - />, - div) + renderPlayer({ + url: test.url, + onReady: () => bump('onReady'), + onStart: () => bump('onStart'), + onPlay: () => bump('onPlay'), + onDuration: secs => bump('onDuration'), + onProgress: progress => bump('onProgress') + }) }) it('onPause', done => { - const onPause = () => done() - const pausePlayer = () => { - render( - , - div) + const props = { + url: test.url, + onPause: () => done(), + playing: true } - render( - { - if (p.playedSeconds >= 3) { - pausePlayer() - } - }} - />, - div) + renderPlayerChange(props, { playing: false }) }) it('should not play if playing is false', done => { - render( - setTimeout(done, 1000)} - onPlay={() => done('should not play if playing is false')} - />, - div) + renderPlayer({ + url: test.url, + playing: false, + onReady: () => setTimeout(done, 1000), + onPlay: () => done('should not play if playing is false') + }) }) it('plays after a delay', done => { const playPlayer = () => { - render( - done()} - />, - div) + renderPlayer({ + url: test.url, + playing: true, + onPlay: () => done() + }) } - render( - setTimeout(playPlayer, 3000)} - />, - div) + renderPlayer({ + url: test.url, + playing: false, + onReady: () => setTimeout(playPlayer, 1000) + }) }) it('volume change does not error', done => { - const changeVolume = () => { - render( - , - div) - setTimeout(done, 1000) - } - render( - { - if (p.playedSeconds >= 3) { - changeVolume() - } - }} - />, - div) + renderPlayerChange( + { url: test.url, volume: 1 }, + { volume: 0.5 }, + () => setTimeout(done, 1000) + ) }) it('muted change does not error', done => { - const changeMuted = () => { - render( - , - div) - setTimeout(done, 1000) - } - render( - { - if (p.playedSeconds >= 3) { - changeMuted() - } - }} - />, - div) + renderPlayerChange( + { url: test.url, muted: false }, + { muted: true }, + () => setTimeout(done, 1000) + ) }) it('playbackRate change does not error', done => { - const changePlaybackRate = () => { - render( - , - div) - setTimeout(done, 1000) - } - render( - { - if (p.playedSeconds >= 3) { - changePlaybackRate() - } - }} - />, - div) + renderPlayerChange( + { url: test.url, playbackRate: 1 }, + { playbackRate: 0.5 }, + () => setTimeout(done, 1000) + ) }) it('renders twice without error', done => { - let count = 0 - const onReady = () => { - count++ - if (count > 1) { - done('Should not call onReady more than once') - } - } - const renderPlayer = () => { - render(, div) - } - renderPlayer() - setTimeout(renderPlayer, 1000) - setTimeout(done, 3000) + const go = () => renderPlayer({ url: test.url }) + go() + setTimeout(go, 1000) + setTimeout(done, 2000) }) if (test.switchTo) { it('switches URL', done => { - const switchPlayer = () => { - render( - done()} - />, - div) - } - render( - { - if (p.playedSeconds >= 3) { - switchPlayer() - } - }} - />, - div) + renderPlayerChange( + { url: test.url }, + { url: test.switchTo, onPlay: () => done() } + ) }) } if (test.error) { it('onError', done => { - render( - done()} - />, - div) + renderPlayer({ url: test.error, onError: () => done() }) }) } it('seekTo, onEnded', done => { - let player let duration let seeked = false - render( - { player = p || player }} - url={test.url} - playing - onDuration={d => { duration = d }} - onProgress={p => { - if (!seeked && duration && p.playedSeconds >= 3) { - player.seekTo(duration - 3) - seeked = true - } - }} - onEnded={() => done()} - />, - div) + renderPlayer({ + url: test.url, + onDuration: d => { duration = d }, + onProgress: p => { + if (!seeked && duration && p.playedSeconds > 1) { + player.seekTo(duration - 1) + seeked = true + } + }, + onEnded: () => done() + }) }) if (test.onSeek) { it('onSeek', done => { - let player - render( - { player = p || player }} - url={test.url} - playing - onProgress={p => { - if (p.playedSeconds >= 3) { - player.seekTo(10) - } - }} - onSeek={() => done()} - />, - div) + renderPlayer({ + url: test.url, + onProgress: p => { + if (p.playedSeconds >= 1) { + player.seekTo(10) + } + }, + onSeek: () => done() + }) }) it('seekTo fraction', done => { - let player - render( - { player = p || player }} - url={test.url} - playing - onProgress={p => { - if (p.playedSeconds >= 3) { - player.seekTo(0.5) - } - }} - onSeek={() => done()} - />, - div) + renderPlayer({ + url: test.url, + onProgress: p => { + if (p.playedSeconds >= 1) { + player.seekTo(0.5) + } + }, + onSeek: () => done() + }) }) it('seekOnPlay', done => { - let player - render( - { - player = p || player - player.seekTo(3) - }} - url={test.url} - playing - onSeek={() => done()} - />, - div) - }) - } - - if (test.name === 'Vidme') { - it('plays a specific format', done => { - render( - done()} - />, - div) - }) - - it('ignores an unknown format', done => { - render( - done()} - />, - div) + renderPlayer({ + url: test.url, + onSeek: () => done() + }, () => player.seekTo(3)) }) } }) } - describe('playbackRate', () => { - it('updates correctly', done => { - let player - const updatePlayer = () => { - render( - { - const p = player.getInternalPlayer() - if (p && p.playbackRate === 0.5) { - done() - } - }} - />, - div) - } - render( - { player = p }} - url='http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4' - playing - onProgress={p => { - if (p.playedSeconds >= 3) { - updatePlayer() - } - }} - />, - div) - }) - }) - describe('instance methods', () => { - let player beforeEach(done => { - render( - { player = p || player }} - url='http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4' - onReady={() => done()} - />, - div) + renderPlayer({ + url: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4', + onReady: () => done() + }) }) it('returns correctly', () => { @@ -470,19 +313,8 @@ describe('ReactPlayer', () => { }) describe('fall back to FilePlayer', () => { - let player beforeEach(done => { - render( - { - if (p) { - player = p - done() - } - }} - url='http://example.com/random/path' - />, - div) + renderPlayer({ url: 'http://example.com/random/path' }, () => done()) }) it('falls back to FilePlayer', () => { @@ -493,24 +325,15 @@ describe('ReactPlayer', () => { }) describe('preloading', () => { - let player beforeEach(done => { - render( - { - if (p) { - player = p - done() - } - }} - url={null} - config={{ - youtube: { preload: true }, - vimeo: { preload: true }, - dailymotion: { preload: true } - }} - />, - div) + renderPlayer({ + url: null, + config: { + youtube: { preload: true }, + vimeo: { preload: true }, + dailymotion: { preload: true } + } + }, () => done()) }) it('renders with preload config', () => { @@ -523,20 +346,54 @@ describe('ReactPlayer', () => { }) }) - it('does not error when seeking using fraction before ready', () => { - render( - { - if (p) p.seekTo(0.5) + describe('Vidme format', () => { + it('plays a specific format', done => { + renderPlayer({ + url: 'https://vid.me/GGho', + config: { vidme: { format: '240p' } }, + onReady: () => done() + }) + }) + + it('ignores an unknown format', done => { + renderPlayer({ + url: 'https://vid.me/GGho', + config: { vidme: { format: 'test-unknown-format' } }, + onReady: () => done() + }) + }) + }) + + describe('FilePlayer tracks', () => { + beforeEach(done => { + renderPlayer({ + url: 'file.mp4', + playsinline: true, // Not required but good for coverage + config: { file: { + tracks: [ + { kind: 'subtitles', src: 'subs/subtitles.en.vtt', srcLang: 'en', default: true }, + { kind: 'subtitles', src: 'subs/subtitles.ja.vtt', srcLang: 'ja' }, + { kind: 'subtitles', src: 'subs/subtitles.de.vtt', srcLang: 'de' } + ] }} - url='http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4' - playing - />, - div) + }, () => done()) + }) + + it('renders with tracks', () => { + expect(player.wrapper).to.be.a('HTMLDivElement') + expect(player.wrapper.querySelectorAll('track')).to.have.length(3) + }) + }) + + it('does not error when seeking using fraction before ready', () => { + renderPlayer({ + url: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4' + }, () => player.seekTo(0.5)) }) it('canPlay returns false', () => { expect(ReactPlayer.canPlay('http://example.com')).to.be.false expect(ReactPlayer.canPlay('file.txt')).to.be.false + expect(ReactPlayer.canPlay([ 'http://example.com', 'file.txt' ])).to.be.false }) })