diff --git a/.circleci/config.yml b/.circleci/config.yml
index adb1bf6c916be..406c6b65159fa 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -199,7 +199,7 @@ jobs:
test_browser:
<<: *default-job
docker:
- - image: mcr.microsoft.com/playwright:v1.44.1-focal
+ - image: mcr.microsoft.com/playwright:v1.46.0-focal
environment:
NODE_ENV: development # Needed if playwright is in `devDependencies`
steps:
@@ -232,7 +232,7 @@ jobs:
test_e2e:
<<: *default-job
docker:
- - image: mcr.microsoft.com/playwright:v1.44.1-focal
+ - image: mcr.microsoft.com/playwright:v1.46.0-focal
environment:
NODE_ENV: development # Needed if playwright is in `devDependencies`
steps:
@@ -245,7 +245,7 @@ jobs:
test_e2e_website:
<<: *default-job
docker:
- - image: mcr.microsoft.com/playwright:v1.44.1-focal
+ - image: mcr.microsoft.com/playwright:v1.46.0-focal
environment:
NODE_ENV: development # Needed if playwright is in `devDependencies`
steps:
@@ -260,7 +260,7 @@ jobs:
test_regressions:
<<: *default-job
docker:
- - image: mcr.microsoft.com/playwright:v1.44.1-focal
+ - image: mcr.microsoft.com/playwright:v1.46.0-focal
environment:
NODE_ENV: development # Needed if playwright is in `devDependencies`
steps:
diff --git a/.eslintrc.js b/.eslintrc.js
index f4762cac6c026..59aab812859c9 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -269,6 +269,12 @@ module.exports = {
],
},
},
+ {
+ files: ['packages/*/src/**/*.e2e.spec{.ts,.tsx,.js}'],
+ rules: {
+ 'react/react-in-jsx-scope': 'off',
+ },
+ },
...buildPackageRestrictedImports('@mui/x-charts', 'x-charts', false),
...buildPackageRestrictedImports('@mui/x-charts-pro', 'x-charts-pro', false),
...buildPackageRestrictedImports('@mui/x-codemod', 'x-codemod', false),
diff --git a/.gitignore b/.gitignore
index ca6bf0461cd64..79b2169dfd187 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,8 @@ performance-snapshot.json
.github/styles/Google
.github/styles/MUI
.github/styles/.vale-config
+**/test-results/
+**/playwright-report/
+**/blob-report/
+**/playwright/.cache/
+
diff --git a/package.json b/package.json
index 8c37f4d776b6b..d93d73b33235e 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,7 @@
"test:e2e:server": "serve test/e2e -p 5001",
"test:e2e-website": "npx playwright test test/e2e-website --config test/e2e-website/playwright.config.ts",
"test:e2e-website:dev": "PLAYWRIGHT_TEST_BASE_URL=http://localhost:3001 npx playwright test test/e2e-website --config test/e2e-website/playwright.config.ts",
+ "test:e2e:charts": "playwright test -c ./test/e2e-charts/playwright-ct.config.ts",
"test:regressions": "cross-env NODE_ENV=production pnpm test:regressions:build && concurrently --success first --kill-others \"pnpm test:regressions:run\" \"pnpm test:regressions:server\"",
"test:regressions:build": "webpack --config test/regressions/webpack.config.js",
"test:regressions:dev": "concurrently \"pnpm test:regressions:build --watch\" \"pnpm test:regressions:server\"",
@@ -94,9 +95,10 @@
"@next/eslint-plugin-next": "14.2.4",
"@octokit/plugin-retry": "^7.1.1",
"@octokit/rest": "^21.0.0",
- "@playwright/test": "^1.44.1",
- "@types/babel__traverse": "^7.20.6",
+ "@playwright/experimental-ct-react": "1.46.0",
+ "@playwright/test": "1.46.0",
"@types/babel__core": "^7.20.5",
+ "@types/babel__traverse": "^7.20.6",
"@types/chai": "^4.3.16",
"@types/chai-dom": "^1.11.3",
"@types/fs-extra": "^11.0.4",
diff --git a/packages/x-charts/src/ChartsTooltip/ChartsTooltip.e2e.spec.tsx b/packages/x-charts/src/ChartsTooltip/ChartsTooltip.e2e.spec.tsx
new file mode 100644
index 0000000000000..04184aef5680e
--- /dev/null
+++ b/packages/x-charts/src/ChartsTooltip/ChartsTooltip.e2e.spec.tsx
@@ -0,0 +1,53 @@
+import { test, expect } from '@playwright/experimental-ct-react';
+import { BarChartTest } from './ChartsTooltip.e2e.stories';
+
+test.use({ viewport: { width: 500, height: 500 } });
+
+test.describe('', () => {
+ test('should display tooltip on item hover', async ({ mount, page }) => {
+ const component = await mount();
+
+ await component.getByText('100').hover({ force: true });
+
+ expect(await page.getByRole('tooltip').isVisible()).toBe(true);
+ expect(await page.getByRole('tooltip').textContent()).toBe('100');
+ });
+
+ test('should display tooltip when dragging over multiple items with touch', async ({
+ mount,
+ page,
+ hasTouch,
+ }) => {
+ test.skip(!hasTouch, 'Test touch only on touch devices');
+
+ const component = await mount();
+
+ const first = (await component.getByText('100').boundingBox())!;
+ const second = (await component.getByText('200').boundingBox())!;
+
+ const getCenter = (box: { x: number; y: number; width: number; height: number }) => ({
+ x: box.x + box.width / 2,
+ y: box.y + box.height / 2,
+ });
+
+ // Wait for playwright v1.46.0 to land
+ // https://github.com/microsoft/playwright/pull/31457
+ await page.touchscreen.touch('touchstart', [{ x: 0, y: 0 }]);
+
+ expect(await page.getByRole('tooltip').isVisible()).toBe(false);
+
+ await page.touchscreen.touch('touchmove', [getCenter(first)]);
+
+ expect(await page.getByRole('tooltip').isVisible()).toBe(true);
+ expect(await page.getByRole('tooltip').textContent()).toBe('100');
+
+ await page.touchscreen.touch('touchmove', [getCenter(second)]);
+
+ expect(await page.getByRole('tooltip').isVisible()).toBe(true);
+ expect(await page.getByRole('tooltip').textContent()).toBe('200');
+
+ await page.touchscreen.touch('touchend', [getCenter(second)]);
+
+ expect(await page.getByRole('tooltip').isVisible()).toBe(false);
+ });
+});
diff --git a/packages/x-charts/src/ChartsTooltip/ChartsTooltip.e2e.stories.tsx b/packages/x-charts/src/ChartsTooltip/ChartsTooltip.e2e.stories.tsx
new file mode 100644
index 0000000000000..4fca08fbf92a3
--- /dev/null
+++ b/packages/x-charts/src/ChartsTooltip/ChartsTooltip.e2e.stories.tsx
@@ -0,0 +1,22 @@
+import * as React from 'react';
+import { BarChart } from '../BarChart';
+
+export function BarChartTest() {
+ return (
+
+ );
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 131f1e9fb22eb..b6aec28cc9ff5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -104,9 +104,12 @@ importers:
'@octokit/rest':
specifier: ^21.0.0
version: 21.0.0
+ '@playwright/experimental-ct-react':
+ specifier: 1.46.0
+ version: 1.46.0(@types/node@18.19.39)(terser@5.27.0)(vite@5.3.2(@types/node@18.19.39)(terser@5.27.0))
'@playwright/test':
- specifier: ^1.44.1
- version: 1.44.1
+ specifier: 1.46.0
+ version: 1.46.0
'@types/babel__core':
specifier: ^7.20.5
version: 7.20.5
@@ -433,7 +436,7 @@ importers:
version: 5.15.21(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@mui/material-nextjs':
specifier: ^5.15.11
- version: 5.15.11(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@5.15.21(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+ version: 5.15.11(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@5.15.21(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
'@mui/styles':
specifier: ^5.15.21
version: 5.15.21(@types/react@18.3.3)(react@18.3.1)
@@ -562,7 +565,7 @@ importers:
version: 0.5.45
next:
specifier: ^14.2.4
- version: 14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ version: 14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
nprogress:
specifier: ^0.2.0
version: 0.2.0
@@ -1462,9 +1465,6 @@ importers:
'@mui/x-license':
specifier: workspace:*
version: link:../packages/x-license/build
- '@playwright/test':
- specifier: ^1.44.1
- version: 1.44.1
'@react-spring/web':
specifier: ^9.7.3
version: 9.7.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -2137,6 +2137,18 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
+ '@babel/plugin-transform-react-jsx-self@7.24.7':
+ resolution: {integrity: sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-transform-react-jsx-source@7.24.7':
+ resolution: {integrity: sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
'@babel/plugin-transform-react-jsx@7.24.7':
resolution: {integrity: sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==}
engines: {node: '>=6.9.0'}
@@ -3361,9 +3373,18 @@ packages:
resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
- '@playwright/test@1.44.1':
- resolution: {integrity: sha512-1hZ4TNvD5z9VuhNJ/walIjvMVvYkZKf71axoF/uiAqpntQJXpG64dlXhoDXE3OczPuTuvjf/M5KWFg5VAVUS3Q==}
- engines: {node: '>=16'}
+ '@playwright/experimental-ct-core@1.46.0':
+ resolution: {integrity: sha512-4bHw+P0ub0A/B6tbiqLQFwvaR+wsH5fE2yt1rxWg/dtE8uGhqEeAav9TX7j4PmILM86R3Le21h94wdDIHyeJBA==}
+ engines: {node: '>=18'}
+
+ '@playwright/experimental-ct-react@1.46.0':
+ resolution: {integrity: sha512-BSEfTBes2ljEQZxmtPpEQi8ZJns+B9F5h226Fk4/DdJbvueriEcJa4uls6KRIScSX8gd27Vg3P9T/buxW2BvjA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ '@playwright/test@1.46.0':
+ resolution: {integrity: sha512-/QYft5VArOrGRP5pgkrfKksqsKA6CEFyGQ/gjNe6q0y4tZ1aaPfq4gIjudr1s3D+pXyrPRdsy4opKDrjBabE5w==}
+ engines: {node: '>=18'}
hasBin: true
'@polka/url@1.0.0-next.24':
@@ -3403,6 +3424,86 @@ packages:
resolution: {integrity: sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==}
engines: {node: '>=14.0.0'}
+ '@rollup/rollup-android-arm-eabi@4.18.0':
+ resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.18.0':
+ resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.18.0':
+ resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.18.0':
+ resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.18.0':
+ resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.18.0':
+ resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.18.0':
+ resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.18.0':
+ resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.18.0':
+ resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.18.0':
+ resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.18.0':
+ resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.18.0':
+ resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.18.0':
+ resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-win32-arm64-msvc@4.18.0':
+ resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.18.0':
+ resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.18.0':
+ resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==}
+ cpu: [x64]
+ os: [win32]
+
'@sec-ant/readable-stream@0.4.1':
resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
@@ -3846,6 +3947,12 @@ packages:
'@ungap/structured-clone@1.2.0':
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
+ '@vitejs/plugin-react@4.3.1':
+ resolution: {integrity: sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ vite: ^4.2.0 || ^5.0.0
+
'@webassemblyjs/ast@1.12.1':
resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==}
@@ -7901,11 +8008,21 @@ packages:
engines: {node: '>=16'}
hasBin: true
+ playwright-core@1.46.0:
+ resolution: {integrity: sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==}
+ engines: {node: '>=18'}
+ hasBin: true
+
playwright@1.44.1:
resolution: {integrity: sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==}
engines: {node: '>=16'}
hasBin: true
+ playwright@1.46.0:
+ resolution: {integrity: sha512-XYJ5WvfefWONh1uPAUAi0H2xXV5S3vrtcnXe6uAOgdGi3aSpqOSXX08IAjXW34xitfuOJsvXU5anXZxPSEQiJw==}
+ engines: {node: '>=18'}
+ hasBin: true
+
please-upgrade-node@3.2.0:
resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==}
@@ -8103,6 +8220,10 @@ packages:
react-is@18.3.1:
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
+ react-refresh@0.14.2:
+ resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
+ engines: {node: '>=0.10.0'}
+
react-router-dom@6.23.1:
resolution: {integrity: sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==}
engines: {node: '>=14.0.0'}
@@ -8376,6 +8497,11 @@ packages:
robust-predicates@3.0.2:
resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==}
+ rollup@4.18.0:
+ resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
rrweb-cssom@0.6.0:
resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==}
@@ -9226,6 +9352,34 @@ packages:
vfile@4.2.1:
resolution: {integrity: sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==}
+ vite@5.3.2:
+ resolution: {integrity: sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.19.39
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+
void-elements@2.0.1:
resolution: {integrity: sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==}
engines: {node: '>=0.10.0'}
@@ -10286,6 +10440,16 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@babel/plugin-transform-react-jsx-self@7.24.7(@babel/core@7.24.7)':
+ dependencies:
+ '@babel/core': 7.24.7
+ '@babel/helper-plugin-utils': 7.24.7
+
+ '@babel/plugin-transform-react-jsx-source@7.24.7(@babel/core@7.24.7)':
+ dependencies:
+ '@babel/core': 7.24.7
+ '@babel/helper-plugin-utils': 7.24.7
+
'@babel/plugin-transform-react-jsx@7.24.7(@babel/core@7.24.7)':
dependencies:
'@babel/core': 7.24.7
@@ -11162,11 +11326,11 @@ snapshots:
'@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
'@types/react': 18.3.3
- '@mui/material-nextjs@5.15.11(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@5.15.21(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
+ '@mui/material-nextjs@5.15.11(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@5.15.21(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.24.7
'@mui/material': 5.15.21(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- next: 14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ next: 14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
optionalDependencies:
'@emotion/cache': 11.11.0
@@ -11781,9 +11945,38 @@ snapshots:
'@pkgr/core@0.1.1': {}
- '@playwright/test@1.44.1':
+ '@playwright/experimental-ct-core@1.46.0(@types/node@18.19.39)(terser@5.27.0)':
dependencies:
- playwright: 1.44.1
+ playwright: 1.46.0
+ playwright-core: 1.46.0
+ vite: 5.3.2(@types/node@18.19.39)(terser@5.27.0)
+ transitivePeerDependencies:
+ - '@types/node'
+ - less
+ - lightningcss
+ - sass
+ - stylus
+ - sugarss
+ - terser
+
+ '@playwright/experimental-ct-react@1.46.0(@types/node@18.19.39)(terser@5.27.0)(vite@5.3.2(@types/node@18.19.39)(terser@5.27.0))':
+ dependencies:
+ '@playwright/experimental-ct-core': 1.46.0(@types/node@18.19.39)(terser@5.27.0)
+ '@vitejs/plugin-react': 4.3.1(vite@5.3.2(@types/node@18.19.39)(terser@5.27.0))
+ transitivePeerDependencies:
+ - '@types/node'
+ - less
+ - lightningcss
+ - sass
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ - vite
+
+ '@playwright/test@1.46.0':
+ dependencies:
+ playwright: 1.46.0
'@polka/url@1.0.0-next.24': {}
@@ -11822,6 +12015,54 @@ snapshots:
'@remix-run/router@1.16.1': {}
+ '@rollup/rollup-android-arm-eabi@4.18.0':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.18.0':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.18.0':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.18.0':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.18.0':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.18.0':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.18.0':
+ optional: true
+
'@sec-ant/readable-stream@0.4.1': {}
'@sigstore/bundle@1.1.0':
@@ -12376,6 +12617,17 @@ snapshots:
'@ungap/structured-clone@1.2.0': {}
+ '@vitejs/plugin-react@4.3.1(vite@5.3.2(@types/node@18.19.39)(terser@5.27.0))':
+ dependencies:
+ '@babel/core': 7.24.7
+ '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.24.7)
+ '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.24.7)
+ '@types/babel__core': 7.20.5
+ react-refresh: 0.14.2
+ vite: 5.3.2(@types/node@18.19.39)(terser@5.27.0)
+ transitivePeerDependencies:
+ - supports-color
+
'@webassemblyjs/ast@1.12.1':
dependencies:
'@webassemblyjs/helper-numbers': 1.11.6
@@ -16586,7 +16838,7 @@ snapshots:
nested-error-stacks@2.1.1: {}
- next@14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ next@14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@next/env': 14.2.4
'@swc/helpers': 0.5.5
@@ -16608,7 +16860,7 @@ snapshots:
'@next/swc-win32-ia32-msvc': 14.2.4
'@next/swc-win32-x64-msvc': 14.2.4
'@opentelemetry/api': 1.8.0
- '@playwright/test': 1.44.1
+ '@playwright/test': 1.46.0
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
@@ -17300,12 +17552,20 @@ snapshots:
playwright-core@1.44.1: {}
+ playwright-core@1.46.0: {}
+
playwright@1.44.1:
dependencies:
playwright-core: 1.44.1
optionalDependencies:
fsevents: 2.3.2
+ playwright@1.46.0:
+ dependencies:
+ playwright-core: 1.46.0
+ optionalDependencies:
+ fsevents: 2.3.2
+
please-upgrade-node@3.2.0:
dependencies:
semver-compare: 1.0.0
@@ -17504,6 +17764,8 @@ snapshots:
react-is@18.3.1: {}
+ react-refresh@0.14.2: {}
+
react-router-dom@6.23.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@remix-run/router': 1.16.1
@@ -17814,6 +18076,28 @@ snapshots:
robust-predicates@3.0.2: {}
+ rollup@4.18.0:
+ dependencies:
+ '@types/estree': 1.0.5
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.18.0
+ '@rollup/rollup-android-arm64': 4.18.0
+ '@rollup/rollup-darwin-arm64': 4.18.0
+ '@rollup/rollup-darwin-x64': 4.18.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.18.0
+ '@rollup/rollup-linux-arm-musleabihf': 4.18.0
+ '@rollup/rollup-linux-arm64-gnu': 4.18.0
+ '@rollup/rollup-linux-arm64-musl': 4.18.0
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.18.0
+ '@rollup/rollup-linux-s390x-gnu': 4.18.0
+ '@rollup/rollup-linux-x64-gnu': 4.18.0
+ '@rollup/rollup-linux-x64-musl': 4.18.0
+ '@rollup/rollup-win32-arm64-msvc': 4.18.0
+ '@rollup/rollup-win32-ia32-msvc': 4.18.0
+ '@rollup/rollup-win32-x64-msvc': 4.18.0
+ fsevents: 2.3.3
+
rrweb-cssom@0.6.0: {}
rrweb-cssom@0.7.0: {}
@@ -18800,6 +19084,16 @@ snapshots:
unist-util-stringify-position: 2.0.3
vfile-message: 2.0.4
+ vite@5.3.2(@types/node@18.19.39)(terser@5.27.0):
+ dependencies:
+ esbuild: 0.21.5
+ postcss: 8.4.38
+ rollup: 4.18.0
+ optionalDependencies:
+ '@types/node': 18.19.39
+ fsevents: 2.3.3
+ terser: 5.27.0
+
void-elements@2.0.1: {}
w3c-xmlserializer@5.0.0:
diff --git a/renovate.json b/renovate.json
index 5c6bf29584a6b..1940bc6efe6a5 100644
--- a/renovate.json
+++ b/renovate.json
@@ -30,6 +30,10 @@
"groupName": "Emotion",
"matchPackagePatterns": "@emotion/*"
},
+ {
+ "groupName": "Playwright",
+ "matchPackagePatterns": "@playwright/*"
+ },
{
"groupName": "core-js",
"matchPackageNames": ["core-js"],
diff --git a/test/e2e-charts/README.md b/test/e2e-charts/README.md
new file mode 100644
index 0000000000000..2fde60fedb507
--- /dev/null
+++ b/test/e2e-charts/README.md
@@ -0,0 +1,35 @@
+# Testing Charts E2E
+
+This directory contains the end-to-end tests for the x-charts project.
+
+## Running the tests
+
+Basic tests can be run with the following command:
+
+```bash
+pnpm test:e2e:charts
+```
+
+We use the playwright test runner to run the tests. You can find more information about playwright [here](https://playwright.dev/).
+
+An useful command to run the tests with the browser UI is:
+
+```bash
+pnpm test:e2e:charts --ui
+```
+
+## Writing tests
+
+The tests are written in TypeScript and can be written in any of the x-charts(-\*) packages. Simply create a new file with the `.e2e.spec.tsx?` extension and write your tests.
+
+We use playwright in [component testing mode](https://playwright.dev/docs/test-components), which is **experimental**. But allows us to test the components in isolation. It has some caveats, so be sure to read the documentation.
+
+Mainly, you can't pass a synchronous function as a prop to a component, because it will be executed in the test environment, not in the browser. You can define your component's "story" in a different file and import it in the test file.
+
+For that we use a `*.e2e.stories.tsx` file, where we define the stories for the components we want to test.
+
+## Reasoning vs RTL
+
+Some of our features use SVG apis that are not available in the JSDOM environment. This is why we use playwright to run the tests in a real browser.
+
+An alternative would be to use [svgdom](https://www.npmjs.com/package/svgdom) or polyfill everything ourselves.
diff --git a/test/e2e-charts/playwright-ct.config.ts b/test/e2e-charts/playwright-ct.config.ts
new file mode 100644
index 0000000000000..7567a413167a0
--- /dev/null
+++ b/test/e2e-charts/playwright-ct.config.ts
@@ -0,0 +1,55 @@
+import { defineConfig, devices } from '@playwright/experimental-ct-react';
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: '../../packages/',
+ testMatch: '**/x-charts?(-pro)/**/*.e2e.spec.tsx',
+ /* The base directory, relative to the config file, for snapshot files created with toMatchSnapshot and toHaveScreenshot. */
+ snapshotDir: './__snapshots__',
+ /* Maximum time one test can run for. */
+ timeout: 10 * 1000,
+ /* Run tests in files in parallel */
+ fullyParallel: true,
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Port to use for Playwright component endpoint. */
+ ctPort: 3100,
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: { ...devices['Desktop Chrome'] },
+ },
+ {
+ name: 'chrome-mobile',
+ use: { ...devices['Pixel 5'] },
+ },
+ {
+ name: 'firefox',
+ use: { ...devices['Desktop Firefox'] },
+ },
+ {
+ name: 'webkit',
+ use: { ...devices['Desktop Safari'] },
+ },
+ {
+ name: 'webkit-mobile',
+ use: { ...devices['iPhone 13'] },
+ },
+ ],
+});
diff --git a/test/e2e-charts/playwright/index.html b/test/e2e-charts/playwright/index.html
new file mode 100644
index 0000000000000..2032be5972c7e
--- /dev/null
+++ b/test/e2e-charts/playwright/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Testing Page
+
+
+
+
+
+
diff --git a/test/e2e-charts/playwright/index.tsx b/test/e2e-charts/playwright/index.tsx
new file mode 100644
index 0000000000000..78b9c5d6ac0ad
--- /dev/null
+++ b/test/e2e-charts/playwright/index.tsx
@@ -0,0 +1,2 @@
+// This file is required somehow. Test will fail if we remove the