Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
a53a6b4
Upgrade react/react-admin and migrate to vitest
Dreamsorcerer Jun 6, 2025
e8d424e
Update package.json
Dreamsorcerer Jun 6, 2025
c460e94
Update permissions.test.js
Dreamsorcerer Jun 6, 2025
5f77903
Update relationships.test.js
Dreamsorcerer Jun 6, 2025
76632b7
Update simple.test.js
Dreamsorcerer Jun 6, 2025
ec13338
Update vite.config.js
Dreamsorcerer Jun 6, 2025
fdd8862
Update vite.config.js
Dreamsorcerer Jun 6, 2025
a34dac1
Update vite.config.js
Dreamsorcerer Jun 6, 2025
ef5c7f7
Update vite.config.js
Dreamsorcerer Jun 6, 2025
50be4a0
Update vite.config.js
Dreamsorcerer Jun 6, 2025
fad4afe
Update vite.config.js
Dreamsorcerer Jun 6, 2025
0f59db7
Update vite.config.js
Dreamsorcerer Jun 6, 2025
1c08127
Update vite.config.js
Dreamsorcerer Jun 6, 2025
d85a6c3
Update vite.config.js
Dreamsorcerer Jun 6, 2025
62459ea
Delete admin-js/jest.config.js
Dreamsorcerer Jun 6, 2025
eb0e757
Update vite.config.js
Dreamsorcerer Jun 6, 2025
8a1d345
Update package.json
Dreamsorcerer Jun 6, 2025
c58f211
Update package.json
Dreamsorcerer Jun 6, 2025
412c7d4
Update package.json
Dreamsorcerer Jun 6, 2025
a03890a
Rename permissions.test.js to permissions.test.jsx
Dreamsorcerer Jun 6, 2025
044a8d3
Rename relationships.test.js to relationships.test.jsx
Dreamsorcerer Jun 6, 2025
29af5f0
Rename simple.test.js to simple.test.jsx
Dreamsorcerer Jun 6, 2025
c3416bb
Update vite.config.js
Dreamsorcerer Jun 6, 2025
f52f8ee
Rename setupTests.js to setupTests.jsx
Dreamsorcerer Jun 6, 2025
d204f22
Update vite.config.js
Dreamsorcerer Jun 6, 2025
4853b61
Update setupTests.jsx
Dreamsorcerer Jun 6, 2025
718bd55
Update setupTests.jsx
Dreamsorcerer Jun 6, 2025
85ede25
Update setupTests.jsx
Dreamsorcerer Jun 6, 2025
9e56794
Update setupTests.jsx
Dreamsorcerer Jun 6, 2025
1ea4d9e
Update vite.config.js
Dreamsorcerer Jun 6, 2025
d912182
Update admin-js/vite.config.js
Dreamsorcerer Jun 6, 2025
e326597
Update vite.config.js
Dreamsorcerer Jun 6, 2025
0584c75
Update setupTests.jsx
Dreamsorcerer Jun 6, 2025
2cc5f62
Update package.json
Dreamsorcerer Jun 6, 2025
9b1d77b
Update setupTests.jsx
Dreamsorcerer Jun 6, 2025
d9e5797
Update setupTests.jsx
Dreamsorcerer Jun 6, 2025
dc423cb
Update ci.yml
Dreamsorcerer Jun 6, 2025
f6b2d9e
Update setupTests.jsx
Dreamsorcerer Jun 6, 2025
3c8f33e
Update package.json
Dreamsorcerer Jun 6, 2025
82bf56e
Update setupTests.jsx
Dreamsorcerer Jun 7, 2025
0632696
Update vite.config.js
Dreamsorcerer Jun 7, 2025
fa67ee9
Update admin-js/tests/setupTests.jsx
Dreamsorcerer Jun 7, 2025
21adf93
Update admin-js/tests/setupTests.jsx
Dreamsorcerer Jun 7, 2025
19aed86
Update setupTests.jsx
Dreamsorcerer Jun 7, 2025
8866794
Update setupTests.jsx
Dreamsorcerer Jun 7, 2025
025e0b0
Update setupTests.jsx
Dreamsorcerer Jun 7, 2025
cd1318e
Update setupTests.jsx
Dreamsorcerer Jun 7, 2025
ea60b92
Update setupTests.jsx
Dreamsorcerer Jun 7, 2025
79ab8a0
Update setupTests.jsx
Dreamsorcerer Jun 7, 2025
4f82c1d
Update setupTests.jsx
Dreamsorcerer Jun 7, 2025
a73c96e
Update package.json
Dreamsorcerer Jun 7, 2025
6535c30
Update setupTests.jsx
Dreamsorcerer Jun 7, 2025
1f65bd6
Update package.json
Dreamsorcerer Jun 7, 2025
6d55047
Update admin-js/tests/setupTests.jsx
Dreamsorcerer Jun 9, 2025
7699b65
Update package.json
Dreamsorcerer Jun 9, 2025
fcccb62
Update admin-js/tests/setupTests.jsx
Dreamsorcerer Jun 9, 2025
f812b29
Update setupTests.jsx
Dreamsorcerer Jun 10, 2025
9b5d068
Update setupTests.jsx
Dreamsorcerer Jun 10, 2025
c027062
Update admin-js/tests/setupTests.jsx
Dreamsorcerer Jun 10, 2025
21cbfab
Update package.json
Dreamsorcerer Jun 10, 2025
f3b192d
Merge branch 'master' into Dreamsorcerer-patch-1
Dreamsorcerer Jun 10, 2025
06acca3
Update setupTests.jsx
Dreamsorcerer Jun 10, 2025
db34bb4
Update setupTests.jsx
Dreamsorcerer Jun 10, 2025
cad93ab
Update vite.config.js
Dreamsorcerer Jun 10, 2025
64f72a2
Update admin-js/vite.config.js
Dreamsorcerer Jun 11, 2025
b69f082
Update setupTests.jsx
Dreamsorcerer Jun 11, 2025
7218901
Update package.json
Dreamsorcerer Jun 11, 2025
d50baea
Update admin-js/tests/setupTests.jsx
Dreamsorcerer Jun 11, 2025
7baf5b1
Merge branch 'master' into Dreamsorcerer-patch-1
Dreamsorcerer Aug 4, 2026
14d109d
Update ci.yml
Dreamsorcerer Aug 28, 2026
6d58c2d
fix jsdom config so requests reach the test server (#1197)
Dreamsorcerer Aug 28, 2026
c9428c6
Apply suggestion from @Dreamsorcerer
Dreamsorcerer Aug 28, 2026
87736ad
Apply batched suggestions from code review
Dreamsorcerer Aug 28, 2026
e86bbab
Merge branch 'master' into Dreamsorcerer-patch-1
Dreamsorcerer Aug 28, 2026
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
4 changes: 1 addition & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ on:
- '[0-9].[0-9]+' # matches to backport branches, e.g. 3.6
tags: [ 'v*' ]
pull_request:
branches:
- master
- '[0-9].[0-9]+'


jobs:
Expand Down Expand Up @@ -162,6 +159,7 @@ jobs:
path: |
${{ env.yarn_cache }}
admin-js/node_modules
admin-js/yarn.lock
- name: Yarn install
run: yarn install
working-directory: admin-js/
Expand Down
12 changes: 0 additions & 12 deletions admin-js/jest.config.js

This file was deleted.

10 changes: 7 additions & 3 deletions admin-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@vitejs/plugin-react": "4.5.1",
"react": "18.2.0",
"react-admin": "4.16.7",
"react-dom": "18.2.0",
Expand Down Expand Up @@ -34,15 +35,18 @@
"@testing-library/react": "16.3.2",
"@testing-library/user-event": "14.6.6",
"@ungap/structured-clone": "1.3.3",
"jest": "30.4.2",
"jest-environment-jsdom": "30.4.1",
"@vitest/coverage-v8": "3.2.2",
"extend-expect": "3.0.0",
"jest-fail-on-console": "3.3.4",
"jsdom": "20.0.3",
"vitest": "3.2.2",
"vitest-location-mock": "1.0.1",
"whatwg-fetch": "3.6.20"
},
"scripts": {
"dev": "vite",
"build": "vite build",
"test": "jest"
"test": "vitest"
},
"eslintConfig": {
"extends": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {beforeAll, describe, expect, test} from "vitest";
import {within} from "@testing-library/dom";
import {screen, waitFor} from "@testing-library/react";
import userEvent from "@testing-library/user-event";
Expand Down Expand Up @@ -25,7 +26,7 @@
beforeAll(() => setLogin("filter", ""));

test("view", async () => {
const table = await screen.findByRole("table");

Check failure on line 29 in admin-js/tests/permissions.test.jsx

View workflow job for this annotation

GitHub Actions / Integration Test

tests/permissions.test.jsx > filter > view

TestingLibraryElementError: Unable to find role="table" Ignored nodes: comments, script, style <body> <div> <div class="MuiScopedCssBaseline-root css-1uodbwk-MuiScopedCssBaseline-root" > <div class="css-c1bgk0-RaLogin-root" > <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 MuiCard-root RaLogin-card css-bhp9pd-MuiPaper-root-MuiCard-root" > <div class="RaLogin-avatar" > <div class="MuiAvatar-root MuiAvatar-circular MuiAvatar-colorDefault RaLogin-icon css-iisrix-MuiAvatar-root" > <svg aria-hidden="true" class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root" data-testid="LockIcon" focusable="false" viewBox="0 0 24 24" > <path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2m-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2m3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1z" /> </svg> </div> </div> <form class="css-1tz8rwi-RaLoginForm-root" novalidate="" > <div class="MuiCardContent-root RaLoginForm-content css-46bh2p-MuiCardContent-root" > <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-username css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-colorPrimary MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled css-1mog9k0-MuiFormLabel-root-MuiInputLabel-root" data-shrink="false" for="username" id="username-label" > <span> Username <span aria-hidden="true" >  * </span> </span> </label> <div class="MuiInputBase-root MuiFilledInput-root MuiFilledInput-underline MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-sizeSmall css-1lm524j-MuiInputBase-root-MuiFilledInput-root" > <input aria-describedby="username-helper-text" aria-invalid="false" autocomplete="username" class="MuiInputBase-input MuiFilledInput-input MuiInputBase-inputSizeSmall css-1zuho2-MuiInputBase-input-MuiFilledInput-input" id="username" name="username" type="text" value="" /> </div> <p class="MuiFormHelperText-root MuiFormHelperText-sizeSmall MuiFormHelperText-contained css-k4qjio-MuiFormHelperText-root" id="username-helper-text" > <span> ​ </span> </p> </div> <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-password css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-colorPrimary MuiInputLabel-root MuiInputLabel-formControl Mu
const rows = within(table).getAllByRole("row").slice(1);
expect(rows).toHaveLength(5);
expect(rows.map(r => within(r).getAllByRole("cell")[1].textContent)).toEqual(["1", "3", "4", "5", "6"]);
Expand All @@ -49,7 +50,7 @@
await userEvent.click(await screen.findByRole("button", {"name": "Set to 7"}));
expect(await screen.findByText("Update 6 simples")).toBeInTheDocument();
await userEvent.click(screen.getByRole("button", {"name": "Confirm"}));
await waitFor(() => screen.getAllByText("7"));

Check failure on line 53 in admin-js/tests/permissions.test.jsx

View workflow job for this annotation

GitHub Actions / Integration Test

tests/permissions.test.jsx > admin > bulk update

TestingLibraryElementError: Unable to find an element with the text: 7. 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 style="" > <div> <div class="MuiScopedCssBaseline-root css-1uodbwk-MuiScopedCssBaseline-root" > <div class="css-c1bgk0-RaLogin-root" > <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 MuiCard-root RaLogin-card css-bhp9pd-MuiPaper-root-MuiCard-root" > <div class="RaLogin-avatar" > <div class="MuiAvatar-root MuiAvatar-circular MuiAvatar-colorDefault RaLogin-icon css-iisrix-MuiAvatar-root" > <svg aria-hidden="true" class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root" data-testid="LockIcon" focusable="false" viewBox="0 0 24 24" > <path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2m-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2m3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1z" /> </svg> </div> </div> <form class="css-1tz8rwi-RaLoginForm-root" novalidate="" > <div class="MuiCardContent-root RaLoginForm-content css-46bh2p-MuiCardContent-root" > <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-username css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-colorPrimary MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled css-1mog9k0-MuiFormLabel-root-MuiInputLabel-root" data-shrink="false" for="username" id="username-label" > <span> Username <span aria-hidden="true" >  * </span> </span> </label> <div class="MuiInputBase-root MuiFilledInput-root MuiFilledInput-underline MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-sizeSmall css-1lm524j-MuiInputBase-root-MuiFilledInput-root" > <input aria-describedby="username-helper-text" aria-invalid="false" autocomplete="username" class="MuiInputBase-input MuiFilledInput-input MuiInputBase-inputSizeSmall css-1zuho2-MuiInputBase-input-MuiFilledInput-input" id="username" name="username" type="text" value="" /> </div> <p class="MuiFormHelperText-root MuiFormHelperText-sizeSmall MuiFormHelperText-contained css-k4qjio-MuiFormHelperText-root" id="username-helper-text" > <span> ​ </span> </p> </div> <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-password css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabe

const table = await screen.findByRole("table");
const rows = within(table).getAllByRole("row");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {expect, test} from "vitest";
import {within} from "@testing-library/dom";
import {screen, waitFor} from "@testing-library/react";
import userEvent from "@testing-library/user-event";
Expand Down Expand Up @@ -32,7 +33,7 @@

test("onetomany child displays", async () => {
await userEvent.click(await screen.findByRole("button", {"name": "Open menu"}));
await userEvent.click(await screen.findByText("Onetomany children"));

Check failure on line 36 in admin-js/tests/relationships.test.jsx

View workflow job for this annotation

GitHub Actions / Integration Test

tests/relationships.test.jsx > onetomany child displays

TestingLibraryElementError: Unable to find an element with the text: Onetomany children. 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 style="" > <div> <div class="MuiScopedCssBaseline-root css-1uodbwk-MuiScopedCssBaseline-root" > <div class="css-c1bgk0-RaLogin-root" > <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 MuiCard-root RaLogin-card css-bhp9pd-MuiPaper-root-MuiCard-root" > <div class="RaLogin-avatar" > <div class="MuiAvatar-root MuiAvatar-circular MuiAvatar-colorDefault RaLogin-icon css-iisrix-MuiAvatar-root" > <svg aria-hidden="true" class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root" data-testid="LockIcon" focusable="false" viewBox="0 0 24 24" > <path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2m-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2m3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1z" /> </svg> </div> </div> <form class="css-1tz8rwi-RaLoginForm-root" novalidate="" > <div class="MuiCardContent-root RaLoginForm-content css-46bh2p-MuiCardContent-root" > <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-username css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-colorPrimary MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled css-1mog9k0-MuiFormLabel-root-MuiInputLabel-root" data-shrink="false" for="username" id="username-label" > <span> Username <span aria-hidden="true" >  * </span> </span> </label> <div class="MuiInputBase-root MuiFilledInput-root MuiFilledInput-underline MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-sizeSmall css-1lm524j-MuiInputBase-root-MuiFilledInput-root" > <input aria-describedby="username-helper-text" aria-invalid="false" autocomplete="username" class="MuiInputBase-input MuiFilledInput-input MuiInputBase-inputSizeSmall css-1zuho2-MuiInputBase-input-MuiFilledInput-input" id="username" name="username" type="text" value="" /> </div> <p class="MuiFormHelperText-root MuiFormHelperText-sizeSmall MuiFormHelperText-contained css-k4qjio-MuiFormHelperText-root" id="username-helper-text" > <span> ​ </span> </p> </div> <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-password css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label c

await waitFor(() => screen.getByRole("heading", {"name": "Onetomany children"}));
await sleep(1);
Expand Down Expand Up @@ -66,7 +67,7 @@
await userEvent.click(await screen.findByRole("button", {"name": "Open menu"}));
await userEvent.click(await screen.findByText("Onetoone parents"));

await waitFor(() => screen.getByRole("heading", {"name": "Onetoone parents"}));

Check failure on line 70 in admin-js/tests/relationships.test.jsx

View workflow job for this annotation

GitHub Actions / Integration Test

tests/relationships.test.jsx > onetoone parents display

TestingLibraryElementError: Unable to find role="heading" and name "Onetoone parents" Ignored nodes: comments, script, style <body style="" > <div> <div class="MuiScopedCssBaseline-root css-1uodbwk-MuiScopedCssBaseline-root" > <div class="css-c1bgk0-RaLogin-root" > <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 MuiCard-root RaLogin-card css-bhp9pd-MuiPaper-root-MuiCard-root" > <div class="RaLogin-avatar" > <div class="MuiAvatar-root MuiAvatar-circular MuiAvatar-colorDefault RaLogin-icon css-iisrix-MuiAvatar-root" > <svg aria-hidden="true" class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root" data-testid="LockIcon" focusable="false" viewBox="0 0 24 24" > <path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2m-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2m3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1z" /> </svg> </div> </div> <form class="css-1tz8rwi-RaLoginForm-root" novalidate="" > <div class="MuiCardContent-root RaLoginForm-content css-46bh2p-MuiCardContent-root" > <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-username css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-colorPrimary MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled css-1mog9k0-MuiFormLabel-root-MuiInputLabel-root" data-shrink="false" for="username" id="username-label" > <span> Username <span aria-hidden="true" >  * </span> </span> </label> <div class="MuiInputBase-root MuiFilledInput-root MuiFilledInput-underline MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-sizeSmall css-1lm524j-MuiInputBase-root-MuiFilledInput-root" > <input aria-describedby="username-helper-text" aria-invalid="false" autocomplete="username" class="MuiInputBase-input MuiFilledInput-input MuiInputBase-inputSizeSmall css-1zuho2-MuiInputBase-input-MuiFilledInput-input" id="username" name="username" type="text" value="" /> </div> <p class="MuiFormHelperText-root MuiFormHelperText-sizeSmall MuiFormHelperText-contained css-k4qjio-MuiFormHelperText-root" id="username-helper-text" > <span> ​ </span> </p> </div> <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-password css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-colorPrimary MuiIn
await sleep(1);

const table = screen.getByRole("table");
Expand All @@ -84,7 +85,7 @@

test("manytomany left displays", async () => {
await userEvent.click(await screen.findByRole("button", {"name": "Open menu"}));
await userEvent.click(await screen.findByText("Manytomany lefts"));

Check failure on line 88 in admin-js/tests/relationships.test.jsx

View workflow job for this annotation

GitHub Actions / Integration Test

tests/relationships.test.jsx > manytomany left displays

TestingLibraryElementError: Unable to find an element with the text: Manytomany lefts. 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 style="" > <div> <div class="MuiScopedCssBaseline-root css-1uodbwk-MuiScopedCssBaseline-root" > <div class="css-c1bgk0-RaLogin-root" > <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 MuiCard-root RaLogin-card css-bhp9pd-MuiPaper-root-MuiCard-root" > <div class="RaLogin-avatar" > <div class="MuiAvatar-root MuiAvatar-circular MuiAvatar-colorDefault RaLogin-icon css-iisrix-MuiAvatar-root" > <svg aria-hidden="true" class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root" data-testid="LockIcon" focusable="false" viewBox="0 0 24 24" > <path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2m-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2m3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1z" /> </svg> </div> </div> <form class="css-1tz8rwi-RaLoginForm-root" novalidate="" > <div class="MuiCardContent-root RaLoginForm-content css-46bh2p-MuiCardContent-root" > <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-username css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-colorPrimary MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled css-1mog9k0-MuiFormLabel-root-MuiInputLabel-root" data-shrink="false" for="username" id="username-label" > <span> Username <span aria-hidden="true" >  * </span> </span> </label> <div class="MuiInputBase-root MuiFilledInput-root MuiFilledInput-underline MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-sizeSmall css-1lm524j-MuiInputBase-root-MuiFilledInput-root" > <input aria-describedby="username-helper-text" aria-invalid="false" autocomplete="username" class="MuiInputBase-input MuiFilledInput-input MuiInputBase-inputSizeSmall css-1zuho2-MuiInputBase-input-MuiFilledInput-input" id="username" name="username" type="text" value="" /> </div> <p class="MuiFormHelperText-root MuiFormHelperText-sizeSmall MuiFormHelperText-contained css-k4qjio-MuiFormHelperText-root" id="username-helper-text" > <span> ​ </span> </p> </div> <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-password css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label cla

await waitFor(() => screen.getByRole("heading", {"name": "Manytomany lefts"}));
await sleep(1);
Expand Down Expand Up @@ -131,7 +132,7 @@

test("composite foreign key child displays table", async () => {
await userEvent.click(await screen.findByRole("button", {"name": "Open menu"}));
await userEvent.click(await screen.findByText("Composite foreign key children"));

Check failure on line 135 in admin-js/tests/relationships.test.jsx

View workflow job for this annotation

GitHub Actions / Integration Test

tests/relationships.test.jsx > composite foreign key child displays table

TestingLibraryElementError: Unable to find an element with the text: Composite foreign key children. 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 style="" > <div> <div class="MuiScopedCssBaseline-root css-1uodbwk-MuiScopedCssBaseline-root" > <div class="css-c1bgk0-RaLogin-root" > <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 MuiCard-root RaLogin-card css-bhp9pd-MuiPaper-root-MuiCard-root" > <div class="RaLogin-avatar" > <div class="MuiAvatar-root MuiAvatar-circular MuiAvatar-colorDefault RaLogin-icon css-iisrix-MuiAvatar-root" > <svg aria-hidden="true" class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root" data-testid="LockIcon" focusable="false" viewBox="0 0 24 24" > <path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2m-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2m3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1z" /> </svg> </div> </div> <form class="css-1tz8rwi-RaLoginForm-root" novalidate="" > <div class="MuiCardContent-root RaLoginForm-content css-46bh2p-MuiCardContent-root" > <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-username css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-colorPrimary MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled css-1mog9k0-MuiFormLabel-root-MuiInputLabel-root" data-shrink="false" for="username" id="username-label" > <span> Username <span aria-hidden="true" >  * </span> </span> </label> <div class="MuiInputBase-root MuiFilledInput-root MuiFilledInput-underline MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-sizeSmall css-1lm524j-MuiInputBase-root-MuiFilledInput-root" > <input aria-describedby="username-helper-text" aria-invalid="false" autocomplete="username" class="MuiInputBase-input MuiFilledInput-input MuiInputBase-inputSizeSmall css-1zuho2-MuiInputBase-input-MuiFilledInput-input" id="username" name="username" type="text" value="" /> </div> <p class="MuiFormHelperText-root MuiFormHelperText-sizeSmall MuiFormHelperText-contained css-k4qjio-MuiFormHelperText-root" id="username-helper-text" > <span> ​ </span> </p> </div> <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-password css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label

await waitFor(() => screen.getByRole("heading", {"name": "Composite foreign key children"}));
await userEvent.click(screen.getByRole("button", {"name": "Columns"}));
Expand All @@ -157,7 +158,7 @@
await userEvent.click(await screen.findByRole("button", {"name": "Open menu"}));
await userEvent.click(await screen.findByText("Composite foreign key parents"));

await waitFor(() => screen.getByRole("heading", {"name": "Composite foreign key parents"}));

Check failure on line 161 in admin-js/tests/relationships.test.jsx

View workflow job for this annotation

GitHub Actions / Integration Test

tests/relationships.test.jsx > composite foreign key parent displays

TestingLibraryElementError: Unable to find role="heading" and name "Composite foreign key parents" Ignored nodes: comments, script, style <body style="" > <div> <div class="MuiScopedCssBaseline-root css-1uodbwk-MuiScopedCssBaseline-root" > <div class="css-c1bgk0-RaLogin-root" > <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 MuiCard-root RaLogin-card css-bhp9pd-MuiPaper-root-MuiCard-root" > <div class="RaLogin-avatar" > <div class="MuiAvatar-root MuiAvatar-circular MuiAvatar-colorDefault RaLogin-icon css-iisrix-MuiAvatar-root" > <svg aria-hidden="true" class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root" data-testid="LockIcon" focusable="false" viewBox="0 0 24 24" > <path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2m-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2m3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1z" /> </svg> </div> </div> <form class="css-1tz8rwi-RaLoginForm-root" novalidate="" > <div class="MuiCardContent-root RaLoginForm-content css-46bh2p-MuiCardContent-root" > <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-username css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-colorPrimary MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled css-1mog9k0-MuiFormLabel-root-MuiInputLabel-root" data-shrink="false" for="username" id="username-label" > <span> Username <span aria-hidden="true" >  * </span> </span> </label> <div class="MuiInputBase-root MuiFilledInput-root MuiFilledInput-underline MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-sizeSmall css-1lm524j-MuiInputBase-root-MuiFilledInput-root" > <input aria-describedby="username-helper-text" aria-invalid="false" autocomplete="username" class="MuiInputBase-input MuiFilledInput-input MuiInputBase-inputSizeSmall css-1zuho2-MuiInputBase-input-MuiFilledInput-input" id="username" name="username" type="text" value="" /> </div> <p class="MuiFormHelperText-root MuiFormHelperText-sizeSmall MuiFormHelperText-contained css-k4qjio-MuiFormHelperText-root" id="username-helper-text" > <span> ​ </span> </p> </div> <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-password css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-color
await sleep(1);
const table = screen.getAllByRole("table")[0];
const rows = within(table).getAllByRole("row").filter((e) => e.parentElement.parentElement === table);
Expand All @@ -182,7 +183,7 @@
await userEvent.click(await screen.findByRole("button", {"name": "Open menu"}));
await userEvent.click(await screen.findByText("Composite foreign key parents"));

await waitFor(() => screen.getByRole("heading", {"name": "Composite foreign key parents"}));

Check failure on line 186 in admin-js/tests/relationships.test.jsx

View workflow job for this annotation

GitHub Actions / Integration Test

tests/relationships.test.jsx > composite foreign key reference input updates

TestingLibraryElementError: Unable to find role="heading" and name "Composite foreign key parents" Ignored nodes: comments, script, style <body style="" > <div> <div class="MuiScopedCssBaseline-root css-1uodbwk-MuiScopedCssBaseline-root" > <div class="css-c1bgk0-RaLogin-root" > <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 MuiCard-root RaLogin-card css-bhp9pd-MuiPaper-root-MuiCard-root" > <div class="RaLogin-avatar" > <div class="MuiAvatar-root MuiAvatar-circular MuiAvatar-colorDefault RaLogin-icon css-iisrix-MuiAvatar-root" > <svg aria-hidden="true" class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root" data-testid="LockIcon" focusable="false" viewBox="0 0 24 24" > <path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2m-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2m3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1z" /> </svg> </div> </div> <form class="css-1tz8rwi-RaLoginForm-root" novalidate="" > <div class="MuiCardContent-root RaLoginForm-content css-46bh2p-MuiCardContent-root" > <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-username css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-colorPrimary MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled css-1mog9k0-MuiFormLabel-root-MuiInputLabel-root" data-shrink="false" for="username" id="username-label" > <span> Username <span aria-hidden="true" >  * </span> </span> </label> <div class="MuiInputBase-root MuiFilledInput-root MuiFilledInput-underline MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-sizeSmall css-1lm524j-MuiInputBase-root-MuiFilledInput-root" > <input aria-describedby="username-helper-text" aria-invalid="false" autocomplete="username" class="MuiInputBase-input MuiFilledInput-input MuiInputBase-inputSizeSmall css-1zuho2-MuiInputBase-input-MuiFilledInput-input" id="username" name="username" type="text" value="" /> </div> <p class="MuiFormHelperText-root MuiFormHelperText-sizeSmall MuiFormHelperText-contained css-k4qjio-MuiFormHelperText-root" id="username-helper-text" > <span> ​ </span> </p> </div> <div class="MuiFormControl-root MuiFormControl-marginDense MuiFormControl-fullWidth MuiTextField-root ra-input ra-input-password css-1i5wpaj-MuiFormControl-root-MuiTextField-root-RaResettableTextField-root" > <label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-filled MuiFormLabel-color
const table = screen.getAllByRole("table")[0];
const rows = within(table).getAllByRole("row").filter((e) => e.parentElement.parentElement === table);
await userEvent.click(within(rows[1]).getByRole("link", {"name": "Edit"}));
Expand Down
28 changes: 16 additions & 12 deletions admin-js/tests/setupTests.js → admin-js/tests/setupTests.jsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
const http = require("http");
//import "vitest-location-mock";
const {spawn} = require("child_process");
import "whatwg-fetch"; // https://github.com/jsdom/jsdom/issues/1724
import "@testing-library/jest-dom";
import failOnConsole from "jest-fail-on-console";
//import failOnConsole from "jest-fail-on-console";
import {memoryStore} from "react-admin";
import {afterAll, beforeAll, beforeEach, expect} from "vitest";
Comment on lines +4 to +6

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 DOM matchers are unregistered

When the migrated tests evaluate toBeInTheDocument(), the setup no longer imports @testing-library/jest-dom, causing Vitest to reject the unknown matcher and fail the JavaScript test suite.

import "@testing-library/jest-dom/vitest";
import {configure, render, screen} from "@testing-library/react";
Comment thread
Dreamsorcerer marked this conversation as resolved.
import * as structuredClone from "@ungap/structured-clone";
//import * as structuredClone from "@ungap/structured-clone";

const {App} = require("../src/App");
delete globalThis.fetch;
await import("whatwg-fetch");

import {App} from "../src/App";

let pythonProcess;
let STATE;

jest.setTimeout(300000); // 5 mins
/*jest.setTimeout(300000); // 5 mins
configure({"asyncUtilTimeout": 10000});
jest.mock("react-admin", () => {
const originalModule = jest.requireActual("react-admin");
return {
...originalModule,
downloadCSV: jest.fn(), // Mock downloadCSV to test export button.
};
});
});*/
Comment on lines 21 to +27

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Export mock is disabled

When the export test clicks the Export button, this disabled module mock leaves downloadCSV as the real function, so the subsequent toHaveBeenCalled() and toHaveBeenCalledWith() assertions operate on a non-mock and fail the test.


// https://github.com/jsdom/jsdom/issues/3363#issuecomment-1387439541
global.structuredClone = structuredClone.default;
//global.structuredClone = structuredClone.default;

// To render full-width
window.matchMedia = (query) => ({
Expand All @@ -33,12 +37,12 @@ window.matchMedia = (query) => ({
});

// Ignore not implemented errors
window.scrollTo = jest.fn();
//window.scrollTo = jest.fn();


global.sleep = (delay_s) => new Promise((resolve) => setTimeout(resolve, delay_s * 1000));

failOnConsole({
/*failOnConsole({
silenceMessage: (msg) => {
return (
// Suppress act() warnings, because there's too many async changes happening.
Expand All @@ -49,7 +53,7 @@ failOnConsole({
|| msg.includes("The above error occurred in the <EditBase> component")
);
}
});
});*/

beforeAll(async() => {
if (!global.pythonProcessPath)
Expand Down Expand Up @@ -103,7 +107,7 @@ beforeEach(async () => {
localStorage.clear();

if (STATE) {
const resp = await fetch("http://localhost:8080/admin/token", {"method": "POST", "body": JSON.stringify(login)});
const resp = await fetch("/admin/token", {"method": "POST", "body": JSON.stringify(login)});
localStorage.setItem("identity", resp.headers.get("X-Token"));
render(<App aiohttpState={STATE} store={memoryStore()} />);
const profile = await screen.findByText(login["username"], {"exact": false});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {expect, test} from "vitest";
import {within} from "@testing-library/dom";
import {screen, waitFor} from "@testing-library/react";
import userEvent from "@testing-library/user-event";
Expand Down
24 changes: 23 additions & 1 deletion admin-js/vite.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import {defineConfig} from "vite";

export default defineConfig({
build: {
Expand All @@ -12,4 +13,25 @@ export default defineConfig({
},
sourcemap: true,
},
plugins: [react()],
test: {
clearMocks: true,
coverage: {
exclude: [],
},
environment: "jsdom",
environmentOptions: {
jsdom: {
url: "http://localhost:8080",
pretendToBeVisual: true
}
},
expect: {
requireAssertions: true
},
fileParallelism: false,
mockReset: true,
restoreMocks: true,
setupFiles: "tests/setupTests.jsx",
}
})
Loading