Skip to content

Use Vitest browser to test react-admin #10479

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -87,6 +87,8 @@ jobs:
cache: 'yarn'
- name: Install dependencies
run: yarn
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Unit Tests
run: make test-unit
env:
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -23,3 +23,4 @@ cypress/screenshots
!.yarn/releases
!.yarn/sdks
!.yarn/versions
__screenshots__
15 changes: 0 additions & 15 deletions __mocks__/@popperjs/core.ts

This file was deleted.

41 changes: 0 additions & 41 deletions jest.config.js

This file was deleted.

19 changes: 8 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -4,9 +4,9 @@
"scripts": {
"build": "lerna run build",
"watch": "lerna run --parallel watch",
"test-unit": "cross-env NODE_ENV=test cross-env BABEL_ENV=cjs NODE_ICU_DATA=./node_modules/full-icu jest",
"test-unit-ci": "cross-env NODE_ENV=test cross-env BABEL_ENV=cjs NODE_ICU_DATA=./node_modules/full-icu jest --runInBand",
"test-e2e": "yarn run -s build && cross-env NODE_ENV=test && cd cypress && yarn test",
"test-unit": "cross-env NODE_ENV=test cross-env BABEL_ENV=cjs NODE_ICU_DATA=./node_modules/full-icu vitest run --no-file-parallelism --browser.headless",
"test-unit-ci": "cross-env NODE_ENV=test cross-env BABEL_ENV=cjs NODE_ICU_DATA=./node_modules/full-icu vitest run --no-file-parallelism",
"test-e2e": "yarn run -s build && cross-env NODE_ENV=test && cd cypress && yarn test",
"test-e2e-local": "cd cypress && yarn start",
"test": "yarn test-unit && yarn test-e2e",
"doc": "cd docs && jekyll server . --watch --host 0.0.0.0",
@@ -32,10 +32,11 @@
"@storybook/react": "^8.4.4",
"@storybook/react-webpack5": "^8.4.4",
"@storybook/source-loader": "patch:@storybook/source-loader@npm%3A8.4.4#~/.yarn/patches/@storybook-source-loader-npm-8.4.4-55dafc88e2.patch",
"@types/jest": "^29.5.2",
"@types/react": "^18.3.3",
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.60.0",
"@vitejs/plugin-react": "^4.3.4",
"@vitest/browser": "^3.0.4",
"cross-env": "^5.2.0",
"eslint": "^8.19.0",
"eslint-config-prettier": "^9.1.0",
@@ -44,23 +45,19 @@
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-testing-library": "^5.11.0",
"full-icu": "^1.3.1",
"global-jsdom": "^9.0.1",
"husky": "^2.3.0",
"jest": "^29.5.0",
"jest-circus": "29.5.0",
"jest-environment-jsdom": "^29.5.0",
"jest-resolve": "29.5.0",
"jest-watch-typeahead": "2.2.2",
"lerna": "~7.1.3",
"lint-staged": "^13.0.3",
"lolex": "~2.3.2",
"playwright": "^1.50.0",
"prettier": "~3.2.5",
"raf": "~3.4.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"storybook": "^8.4.4",
"ts-jest": "^29.1.0",
"typescript": "^5.1.3",
"vitest": "^3.0.4",
"vitest-browser-react": "^0.0.4",
"whatwg-fetch": "^3.0.0"
},
"workspaces": [
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import expect from 'expect';
import { expect } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import { createMemoryHistory } from 'history';
import { Routes, Route, useLocation } from 'react-router-dom';
@@ -20,12 +20,12 @@ describe('<Authenticated>', () => {
const authProvider = {
login: () => Promise.reject('bad method'),
logout: () => Promise.reject('bad method'),
checkAuth: jest.fn().mockResolvedValueOnce(''),
checkAuth: vi.fn().mockResolvedValueOnce(''),
checkError: () => Promise.reject('bad method'),
getPermissions: () => Promise.reject('bad method'),
};
const store = memoryStore();
const reset = jest.spyOn(store, 'reset');
const reset = vi.spyOn(store, 'reset');

render(
<CoreAdminContext authProvider={authProvider} store={store}>
@@ -40,14 +40,14 @@ describe('<Authenticated>', () => {

it('should logout, redirect to login and show a notification after a tick if the auth fails', async () => {
const authProvider = {
login: jest.fn().mockResolvedValue(''),
logout: jest.fn().mockResolvedValue(''),
checkAuth: jest.fn().mockRejectedValue(undefined),
checkError: jest.fn().mockResolvedValue(''),
getPermissions: jest.fn().mockResolvedValue(''),
login: vi.fn().mockResolvedValue(''),
logout: vi.fn().mockResolvedValue(''),
checkAuth: vi.fn().mockRejectedValue(undefined),
checkError: vi.fn().mockResolvedValue(''),
getPermissions: vi.fn().mockResolvedValue(''),
};
const store = memoryStore();
const reset = jest.spyOn(store, 'reset');
const reset = vi.spyOn(store, 'reset');
const history = createMemoryHistory();

const Login = () => {
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import expect from 'expect';
import { expect } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import { TestMemoryRouter } from 'react-admin';
import { Routes, Route, useLocation } from 'react-router-dom';
@@ -20,12 +20,12 @@ describe('<Authenticated>', () => {
const authProvider = {
login: () => Promise.reject('bad method'),
logout: () => Promise.reject('bad method'),
checkAuth: jest.fn().mockResolvedValueOnce(''),
checkAuth: vi.fn().mockResolvedValueOnce(''),
checkError: () => Promise.reject('bad method'),
getPermissions: () => Promise.reject('bad method'),
};
const store = memoryStore();
const reset = jest.spyOn(store, 'reset');
const reset = vi.spyOn(store, 'reset');

render(
<CoreAdminContext authProvider={authProvider} store={store}>
@@ -40,14 +40,14 @@ describe('<Authenticated>', () => {

it('should logout, redirect to login and show a notification after a tick if the auth fails', async () => {
const authProvider = {
login: jest.fn().mockResolvedValue(''),
logout: jest.fn().mockResolvedValue(''),
checkAuth: jest.fn().mockRejectedValue(undefined),
checkError: jest.fn().mockResolvedValue(''),
getPermissions: jest.fn().mockResolvedValue(''),
login: vi.fn().mockResolvedValue(''),
logout: vi.fn().mockResolvedValue(''),
checkAuth: vi.fn().mockRejectedValue(undefined),
checkError: vi.fn().mockResolvedValue(''),
getPermissions: vi.fn().mockResolvedValue(''),
};
const store = memoryStore();
const reset = jest.spyOn(store, 'reset');
const reset = vi.spyOn(store, 'reset');

const Login = () => {
const location = useLocation();
Loading

Unchanged files with check annotations Beta

value: Store,
children,
}: StoreContextProviderProps) => {
useEffect(() => {

Check failure on line 10 in packages/ra-core/src/store/StoreContextProvider.tsx

GitHub Actions / unit-test

packages/ra-core/src/core/Resource.spec.tsx > <Resource> > renders resource routes by default

TestingLibraryElementError: Unable to find an element with the text: PostList. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible. Ignored nodes: comments, script, style <body> <div> <h2> Unexpected Application Error! </h2> <h3 style="font-style: italic;" > Cannot read properties of null (reading 'useEffect') </h3> <pre style="padding: 0.5rem; background-color: rgba(200, 200, 200, 0.5);" > TypeError: Cannot read properties of null (reading 'useEffect') at useEffect (http://localhost:63315/node_modules/.vite/deps/chunk-ZMLY2J2T.js?v=2fed52ba:1078:29) at StoreContextProvider (http://localhost:63315/packages/ra-core/src/store/StoreContextProvider.tsx:8:3) at renderWithHooks (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:11414:26) at mountIndeterminateComponent (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:14792:21) at beginWork (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:15780:22) at beginWork$1 (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:19624:22) at performUnitOfWork (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:19072:20) at workLoopSync (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:19008:13) at renderRootSync (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:18987:15) at recoverFromConcurrentError (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:18604:28) </pre> <p> 💿 Hey developer 👋 </p> <p> You can provide a way better UX than this when your app throws errors by providing your own <code style="padding: 2px 4px; background-color: rgba(200, 200, 200, 0.5);" > ErrorBoundary </code> or <code style="padding: 2px 4px; background-color: rgba(200, 200, 200, 0.5);" > errorElement </code> prop on your route. </p> </div> </body> Ignored nodes: comments, script, style <body> <div> <h2> Unexpected Application Error! </h2> <h3 style="font-style: italic;" > Cannot read properties of null (reading 'useEffect') </h3> <pre style="padding: 0.5rem; background-color: rgba(200, 200, 200, 0.5);" > TypeError: Cannot read properties of null (reading 'useEffect') at useEffect (http://localhost:63315/node_modules/.vite/deps/chunk-ZMLY2J2T.js?v=2fed52ba:1078:29) at StoreContextProvider (http://localhost:63315/packages/ra-core/src/store/StoreContextProvider.tsx:8:3) at renderWithHooks (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:11414:26) at mountIndeterminateComponent (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:14792:21) at beginWork (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:15780:22) at beginWork$1 (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:19624:22) at performUnitOfWork (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:19072:20) at workLoopSync (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:19008:13) at renderRootSync (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:18987:15) at recoverFromConcurrentError (http://localhost:63315/node_modules/.vite/deps/chunk-VCHWBZ6P.js?v=ce568e40:18604:28) </pre> <p> 💿 Hey developer 👋 </p> <p> You can provide a way better UX than this when your app throws errors by providing your own <code style="padding: 2px 4px; background-color: rgba(200, 200, 200, 0.5);" > ErrorBoundary </code> or <code style="p
Store.setup();
return () => {
Store.teardown();
): RecordType | undefined => {
// Can't find a way to specify the RecordType when CreateContext is declared
// @ts-ignore
const context = useContext<RecordType | undefined>(RecordContext);

Check failure on line 40 in packages/ra-core/src/controller/record/useRecordContext.ts

GitHub Actions / unit-test

packages/ra-core/src/dataProvider/useGetRecordId.spec.tsx > useGetRecordId > should return the record id it received in options

TypeError: Cannot read properties of null (reading 'useContext') ❯ useRecordContext packages/ra-core/src/controller/record/useRecordContext.ts:40:20 ❯ useGetRecordId packages/ra-core/src/dataProvider/useGetRecordId.ts:18:26 ❯ UseGetRecordId packages/ra-core/src/dataProvider/useGetRecordId.spec.tsx:9:22

Check failure on line 40 in packages/ra-core/src/controller/record/useRecordContext.ts

GitHub Actions / unit-test

packages/ra-core/src/dataProvider/useGetRecordId.spec.tsx > useGetRecordId > should return the record id it received in options even if it is falsy

TypeError: Cannot read properties of null (reading 'useContext') ❯ useRecordContext packages/ra-core/src/controller/record/useRecordContext.ts:40:20 ❯ useGetRecordId packages/ra-core/src/dataProvider/useGetRecordId.ts:18:26 ❯ UseGetRecordId packages/ra-core/src/dataProvider/useGetRecordId.spec.tsx:9:22

Check failure on line 40 in packages/ra-core/src/controller/record/useRecordContext.ts

GitHub Actions / unit-test

packages/ra-core/src/dataProvider/useGetRecordId.spec.tsx > useGetRecordId > should return the record id it received through the record context

TypeError: Cannot read properties of null (reading 'useContext') ❯ useRecordContext packages/ra-core/src/controller/record/useRecordContext.ts:40:20 ❯ useGetRecordId packages/ra-core/src/dataProvider/useGetRecordId.ts:18:26 ❯ UseGetRecordId packages/ra-core/src/dataProvider/useGetRecordId.spec.tsx:9:22

Check failure on line 40 in packages/ra-core/src/controller/record/useRecordContext.ts

GitHub Actions / unit-test

packages/ra-core/src/dataProvider/useGetRecordId.spec.tsx > useGetRecordId > should return the record id it received through the record context even if it is falsy

TypeError: Cannot read properties of null (reading 'useContext') ❯ useRecordContext packages/ra-core/src/controller/record/useRecordContext.ts:40:20 ❯ useGetRecordId packages/ra-core/src/dataProvider/useGetRecordId.ts:18:26 ❯ UseGetRecordId packages/ra-core/src/dataProvider/useGetRecordId.spec.tsx:9:22
return (props && props.record) || context;
};
React-admin requires a valid dataProvider function to work.`);
}
const finalQueryClient = useMemo(

Check failure on line 185 in packages/ra-core/src/core/CoreAdminContext.tsx

GitHub Actions / unit-test

packages/ra-core/src/dataProvider/useUpdate.spec.tsx > useUpdate > mutate > returns a callback that can be used with update arguments

TypeError: Cannot read properties of null (reading 'useMemo') ❯ CoreAdminContext packages/ra-core/src/core/CoreAdminContext.tsx:185:29

Check failure on line 185 in packages/ra-core/src/core/CoreAdminContext.tsx

GitHub Actions / unit-test

packages/ra-core/src/dataProvider/useUpdate.spec.tsx > useUpdate > mutate > returns a callback that can be used with no arguments

TypeError: Cannot read properties of null (reading 'useMemo') ❯ CoreAdminContext packages/ra-core/src/core/CoreAdminContext.tsx:185:29

Check failure on line 185 in packages/ra-core/src/core/CoreAdminContext.tsx

GitHub Actions / unit-test

packages/ra-core/src/dataProvider/useUpdate.spec.tsx > useUpdate > mutate > accepts falsy value that are not null nor undefined as the record id

TypeError: Cannot read properties of null (reading 'useMemo') ❯ CoreAdminContext packages/ra-core/src/core/CoreAdminContext.tsx:185:29
() => queryClient || new QueryClient(),
[queryClient]
);