diff --git a/.babelrc.js b/.babelrc.js
index 0075d94..a29ad66 100644
--- a/.babelrc.js
+++ b/.babelrc.js
@@ -10,4 +10,7 @@ module.exports = {
}],
'@babel/react',
],
+ plugins: TEST ? [
+ 'dynamic-import-node',
+ ] : [],
};
diff --git a/.eslintrc.js b/.eslintrc.js
index eb15afb..2a91a70 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,5 +1,9 @@
module.exports = {
extends: 'airbnb',
+ parserOptions: {
+ ecmaVersion: 2022,
+ sourceType: 'module',
+ },
rules: {
// I disagree
'react/jsx-filename-extension': 'off',
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ef952a9..ba0b859 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -36,9 +36,10 @@ jobs:
test:
name: Tests
strategy:
+ fail-fast: false
matrix:
- node-version: [14.x, 16.x, 17.x]
- react-version: [17.x, 18.x]
+ node-version: [16.x, 18.x, 20.x]
+ react-version: [17.x, 18.x, beta]
include:
- node-version: 14.x
react-version: 16.0.0
diff --git a/package.json b/package.json
index b5ba8a6..0d93289 100644
--- a/package.json
+++ b/package.json
@@ -48,6 +48,7 @@
"@babel/register": "^7.12.10",
"@rollup/plugin-babel": "^6.0.0",
"@u-wave/react-vimeo-example": "file:example",
+ "babel-plugin-dynamic-import-node": "^2.3.3",
"cross-env": "^7.0.3",
"eslint": "^8.2.0",
"eslint-config-airbnb": "^19.0.0",
diff --git a/test/test.js b/test/test.js
index 7acde90..018f91d 100644
--- a/test/test.js
+++ b/test/test.js
@@ -4,7 +4,7 @@ import render from './util/render';
describe('Vimeo', () => {
it('should create a Vimeo player when mounted', async () => {
const onReady = createSpy();
- const { sdkMock, playerMock } = render({
+ const { sdkMock, playerMock } = await render({
video: 169408731,
onReady,
});
@@ -16,14 +16,14 @@ describe('Vimeo', () => {
});
it('should use `url` prop for full vimeo URLs', async () => {
- const { sdkMock } = render({ video: 'https://vimeo.com/179290396' });
+ const { sdkMock } = await render({ video: 'https://vimeo.com/179290396' });
expect(sdkMock).toHaveBeenCalled();
expect(sdkMock.calls[0].arguments[1]).toMatch({ url: 'https://vimeo.com/179290396' });
});
it('should all onError when `ready()` fails', async () => {
const onError = createSpy();
- const { sdkMock } = render({
+ const { sdkMock } = await render({
video: 404,
shouldFail: true,
onError,
@@ -36,7 +36,7 @@ describe('Vimeo', () => {
});
it('should load a different video when "video" prop changes', async () => {
- const { sdkMock, playerMock, rerender } = render({
+ const { sdkMock, playerMock, rerender } = await render({
video: 169408731,
});
expect(sdkMock).toHaveBeenCalled();
@@ -49,7 +49,7 @@ describe('Vimeo', () => {
});
it('should pause the video using the "paused" prop', async () => {
- const { playerMock, rerender } = render({
+ const { playerMock, rerender } = await render({
video: 169408731,
autoplay: true,
});
@@ -66,7 +66,7 @@ describe('Vimeo', () => {
});
it('should set the volume using the "volume" prop', async () => {
- const { playerMock, rerender } = render({
+ const { playerMock, rerender } = await render({
video: 169408731,
volume: 0.5,
});
@@ -78,7 +78,7 @@ describe('Vimeo', () => {
});
it('should set the start time using the "start" prop', async () => {
- const { playerMock, rerender } = render({
+ const { playerMock, rerender } = await render({
video: 169408731,
start: 60,
});
@@ -93,7 +93,7 @@ describe('Vimeo', () => {
});
it('should set the player color using the "color" prop', async () => {
- const { playerMock, sdkMock, rerender } = render({
+ const { playerMock, sdkMock, rerender } = await render({
video: 169408731,
color: '#0000ff',
});
@@ -107,7 +107,7 @@ describe('Vimeo', () => {
});
it('should set the looping flag using the "loop" prop', async () => {
- const { playerMock, sdkMock, rerender } = render({
+ const { playerMock, sdkMock, rerender } = await render({
video: 169408731,
loop: false,
});
@@ -121,7 +121,7 @@ describe('Vimeo', () => {
});
it('should set the iframe width/height using the width/height props', async () => {
- const { sdkMock, playerMock, rerender } = render({
+ const { sdkMock, playerMock, rerender } = await render({
video: 169408731,
width: 640,
height: 320,
@@ -141,7 +141,7 @@ describe('Vimeo', () => {
});
it('should set the playback rate using the "playbackRate" props', async () => {
- const { playerMock, rerender } = render({
+ const { playerMock, rerender } = await render({
video: 169408731,
playbackRate: 0.5,
});
@@ -154,13 +154,13 @@ describe('Vimeo', () => {
});
it('should destroy player when unmounting', async () => {
- const { playerMock, unmount } = render({
+ const { playerMock, unmount } = await render({
video: 169408731,
width: 640,
height: 320,
});
- await unmount();
+ unmount();
expect(playerMock.destroy).toHaveBeenCalled();
});
diff --git a/test/util/render.js b/test/util/render.js
index f45161d..bef2c64 100644
--- a/test/util/render.js
+++ b/test/util/render.js
@@ -5,12 +5,21 @@
import React from 'react';
import ReactDOM from 'react-dom';
+import { act } from 'react-dom/test-utils';
import env from 'min-react-env';
import createVimeo from './createVimeo';
-Object.assign(global, env);
+Object.assign(global, env, {
+ navigator: { userAgent: 'min-react-env' },
+});
-const render = (initialProps) => {
+const reactMajor = parseInt((ReactDOM.version || '16').split('.')[0], 10);
+
+function noAct(fn) {
+ return fn();
+}
+
+async function render(initialProps) {
const { Vimeo, sdkMock, playerMock } = createVimeo({
shouldFail: initialProps.shouldFail,
});
@@ -37,24 +46,34 @@ const render = (initialProps) => {
}
const div = env.document.createElement('div');
- const container = new Promise((resolve) => {
- // eslint-disable-next-line react/no-deprecated
- ReactDOM.render(, div);
+ let root;
+ if (reactMajor >= 18) {
+ const { createRoot } = await import('react-dom/client');
+ root = createRoot(div);
+ } else {
+ root = {
+ render(element) {
+ // eslint-disable-next-line react/no-deprecated
+ ReactDOM.render(element, div);
+ },
+ unmount() {
+ // eslint-disable-next-line react/no-deprecated
+ ReactDOM.unmountComponentAtNode(div);
+ },
+ };
+ }
+ const container = await new Promise((resolve) => {
+ root.render();
});
function rerender(newProps) {
- return container.then((wrapper) => (
- new Promise((resolve) => {
- wrapper.setState({ props: newProps }, () => {
- Promise.resolve().then(resolve);
- });
- })
- ));
+ return (act || noAct)(async () => {
+ container.setState({ props: newProps });
+ });
}
function unmount() {
- // eslint-disable-next-line react/no-deprecated
- ReactDOM.unmountComponentAtNode(div);
+ root.unmount();
}
return {
@@ -64,6 +83,6 @@ const render = (initialProps) => {
rerender,
unmount,
};
-};
+}
export default render;