Skip to content
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

TypeError: Cannot read property 'play' of undefined #909

Closed
Tokimon opened this issue Jun 3, 2020 · 3 comments
Closed

TypeError: Cannot read property 'play' of undefined #909

Tokimon opened this issue Jun 3, 2020 · 3 comments

Comments

@Tokimon
Copy link

Tokimon commented Jun 3, 2020

Current Behavior

When you change the playing prop during test (using Jest), the following error is thrown.

TypeError: Cannot read property 'play' of undefined

Expected Behavior

No Error to be thrown

Steps to Reproduce

React component

import React from 'react';
import ReactPlayer from 'react-player';

const VideoTest = ({ play }) => {
  return (
    <ReactPlayer
      url='./test-video.mp4'
      playing={!!play}
      className='react-player'
      width='100%'
      height='100%'
      style={{ lineHeight: 0 }}
    />
  );
};

VideoTest.displayName = 'VideoTest';

export default VideoTest;

Test File

import React from 'react';
import { mount } from 'enzyme';

import VideoTest from './VideoTest';

describe('[molecule] VideoPlayerTest', () => {
  it('testing resetting play', () => {
    const wrapper = mount(<VideoTest file='http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4' />);

    wrapper.setProps({ play: true });
    wrapper.setProps({ play: false });
  });
});

Environment

  • Test runner: Jest
  • Browser: JsDom
  • Operating system: Windows
@cookpete
Copy link
Owner

cookpete commented Jun 5, 2020

I'm guessing the ref function for FilePlayer isn't running during Enzyme's mount:

https://github.com/CookPete/react-player/blob/2a9e09c7405a67ac767c6f8f03b0559e541046e0/src/players/FilePlayer.js#L272-L278

The prop change in the test will attempt to do this.player.pause() but if the ref hasn't been resolved to the video/audio element then it will cause the error you describe.

I guess the solution is to use shallow rendering instead? You're probably always gonna run in to issues with mount, assuming audio/video doesn't work correctly in jsDom.

@Tokimon
Copy link
Author

Tokimon commented Jun 5, 2020

hm. I can try to test with shallow.

@peeke
Copy link

peeke commented Jun 10, 2020

I have the same issue using react-player/lazy.

I'm changing the playing prop, before the video is ready:

function Video({ src, autoplay }) {
  const { ref, wasInViewport } = useWasInViewport({ threshold: [0.66] })

  return (
    <ReactPlayer
      url={src}
      muted={autoplay}
      playing={autoplay && wasInViewport}
      controls
    />
  )
}

I've managed to work around it by listening for onReady, but it would be nice if that wasn't needed:

function Video({ src, autoplay }) {
  const [ready, setReady] = React.useState(false)
  const { ref, wasInViewport } = useWasInViewport({ threshold: [0.66] })

  return (
    <ReactPlayer
      onReady={() => setReady(true)}
      url={src}
      muted={autoplay}
      playing={autoplay && ready && wasInViewport}
      controls
    />
  )
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants