diff --git a/.eslintignore b/.eslintignore index 631a751b..b6856e40 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,3 +3,5 @@ node_modules /build /storybook-static /server + +/playwright/playwright/.cache/ diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 00000000..66f652c1 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,41 @@ +name: Playwright Tests + +on: + pull_request: + +jobs: + test: + name: Test component + runs-on: ubuntu-latest + container: + image: mcr.microsoft.com/playwright:v1.45.3-jammy + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - name: Install dependencies + run: npm ci + - name: Run Playwright tests + run: npm run playwright + env: + CI: 'true' + - name: Upload Playwright playwright report to GitHub Actions Artifacts + if: always() + uses: actions/upload-artifact@v3 + with: + name: playwright-report + path: ./playwright-report + retention-days: 1 + - name: Save PR ID + if: always() + run: | + pr="${{ github.event.pull_request.number }}" + echo $pr > ./pr-id.txt + shell: bash + - name: Create PR Artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: pr + path: ./pr-id.txt diff --git a/.github/workflows/pr-playwright-report.yml b/.github/workflows/pr-playwright-report.yml new file mode 100644 index 00000000..8716a056 --- /dev/null +++ b/.github/workflows/pr-playwright-report.yml @@ -0,0 +1,38 @@ +name: PR Playwright Report + +on: + workflow_run: + workflows: ['Playwright Tests'] + types: + - completed + +jobs: + comment: + name: Upload Playwright report to s3 + if: github.event.workflow_run.event == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Download Artifacts + uses: dawidd6/action-download-artifact@v2 + with: + workflow: ${{ github.event.workflow_run.workflow_id }} + run_id: ${{ github.event.workflow_run.id }} + - name: Extract PR Number + id: pr + run: echo "::set-output name=id::$( ( @@ -23,8 +26,19 @@ const withContextProvider: Decorator = (Story, context) => ( ); +const withBlogConstructorProvider: Decorator = (Story, context) => { + return ( + + + + ); +}; + const preview: Preview = { - decorators: [withTheme, withLang, withMobile, withContextProvider], + decorators: [withTheme, withLang, withMobile, withContextProvider, withBlogConstructorProvider], parameters: { docs: { theme: themes.light, diff --git a/jest.config.js b/jest.config.js index c01c4169..fbfea4d4 100644 --- a/jest.config.js +++ b/jest.config.js @@ -22,4 +22,11 @@ module.exports = { '\\.(css|less|scss|sass)$': 'jest-transform-css', }, testMatch: ['**/*.test.[jt]s?(x)'], + testPathIgnorePatterns: [ + '/node_modules', + '/build', + '/server', + '/.storybook', + '.visual.', + ], }; diff --git a/package-lock.json b/package-lock.json index 0db36e03..67979267 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,12 +26,14 @@ "@commitlint/config-conventional": "^17.4.3", "@diplodoc/transform": "^4.10.8", "@gravity-ui/eslint-config": "^3.1.1", - "@gravity-ui/page-constructor": "^5.18.0", + "@gravity-ui/page-constructor": "^5.27.0", "@gravity-ui/prettier-config": "^1.1.0", "@gravity-ui/stylelint-config": "^4.0.1", "@gravity-ui/tsconfig": "^1.0.0", "@gravity-ui/uikit": "^6.22.0", "@jest/environment": "^29.7.0", + "@playwright/experimental-ct-react": "^1.45.3", + "@playwright/test": "^1.45.3", "@storybook/addon-essentials": "^8.0.5", "@storybook/addon-mdx-gfm": "^8.0.5", "@storybook/addon-webpack5-compiler-babel": "^3.0.3", @@ -50,6 +52,7 @@ "@types/react-helmet": "^6.1.5", "@types/ua-parser-js": "^0.7.36", "@types/uuid": "^9.0.7", + "@vitejs/plugin-react": "^4.3.1", "eslint": "^8.34.0", "eslint-plugin-no-not-accumulator-reassign": "^0.1.0", "eslint-plugin-testing-library": "^5.9.1", @@ -76,7 +79,9 @@ "storybook": "^8.0.5", "stylelint": "^15.11.0", "ts-jest": "^29.0.5", - "typescript": "^4.9.3" + "typescript": "^4.9.3", + "vite-plugin-commonjs": "^0.10.3", + "vite-plugin-svgr": "^4.2.0" }, "peerDependencies": { "@diplodoc/transform": "^4.10.7", @@ -126,43 +131,43 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", - "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.0", - "@babel/parser": "^7.24.0", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.0", - "@babel/types": "^7.24.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -202,14 +207,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -241,14 +246,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -359,28 +364,28 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.15" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -402,9 +407,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", - "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -445,12 +450,13 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -481,27 +487,27 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, "engines": { "node": ">=6.9.0" @@ -522,38 +528,41 @@ } }, "node_modules/@babel/helpers": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz", - "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, "dependencies": { - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", - "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -1580,6 +1589,36 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz", + "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz", + "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-pure-annotations": { "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", @@ -2123,33 +2162,30 @@ } }, "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", - "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2158,13 +2194,13 @@ } }, "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2948,9 +2984,9 @@ "dev": true }, "node_modules/@gravity-ui/components": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@gravity-ui/components/-/components-3.4.2.tgz", - "integrity": "sha512-cwxV1QSrWzQN3J9UqjIAnFi8Ebv0VHK/65PchpO7ve9YeT3X2EWRp3ITTcvC2W9EIvDGFdLGFxCav9NPJsVGkQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@gravity-ui/components/-/components-3.10.1.tgz", + "integrity": "sha512-u9PYzbstUg7+ueAtZk2PSTWnvZR1r8zV2HlrMPhhTHcuJROymRWPgiTwkIYmd3SA4U75p8RRBcrw+FEbDzateA==", "dependencies": { "@bem-react/classname": "^1.6.0", "@gravity-ui/date-utils": "^2.1.0", @@ -2961,28 +2997,47 @@ "universal-cookie": "^6.1.3" }, "peerDependencies": { - "@gravity-ui/uikit": "^6.0.0", + "@gravity-ui/uikit": "^6.13.0", "react": "^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@gravity-ui/date-components": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@gravity-ui/date-components/-/date-components-2.10.1.tgz", + "integrity": "sha512-7g5SYEzpkQnb5L+e/k0S9pS9zY4r+Dus4x/5Bpbdn7WLR8j0/ONWyQIY8ZQxkvZPKrmeMyha2bNi8QGJZRHFcQ==", + "dev": true, + "dependencies": { + "@bem-react/classname": "^1.6.0", + "@gravity-ui/date-utils": "^2.5.3", + "@gravity-ui/icons": "^2.2.0", + "tslib": "^2.6.2" + }, + "peerDependencies": { + "@gravity-ui/uikit": "^6.0.0", + "react": ">=17.0.0", + "react-dom": ">=17.0.0" + } + }, "node_modules/@gravity-ui/date-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/date-utils/-/date-utils-2.1.0.tgz", - "integrity": "sha512-f7PsINb3/Q4gDDNZnZkE5SjDQqCba6NKa1e4W6976Zc7MkJ8fNTDnhC8sQP3Xpgme/yXAOx6U1rAJiijFaJY9Q==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@gravity-ui/date-utils/-/date-utils-2.5.3.tgz", + "integrity": "sha512-WetzttqlW454yGsh/LBo0AxuqIFT0erENCMYAfemhu6qLiuqy35NdDGP6VA4iDkWiSPFuQ1sRoVU8tC+OwiPEg==", "dependencies": { "dayjs": "1.11.10", "lodash": "^4.17.0" } }, "node_modules/@gravity-ui/dynamic-forms": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/dynamic-forms/-/dynamic-forms-4.0.0.tgz", - "integrity": "sha512-ofjsMtP/EGqkfXs/nM7b0wG80p5CdGi3Ibh71dEv4BDq4i7CZeakX6wxLQ3Yz9hrrpd7Z2oJ9vnBZt8Sw1oC9Q==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/dynamic-forms/-/dynamic-forms-4.12.0.tgz", + "integrity": "sha512-JNiGLHj2y7t1/coV4AbpgV1D3Crwk00VIK7EDXRLQvteSGUwpZQ5puM9M89DMZZK3DBcWCpQO9f4GWLxXwLCTg==", "dev": true, "dependencies": { "@bem-react/classname": "^1.6.0", "@gravity-ui/components": "^3.0.0", + "@gravity-ui/date-components": "^2.4.0", + "@gravity-ui/date-utils": "^2.4.0", "@gravity-ui/i18n": "^1.2.0", "@gravity-ui/icons": "^2.8.1", "lodash": "^4.17.20" @@ -3045,14 +3100,14 @@ } }, "node_modules/@gravity-ui/page-constructor": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/page-constructor/-/page-constructor-5.18.0.tgz", - "integrity": "sha512-uVcLnXB7/RHSwFbaeuaulQwI5vcVc89yY9skuewab7kB8cXoZvJbuSRd/TK/OSqWrEqxso+9MpXgz99Rr8Z6sA==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/page-constructor/-/page-constructor-5.27.0.tgz", + "integrity": "sha512-LYkxXHEpKihWAYm1WwgxxlyjhiaCrbl1o5HBMLd+fzeXLAcBN6ZpjVWyq+QRuY6duc1RWMJ68A3szxlr/LBy7Q==", "dev": true, "dependencies": { "@bem-react/classname": "^1.6.0", - "@gravity-ui/components": "^3.0.0", - "@gravity-ui/dynamic-forms": "^4.0.0", + "@gravity-ui/components": "^3.8.0", + "@gravity-ui/dynamic-forms": "^4.11.0", "@gravity-ui/i18n": "^1.3.0", "@react-spring/web": "^9.7.3", "ajv": "^8.12.0", @@ -4019,9 +4074,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { @@ -4166,6 +4221,51 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@playwright/experimental-ct-core": { + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/@playwright/experimental-ct-core/-/experimental-ct-core-1.45.3.tgz", + "integrity": "sha512-uYcWBxRPu2G2Mj2e+XUxRBzRNnG/Yz0A5DVWFewiG3qEfC92MaGYGxmzKeFeU9NcMA2fWwaqB3XWHXjn9qSM5Q==", + "dev": true, + "dependencies": { + "playwright": "1.45.3", + "playwright-core": "1.45.3", + "vite": "^5.2.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@playwright/experimental-ct-react": { + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/@playwright/experimental-ct-react/-/experimental-ct-react-1.45.3.tgz", + "integrity": "sha512-cEgiZ2+DqVCeFJWJdHgOUwhlEof41Rg1GX48FtMX/xrjAnxs2ccqqAXMILD+mVV1ftsC2jeS1EiRLoAmf8QXgA==", + "dev": true, + "dependencies": { + "@playwright/experimental-ct-core": "1.45.3", + "@vitejs/plugin-react": "^4.2.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@playwright/test": { + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.3.tgz", + "integrity": "sha512-UKF4XsBfy+u3MFWEH44hva1Q8Da28G6RFtR2+5saw+jgAFQV5yYnB1fu68Mz7fO+5GJF3wgwAIs0UelU8TxFrA==", + "dev": true, + "dependencies": { + "playwright": "1.45.3" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -4278,6 +4378,242 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz", + "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", + "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", + "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", + "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", + "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", + "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", + "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", + "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", + "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", + "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", + "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", + "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", + "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", + "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", + "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", + "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", + "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -5774,7 +6110,276 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@testing-library/dom": { + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "dev": true, + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/core/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@svgr/core/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@svgr/core/node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@svgr/core/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@testing-library/dom": { "version": "9.3.3", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.3.tgz", "integrity": "sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==", @@ -5972,9 +6577,9 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", - "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "dependencies": { "@babel/parser": "^7.20.7", @@ -6812,6 +7417,25 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", + "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.24.5", + "@babel/plugin-transform-react-jsx-self": "^7.24.5", + "@babel/plugin-transform-react-jsx-source": "^7.24.1", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", @@ -8481,9 +9105,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "dev": true, "funding": [ { @@ -8500,10 +9124,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -8703,9 +9327,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001591", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", - "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", + "version": "1.0.30001663", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", + "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==", "dev": true, "funding": [ { @@ -10716,9 +11340,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.689", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.689.tgz", - "integrity": "sha512-GatzRKnGPS1go29ep25reM94xxd1Wj8ritU0yRhCJ/tr1Bg8gKnm6R9O/yPOhGQBoLMZ9ezfrpghNaTw97C/PQ==", + "version": "1.5.28", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.28.tgz", + "integrity": "sha512-VufdJl+rzaKZoYVUijN13QcXVF5dWPZANeFTLNy+OSpHdDL5ynXTF35+60RSBbaQYB1ae723lQXHCrf4pyLsMw==", "dev": true }, "node_modules/emittery": { @@ -10952,9 +11576,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz", - "integrity": "sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", "dev": true }, "node_modules/es-set-tostringtag": { @@ -11102,9 +11726,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "engines": { "node": ">=6" @@ -11917,6 +12541,12 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -12339,9 +12969,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -18559,15 +19189,12 @@ } }, "node_modules/magic-string": { - "version": "0.30.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz", - "integrity": "sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dev": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/make-dir": { @@ -20383,9 +21010,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, "node_modules/normalize-package-data": { @@ -21354,9 +21981,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "node_modules/picomatch": { @@ -21434,6 +22061,36 @@ "node": ">=10" } }, + "node_modules/playwright": { + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.3.tgz", + "integrity": "sha512-QhVaS+lpluxCaioejDZ95l4Y4jSFCsBvl2UZkpeXlzxmqS+aABr5c82YmfMHrL6x27nvrvykJAFpkzT2eWdJww==", + "dev": true, + "dependencies": { + "playwright-core": "1.45.3" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.3.tgz", + "integrity": "sha512-+ym0jNbcjikaOwwSZycFbwkWgfruWvYlJfThKYAlImbxUgdWFO2oW70ojPm4OpE4t6TAo2FY/smM+hpVTtkhDA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/please-upgrade-node": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", @@ -21480,9 +22137,9 @@ } }, "node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "dev": true, "funding": [ { @@ -21500,8 +22157,8 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -22313,6 +22970,15 @@ } } }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-side-effect": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz", @@ -23133,13 +23799,54 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/run-applescript": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", - "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "node_modules/rollup": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", + "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", "dev": true, "dependencies": { - "execa": "^5.0.0" + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup/node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" }, "engines": { "node": ">=12" @@ -23961,9 +24668,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -24852,6 +25559,12 @@ "es6-symbol": "^3.1.1" } }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true + }, "node_modules/svg-tags": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", @@ -26304,9 +27017,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -26323,8 +27036,8 @@ } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -26621,6 +27334,546 @@ "node": ">=0.10.0" } }, + "node_modules/vite": { + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", + "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-commonjs": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/vite-plugin-commonjs/-/vite-plugin-commonjs-0.10.3.tgz", + "integrity": "sha512-trtH4dfAqrbqwiUhSKcqrfjnlXnqLHdIbYuUy943y34JnDjIX8qlpExP0nFN+kE2s6/BS6r9d1cAHS0KtiF4yQ==", + "dev": true, + "dependencies": { + "acorn": "^8.12.1", + "magic-string": "^0.30.11", + "vite-plugin-dynamic-import": "^1.6.0" + } + }, + "node_modules/vite-plugin-commonjs/node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/vite-plugin-dynamic-import": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-plugin-dynamic-import/-/vite-plugin-dynamic-import-1.6.0.tgz", + "integrity": "sha512-TM0sz70wfzTIo9YCxVFwS8OA9lNREsh+0vMHGSkWDTZ7bgd1Yjs5RV8EgB634l/91IsXJReg0xtmuQqP0mf+rg==", + "dev": true, + "dependencies": { + "acorn": "^8.12.1", + "es-module-lexer": "^1.5.4", + "fast-glob": "^3.3.2", + "magic-string": "^0.30.11" + } + }, + "node_modules/vite-plugin-dynamic-import/node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/vite-plugin-svgr": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.2.0.tgz", + "integrity": "sha512-SC7+FfVtNQk7So0XMjrrtLAbEC8qjFPifyD7+fs/E6aaNdVde6umlVVh0QuwDLdOMu7vp5RiGFsB70nj5yo0XA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.5", + "@svgr/core": "^8.1.0", + "@svgr/plugin-jsx": "^8.1.0" + }, + "peerDependencies": { + "vite": "^2.6.0 || 3 || 4 || 5" + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", diff --git a/package.json b/package.json index cb6fbae8..642d38fa 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,14 @@ "svgo:all": "svgo --config svgo.config.js -r -f assets", "test": "jest --maxWorkers=50%", "test:coverage": "jest --coverage", - "test:watch": "jest --watchAll --maxWorkers=25%" + "test:watch": "jest --watchAll --maxWorkers=25%", + "playwright": "playwright test --config=playwright/playwright.config.ts", + "playwright:update": "npm run playwright -- -u", + "playwright:clear-cache": "rm -rf ./playwright/.cache", + "playwright:docker": "./scripts/playwright-docker.sh 'npm run playwright'", + "playwright:docker:update": "./scripts/playwright-docker.sh 'npm run playwright:update'", + "playwright:docker:clear-cache": "./scripts/playwright-docker.sh clear-cache", + "playwright:install": "playwright install --with-deps" }, "dependencies": { "@bem-react/classname": "^1.6.0", @@ -82,12 +89,14 @@ "@commitlint/config-conventional": "^17.4.3", "@diplodoc/transform": "^4.10.8", "@gravity-ui/eslint-config": "^3.1.1", - "@gravity-ui/page-constructor": "^5.18.0", + "@gravity-ui/page-constructor": "^5.27.0", "@gravity-ui/prettier-config": "^1.1.0", "@gravity-ui/stylelint-config": "^4.0.1", "@gravity-ui/tsconfig": "^1.0.0", "@gravity-ui/uikit": "^6.22.0", "@jest/environment": "^29.7.0", + "@playwright/experimental-ct-react": "^1.45.3", + "@playwright/test": "^1.45.3", "@storybook/addon-essentials": "^8.0.5", "@storybook/addon-mdx-gfm": "^8.0.5", "@storybook/addon-webpack5-compiler-babel": "^3.0.3", @@ -106,6 +115,7 @@ "@types/react-helmet": "^6.1.5", "@types/ua-parser-js": "^0.7.36", "@types/uuid": "^9.0.7", + "@vitejs/plugin-react": "^4.3.1", "eslint": "^8.34.0", "eslint-plugin-no-not-accumulator-reassign": "^0.1.0", "eslint-plugin-testing-library": "^5.9.1", @@ -132,7 +142,9 @@ "storybook": "^8.0.5", "stylelint": "^15.11.0", "ts-jest": "^29.0.5", - "typescript": "^4.9.3" + "typescript": "^4.9.3", + "vite-plugin-commonjs": "^0.10.3", + "vite-plugin-svgr": "^4.2.0" }, "lint-staged": { "*.{css,scss}": [ diff --git a/playwright/README.md b/playwright/README.md new file mode 100644 index 00000000..4f5031f3 --- /dev/null +++ b/playwright/README.md @@ -0,0 +1,138 @@ +# Playwright Test Component + +## How to write a test + +1. Select the component you want to write tests for +2. Inside the component folder, create the `__tests__` folder and create a file inside it with the following name `.visual.test.tsx` +3. Writing a test: + + > NOTE: + > Add `await defaultDelay()` between mounting and testing routine in every test with animation. It is necessary because of testing during animation in progress is unstable. + + Capture a screenshot, by default in light theme only: + + ```ts + import React from 'react'; + + import {expect} from '@playwright/experimental-ct-react'; + + import {MyComponent} from '../MyComponent'; + + import {test} from '~playwright/core'; + + test('test description', async ({page, mount, defaultDelay}) => { + // mount the component + const component = await mount(); + + // default delay to bypass animation issues + await defaultDelay(); + + // capture the screenshot + await expect(component).toHaveScreenshot(); + }); + ``` + + You can also capture screenshots both in dark and light themes: + + ```ts + import React from 'react'; + + import {MyComponent} from '../MyComponent'; + + import {test} from '~playwright/core'; + + test('test description', async ({page, mount, expectScreenshot, defaultDelay}) => { + // mount the component + await mount(); + + // default delay to bypass animation issues + await defaultDelay(); + + // capture the screenshot + await expectScreenshot(); + }); + ``` + + If you need to do any actions with the component: + + ```ts + import React from 'react'; + + import {MyComponent} from '../MyComponent'; + + import {test} from '~playwright/core'; + + test('test description', async ({page, mount, expectScreenshot, defaultDelay}) => { + // mount the component + const component = await mount(); + + // default delay to bypass animation issues + await defaultDelay(); + + // the action + await component.click(); + + // capture the screenshot + await expectScreenshot({component}); + }); + ``` + + Group of tests. + + ```ts + test.describe('Name group tests', () => { + test('1', ...); + test('2', ...); + ... + test('10', ...) + }); + ``` + +4. Run tests + + ```shell + npm run playwright:install + npm run playwright + ``` + + If you are using system other than Linux, then you need to run tests via docker command: + + ```shell + npm run playwright:docker + ``` + + > `npm run playwright:install` command must be run only once on initial setup + +5. Update screenshots if needed + + ```shell + npm run playwright:update + ``` + + Or + + ```shell + npm run playwright:docker:update + ``` + +6. In the folder `__snapshots__`, which is on the same level as the `__tests__` folder, the folder `.visual.test.tsx-snapshots`, will contain screenshots + +## Description of possible commands: + +1. [playwright-test-components](https://playwright.dev/docs/test-components) +2. [playwright-docs](https://playwright.dev/docs/api/class-test) +3. [playwright-writing-tests](https://playwright.dev/docs/writing-tests) + +## Test examples + +- [Button](../src/components/Button/__tests__/Button.visual.test.tsx) + +## Npm scripts + +- `npm run playwright:install` - install playwright browsers and dependencies +- `npm run playwright` - run tests +- `npm run playwright:update` - update screenshots +- `npm run playwright:clear-cache` - clear cache vite +- `npm run playwright:docker` - run tests using docker +- `npm run playwright:docker:update` - update screenshots using docker +- `npm run playwright:docker:clear-cache` - clear node_modules cache for docker container and clear cache vite diff --git a/playwright/core/constants.ts b/playwright/core/constants.ts new file mode 100644 index 00000000..30d3bfe4 --- /dev/null +++ b/playwright/core/constants.ts @@ -0,0 +1 @@ +export const DEFAULT_MOUNT_TEST_DELAY = 1000; // ms diff --git a/playwright/core/delays.ts b/playwright/core/delays.ts new file mode 100644 index 00000000..a3300901 --- /dev/null +++ b/playwright/core/delays.ts @@ -0,0 +1,15 @@ +import {DEFAULT_MOUNT_TEST_DELAY} from './constants'; +import type {PlaywrightFixture} from './types'; + +export const defaultDelayFixture: PlaywrightFixture<() => Promise> = async ({page}, use) => { + const defaultDelay = async () => await page.waitForTimeout(DEFAULT_MOUNT_TEST_DELAY); + await use(defaultDelay); +}; + +export const delayFixture: PlaywrightFixture<(delay: number) => Promise> = async ( + {page}, + use, +) => { + const delayFunction = async (delay: number) => await page.waitForTimeout(delay); + await use(delayFunction); +}; diff --git a/playwright/core/expectScreenshotFixture.ts b/playwright/core/expectScreenshotFixture.ts new file mode 100644 index 00000000..f81ee551 --- /dev/null +++ b/playwright/core/expectScreenshotFixture.ts @@ -0,0 +1,65 @@ +import {expect} from '@playwright/experimental-ct-react'; +import type {Locator, PageScreenshotOptions} from '@playwright/test'; + +import {DEFAULT_MOUNT_TEST_DELAY} from './constants'; +import type {PlaywrightFixture} from './types'; + +interface CaptureScreenshotParams extends PageScreenshotOptions { + screenshotName?: string; + component?: Locator; + skipTheme?: 'light' | 'dark'; +} + +export interface ExpectScreenshotFixture { + (props?: CaptureScreenshotParams): Promise; +} + +export const expectScreenshotFixture: PlaywrightFixture = async ( + {page}, + use, + testInfo, +) => { + const expectScreenshot: ExpectScreenshotFixture = async ({ + component, + screenshotName, + skipTheme, + ...pageScreenshotOptions + } = {}) => { + const captureScreenshot = async () => { + const locators = await page.locator('//img').all(); + const promises = locators.map((locator) => + locator.evaluate( + (image: HTMLImageElement) => + image.complete || + new Promise((resolve) => image.addEventListener('load', resolve)), + ), + ); + await Promise.all(promises); + + return (component || page.locator('.playwright-wrapper-test')).screenshot({ + animations: 'disabled', + ...pageScreenshotOptions, + }); + }; + + const nameScreenshot = testInfo.titlePath.slice(1).join(' '); + + if (skipTheme !== 'light') { + expect(await captureScreenshot()).toMatchSnapshot({ + name: `${screenshotName || nameScreenshot} light.png`, + }); + } + + if (skipTheme !== 'dark') { + await page.emulateMedia({colorScheme: 'dark'}); + + await page.waitForTimeout(DEFAULT_MOUNT_TEST_DELAY); + + expect(await captureScreenshot()).toMatchSnapshot({ + name: `${screenshotName || nameScreenshot} dark.png`, + }); + } + }; + + await use(expectScreenshot); +}; diff --git a/playwright/core/index.ts b/playwright/core/index.ts new file mode 100644 index 00000000..e22bb0de --- /dev/null +++ b/playwright/core/index.ts @@ -0,0 +1,15 @@ +import {test as base} from '@playwright/experimental-ct-react'; + +import {defaultDelayFixture, delayFixture} from './delays'; +import {expectScreenshotFixture} from './expectScreenshotFixture'; +import {mountFixture} from './mountFixture'; +import type {Fixtures} from './types'; + +export const test = base.extend({ + mount: mountFixture, + expectScreenshot: expectScreenshotFixture, + defaultDelay: defaultDelayFixture, + delay: delayFixture, +}); + +export {expect} from '@playwright/experimental-ct-react'; diff --git a/playwright/core/mountFixture.tsx b/playwright/core/mountFixture.tsx new file mode 100644 index 00000000..e05bf54c --- /dev/null +++ b/playwright/core/mountFixture.tsx @@ -0,0 +1,21 @@ +import type {MountOptions} from '@playwright/experimental-ct-react'; +import React from 'react'; + +import type {MountFixture, PlaywrightFixture} from './types'; + +export const mountFixture: PlaywrightFixture = async ({mount: baseMount}, use) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const mount = async (component: JSX.Element, options?: MountOptions | undefined) => { + return await baseMount( +
+ {component} +
, + options, + ); + }; + + await use(mount); +}; diff --git a/playwright/core/types.ts b/playwright/core/types.ts new file mode 100644 index 00000000..57a6ed0a --- /dev/null +++ b/playwright/core/types.ts @@ -0,0 +1,43 @@ +import type {MountOptions, MountResult} from '@playwright/experimental-ct-react'; +import type { + Locator, + PageScreenshotOptions, + PlaywrightTestArgs, + PlaywrightTestOptions, + PlaywrightWorkerArgs, + PlaywrightWorkerOptions, + TestFixture, +} from '@playwright/test'; + +interface ComponentFixtures { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + mount( + component: JSX.Element, + options?: MountOptions, + style?: React.CSSProperties, + ): Promise; +} + +type PlaywrightTestFixtures = PlaywrightTestArgs & PlaywrightTestOptions & ComponentFixtures; +type PlaywrightWorkerFixtures = PlaywrightWorkerArgs & PlaywrightWorkerOptions; +type PlaywrightFixtures = PlaywrightTestFixtures & PlaywrightWorkerFixtures; +export type PlaywrightFixture = TestFixture; + +export type Fixtures = { + mount: MountFixture; + expectScreenshot: ExpectScreenshotFixture; + defaultDelay: () => Promise; + delay: (delay: number) => Promise; +}; + +export type MountFixture = ComponentFixtures['mount']; + +export interface ExpectScreenshotFixture { + (props?: CaptureScreenshotParams): Promise; +} + +interface CaptureScreenshotParams extends PageScreenshotOptions { + screenshotName?: string; + component?: Locator; + skipTheme?: 'light' | 'dark'; +} diff --git a/playwright/playwright.config.ts b/playwright/playwright.config.ts new file mode 100644 index 00000000..258c2b12 --- /dev/null +++ b/playwright/playwright.config.ts @@ -0,0 +1,99 @@ +import {resolve} from 'path'; + +import type {PlaywrightTestConfig} from '@playwright/experimental-ct-react'; +import {defineConfig, devices} from '@playwright/experimental-ct-react'; +import react from '@vitejs/plugin-react'; +import commonjs from 'vite-plugin-commonjs'; +import svgrPlugin from 'vite-plugin-svgr'; + +function pathFromRoot(p: string) { + return resolve(__dirname, '../', p); +} + +const reporter: PlaywrightTestConfig['reporter'] = []; + +reporter.push( + ['list'], + [ + 'html', + { + open: process.env.CI ? 'never' : 'on-failure', + outputFolder: resolve( + process.cwd(), + process.env.IS_DOCKER ? 'playwright-report-docker' : 'playwright-report', + ), + }, + ], +); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +const config: PlaywrightTestConfig = { + testDir: pathFromRoot('src'), + testMatch: '**/__tests__/*.visual.test.tsx', + updateSnapshots: process.env.UPDATE_REQUEST ? 'all' : 'missing', + snapshotPathTemplate: + '{testDir}/{testFileDir}/../__snapshots__/{testFileName}-snapshots/{arg}{-projectName}-linux{ext}', + /* The base directory, relative to the config file, for snapshot files created with toMatchSnapshot and toHaveScreenshot. */ + /* Maximum time one test can run for. */ + timeout: 30 * 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: Boolean(process.env.CI), + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 8 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter, + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + testIdAttribute: 'data-qa', + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: process.env.CI ? 'on-first-retry' : 'retain-on-failure', + headless: true, + /* Port to use for Playwright component endpoint. */ + screenshot: 'only-on-failure', + timezoneId: 'UTC', + ctCacheDir: process.env.IS_DOCKER ? '.cache-docker' : '.cache', + ctViteConfig: { + publicDir: pathFromRoot('.storybook/public'), + json: { + stringify: true, + }, + plugins: [ + react(), + svgrPlugin({ + include: '**/*.svg?react', + svgrOptions: { + svgo: true, + icon: true, + }, + }), + commonjs(), + ], + resolve: { + preserveSymlinks: true, + alias: { + '~@gravity-ui/uikit/styles/styles.css': '@gravity-ui/uikit/styles/styles.css', + '~@diplodoc/transform/dist/css/yfm.css': '@diplodoc/transform/dist/css/yfm.css', + }, + }, + }, + }, + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: {...devices['Desktop Chrome']}, + }, + { + name: 'webkit', + use: {...devices['Desktop Safari']}, + }, + ], +}; + +export default defineConfig(config); diff --git a/playwright/playwright/Providers.tsx b/playwright/playwright/Providers.tsx new file mode 100644 index 00000000..29685fd6 --- /dev/null +++ b/playwright/playwright/Providers.tsx @@ -0,0 +1,36 @@ +import {Theme} from '@gravity-ui/page-constructor'; +import {MobileProvider, ThemeProvider, ToasterComponent, ToasterProvider} from '@gravity-ui/uikit'; +import React from 'react'; +import {BlogConstructorProvider} from '../../src/constructor/BlogConstructorProvider'; + +export const Providers = ({children}) => { + const [theme, setTheme] = React.useState(Theme.Light); + + React.useEffect(() => { + const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + const updateTheme = (event) => { + setTheme(event.matches ? Theme.Dark : Theme.Light); + }; + + setTheme(darkModeMediaQuery.matches ? Theme.Dark : Theme.Light); + + darkModeMediaQuery.addEventListener('change', updateTheme); + + return () => { + darkModeMediaQuery.removeEventListener('change', updateTheme); + }; + }, []); + + return ( + + + + + {children} + + + + + + ); +}; diff --git a/playwright/playwright/index.html b/playwright/playwright/index.html new file mode 100644 index 00000000..3431f3d2 --- /dev/null +++ b/playwright/playwright/index.html @@ -0,0 +1,10 @@ + + + + + + Testing Page + + + + diff --git a/playwright/playwright/index.scss b/playwright/playwright/index.scss new file mode 100644 index 00000000..d06dc159 --- /dev/null +++ b/playwright/playwright/index.scss @@ -0,0 +1,4 @@ +@import '../../styles/styles.scss'; +@import '../../styles/storybook/index.scss'; +@import '@gravity-ui/uikit/styles/styles.scss'; +@import '../../styles/root.scss'; diff --git a/playwright/playwright/index.tsx b/playwright/playwright/index.tsx new file mode 100644 index 00000000..6889da0d --- /dev/null +++ b/playwright/playwright/index.tsx @@ -0,0 +1,13 @@ +import {beforeMount} from '@playwright/experimental-ct-react/hooks'; +import React from 'react'; + +import {Providers} from './Providers'; +import './index.scss'; + +beforeMount(async ({App}) => { + return ( + + + + ); +}); diff --git a/scripts/playwright-docker.sh b/scripts/playwright-docker.sh new file mode 100755 index 00000000..891b6a51 --- /dev/null +++ b/scripts/playwright-docker.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +set -euo pipefail + +IMAGE_NAME="mcr.microsoft.com/playwright" +IMAGE_TAG="v1.45.3-jammy" # This version have to be synchronized with playwright version from package.json + +NODE_MODULES_CACHE_DIR="$HOME/.cache/blog-constructor-playwright-docker-node-modules" + +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +run_command() { + $CONTAINER_TOOL run --rm --network host -it -w /work \ + -v $(pwd):/work \ + -v "$NODE_MODULES_CACHE_DIR:/work/node_modules" \ + -e IS_DOCKER=1 \ + "$IMAGE_NAME:$IMAGE_TAG" \ + /bin/bash -c "$1" +} + +if command_exists docker; then + CONTAINER_TOOL="docker" +elif command_exists podman; then + CONTAINER_TOOL="podman" +else + echo "Neither Docker nor Podman is installed on the system." + exit 1 +fi + +if [[ "$1" = "clear-cache" ]]; then + rm -rf "$NODE_MODULES_CACHE_DIR" + rm -rf "./playwright/.cache-docker" + exit 0 +fi + +if [[ ! -d "$NODE_MODULES_CACHE_DIR" ]]; then + mkdir -p "$NODE_MODULES_CACHE_DIR" + run_command 'npm ci' +fi + +run_command "$1" diff --git a/src/blocks/Author/__snapshots__/Author.visual.test.tsx-snapshots/Author-render-stories-Default-light-chromium-linux.png b/src/blocks/Author/__snapshots__/Author.visual.test.tsx-snapshots/Author-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..fa95e319 Binary files /dev/null and b/src/blocks/Author/__snapshots__/Author.visual.test.tsx-snapshots/Author-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/Author/__snapshots__/Author.visual.test.tsx-snapshots/Author-render-stories-Default-light-webkit-linux.png b/src/blocks/Author/__snapshots__/Author.visual.test.tsx-snapshots/Author-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..80cad899 Binary files /dev/null and b/src/blocks/Author/__snapshots__/Author.visual.test.tsx-snapshots/Author-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/Author/__tests__/Author.visual.test.tsx b/src/blocks/Author/__tests__/Author.visual.test.tsx new file mode 100644 index 00000000..1bf1d262 --- /dev/null +++ b/src/blocks/Author/__tests__/Author.visual.test.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default} from './helpers'; + +test.describe('Author', () => { + test('render stories ', async ({mount, expectScreenshot, defaultDelay}) => { + await mount(); + await defaultDelay(); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/blocks/Author/__tests__/helpers.tsx b/src/blocks/Author/__tests__/helpers.tsx new file mode 100644 index 00000000..6ffcf4ae --- /dev/null +++ b/src/blocks/Author/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as AuthorStories from '../__stories__/Author.stories'; + +export const {Default} = composeStories(AuthorStories); diff --git a/src/blocks/Banner/__snapshots__/Banner.visual.test.tsx-snapshots/Banner-render-stories-Default-light-chromium-linux.png b/src/blocks/Banner/__snapshots__/Banner.visual.test.tsx-snapshots/Banner-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..effbbc40 Binary files /dev/null and b/src/blocks/Banner/__snapshots__/Banner.visual.test.tsx-snapshots/Banner-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/Banner/__snapshots__/Banner.visual.test.tsx-snapshots/Banner-render-stories-Default-light-webkit-linux.png b/src/blocks/Banner/__snapshots__/Banner.visual.test.tsx-snapshots/Banner-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..7ddd2fc1 Binary files /dev/null and b/src/blocks/Banner/__snapshots__/Banner.visual.test.tsx-snapshots/Banner-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/Banner/__tests__/Banner.visual.test.tsx b/src/blocks/Banner/__tests__/Banner.visual.test.tsx new file mode 100644 index 00000000..5f641aae --- /dev/null +++ b/src/blocks/Banner/__tests__/Banner.visual.test.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default} from './helpers'; + +test.describe('Banner', () => { + test('render stories ', async ({mount, expectScreenshot, defaultDelay}) => { + await mount(); + await defaultDelay(); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/blocks/Banner/__tests__/helpers.tsx b/src/blocks/Banner/__tests__/helpers.tsx new file mode 100644 index 00000000..7ed9c6d3 --- /dev/null +++ b/src/blocks/Banner/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as BannerStories from '../__stories__/Banner.stories'; + +export const {Default} = composeStories(BannerStories); diff --git a/src/blocks/CTA/__snapshots__/CTA.visual.test.tsx-snapshots/CTA-render-stories-Default-light-chromium-linux.png b/src/blocks/CTA/__snapshots__/CTA.visual.test.tsx-snapshots/CTA-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..bf2eb5a6 Binary files /dev/null and b/src/blocks/CTA/__snapshots__/CTA.visual.test.tsx-snapshots/CTA-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/CTA/__snapshots__/CTA.visual.test.tsx-snapshots/CTA-render-stories-Default-light-webkit-linux.png b/src/blocks/CTA/__snapshots__/CTA.visual.test.tsx-snapshots/CTA-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..df40c9f2 Binary files /dev/null and b/src/blocks/CTA/__snapshots__/CTA.visual.test.tsx-snapshots/CTA-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/CTA/__tests__/CTA.visual.test.tsx b/src/blocks/CTA/__tests__/CTA.visual.test.tsx new file mode 100644 index 00000000..07f03b19 --- /dev/null +++ b/src/blocks/CTA/__tests__/CTA.visual.test.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default} from './helpers'; + +test.describe('CTA', () => { + test('render stories ', async ({mount, expectScreenshot, defaultDelay}) => { + await mount(); + await defaultDelay(); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/blocks/CTA/__tests__/helpers.tsx b/src/blocks/CTA/__tests__/helpers.tsx new file mode 100644 index 00000000..90da28a3 --- /dev/null +++ b/src/blocks/CTA/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as CTAStories from '../__stories__/CTA.stories'; + +export const {Default} = composeStories(CTAStories); diff --git a/src/blocks/ColoredText/__snapshots__/ColoredText.visual.test.tsx-snapshots/ColoredText-render-stories-Default-light-chromium-linux.png b/src/blocks/ColoredText/__snapshots__/ColoredText.visual.test.tsx-snapshots/ColoredText-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..13ec08f9 Binary files /dev/null and b/src/blocks/ColoredText/__snapshots__/ColoredText.visual.test.tsx-snapshots/ColoredText-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/ColoredText/__snapshots__/ColoredText.visual.test.tsx-snapshots/ColoredText-render-stories-Default-light-webkit-linux.png b/src/blocks/ColoredText/__snapshots__/ColoredText.visual.test.tsx-snapshots/ColoredText-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..86535049 Binary files /dev/null and b/src/blocks/ColoredText/__snapshots__/ColoredText.visual.test.tsx-snapshots/ColoredText-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/ColoredText/__tests__/ColoredText.visual.test.tsx b/src/blocks/ColoredText/__tests__/ColoredText.visual.test.tsx new file mode 100644 index 00000000..54e416d7 --- /dev/null +++ b/src/blocks/ColoredText/__tests__/ColoredText.visual.test.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default} from './helpers'; + +test.describe('ColoredText', () => { + test('render stories ', async ({mount, expectScreenshot, defaultDelay}) => { + await mount(); + await defaultDelay(); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/blocks/ColoredText/__tests__/helpers.tsx b/src/blocks/ColoredText/__tests__/helpers.tsx new file mode 100644 index 00000000..8a72c5f6 --- /dev/null +++ b/src/blocks/ColoredText/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as ColoredTextStories from '../__stories__/ColoredText.stories'; + +export const {Default} = composeStories(ColoredTextStories); diff --git a/src/blocks/Feed/__snapshots__/Feed.visual.test.tsx-snapshots/Feed-render-stories-Default-light-chromium-linux.png b/src/blocks/Feed/__snapshots__/Feed.visual.test.tsx-snapshots/Feed-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..16b81833 Binary files /dev/null and b/src/blocks/Feed/__snapshots__/Feed.visual.test.tsx-snapshots/Feed-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/Feed/__snapshots__/Feed.visual.test.tsx-snapshots/Feed-render-stories-Default-light-webkit-linux.png b/src/blocks/Feed/__snapshots__/Feed.visual.test.tsx-snapshots/Feed-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..927352fa Binary files /dev/null and b/src/blocks/Feed/__snapshots__/Feed.visual.test.tsx-snapshots/Feed-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/Feed/__stories__/Feed.stories.tsx b/src/blocks/Feed/__stories__/Feed.stories.tsx index fe8a30a9..8e1586de 100644 --- a/src/blocks/Feed/__stories__/Feed.stories.tsx +++ b/src/blocks/Feed/__stories__/Feed.stories.tsx @@ -1,6 +1,6 @@ -import React from 'react'; +import React, {useContext} from 'react'; -import {Block, PageConstructor} from '@gravity-ui/page-constructor'; +import {Block, PageConstructor, PageConstructorProvider} from '@gravity-ui/page-constructor'; import type {Meta, StoryFn} from '@storybook/react'; import isEqual from 'lodash/isEqual'; @@ -23,6 +23,7 @@ import mockedServices from '../../../../.mocks/services.json'; import mockedTags from '../../../../.mocks/tags.json'; import {RouterContext} from '../../../contexts/RouterContext'; import {routerData} from '../../../demo/mocks'; +import {SettingsContext} from '../../../contexts/SettingsContext'; export default { title: 'Blocks/Feed', @@ -76,16 +77,22 @@ const contextData = { getPosts, }; -const DefaultTemplate: StoryFn = (args) => ( - - - - - -); +const DefaultTemplate: StoryFn = (args) => { + const {isAnimationEnabled} = useContext(SettingsContext); + + return ( + + + + + + + + ); +}; export const Default = DefaultTemplate.bind({}); diff --git a/src/blocks/Feed/__tests__/Feed.visual.test.tsx b/src/blocks/Feed/__tests__/Feed.visual.test.tsx new file mode 100644 index 00000000..bac4f05b --- /dev/null +++ b/src/blocks/Feed/__tests__/Feed.visual.test.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default} from './helpers'; + +test.describe('Feed', () => { + test('render stories ', async ({mount, expectScreenshot, defaultDelay}) => { + await mount(); + await defaultDelay(); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/blocks/Feed/__tests__/helpers.tsx b/src/blocks/Feed/__tests__/helpers.tsx new file mode 100644 index 00000000..2ec7fba6 --- /dev/null +++ b/src/blocks/Feed/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as FeedStories from '../__stories__/Feed.stories'; + +export const {Default} = composeStories(FeedStories); diff --git a/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-Default-light-chromium-linux.png b/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..37812722 Binary files /dev/null and b/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-Default-light-webkit-linux.png b/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..3474d58c Binary files /dev/null and b/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-FormData-light-chromium-linux.png b/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-FormData-light-chromium-linux.png new file mode 100644 index 00000000..058b43b0 Binary files /dev/null and b/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-FormData-light-chromium-linux.png differ diff --git a/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-FormData-light-webkit-linux.png b/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-FormData-light-webkit-linux.png new file mode 100644 index 00000000..ed6d22a2 Binary files /dev/null and b/src/blocks/Form/__snapshots__/Form.visual.test.tsx-snapshots/Form-render-stories-FormData-light-webkit-linux.png differ diff --git a/src/blocks/Form/__tests__/Form.visual.test.tsx b/src/blocks/Form/__tests__/Form.visual.test.tsx new file mode 100644 index 00000000..86fadf3a --- /dev/null +++ b/src/blocks/Form/__tests__/Form.visual.test.tsx @@ -0,0 +1,22 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default, FormData} from './helpers'; + +const FORM_DEALAY = 15 * 1000; + +test.describe('Form', () => { + // skip because yandex forms falls shows Captcha + test.skip('render stories ', async ({mount, expectScreenshot, delay}) => { + await mount(); + await delay(FORM_DEALAY); + await expectScreenshot({skipTheme: 'dark'}); + }); + + test.skip('render stories ', async ({mount, expectScreenshot, delay}) => { + await mount(); + await delay(FORM_DEALAY); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/blocks/Form/__tests__/helpers.tsx b/src/blocks/Form/__tests__/helpers.tsx new file mode 100644 index 00000000..29daf3d1 --- /dev/null +++ b/src/blocks/Form/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as FormStories from '../__stories__/Form.stories'; + +export const {Default, FormData} = composeStories(FormStories); diff --git a/src/blocks/Header/__snapshots__/Header.visual.test.tsx-snapshots/Header-render-stories-Default-light-chromium-linux.png b/src/blocks/Header/__snapshots__/Header.visual.test.tsx-snapshots/Header-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..59465593 Binary files /dev/null and b/src/blocks/Header/__snapshots__/Header.visual.test.tsx-snapshots/Header-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/Header/__snapshots__/Header.visual.test.tsx-snapshots/Header-render-stories-Default-light-webkit-linux.png b/src/blocks/Header/__snapshots__/Header.visual.test.tsx-snapshots/Header-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..a9a145d3 Binary files /dev/null and b/src/blocks/Header/__snapshots__/Header.visual.test.tsx-snapshots/Header-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/Header/__tests__/Header.visual.test.tsx b/src/blocks/Header/__tests__/Header.visual.test.tsx new file mode 100644 index 00000000..4042ca46 --- /dev/null +++ b/src/blocks/Header/__tests__/Header.visual.test.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default} from './helpers'; + +test.describe('Header', () => { + test('render stories ', async ({mount, expectScreenshot, defaultDelay}) => { + await mount(); + await defaultDelay(); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/blocks/Header/__tests__/helpers.tsx b/src/blocks/Header/__tests__/helpers.tsx new file mode 100644 index 00000000..06d4d51a --- /dev/null +++ b/src/blocks/Header/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as HeaderStories from '../__stories__/Header.stories'; + +export const {Default} = composeStories(HeaderStories); diff --git a/src/blocks/Layout/__snapshots__/Layout.visual.test.tsx-snapshots/Layout-render-stories-Default-light-chromium-linux.png b/src/blocks/Layout/__snapshots__/Layout.visual.test.tsx-snapshots/Layout-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..59d7a441 Binary files /dev/null and b/src/blocks/Layout/__snapshots__/Layout.visual.test.tsx-snapshots/Layout-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/Layout/__snapshots__/Layout.visual.test.tsx-snapshots/Layout-render-stories-Default-light-webkit-linux.png b/src/blocks/Layout/__snapshots__/Layout.visual.test.tsx-snapshots/Layout-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..9d43f407 Binary files /dev/null and b/src/blocks/Layout/__snapshots__/Layout.visual.test.tsx-snapshots/Layout-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/Layout/__tests__/Layout.visual.test.tsx b/src/blocks/Layout/__tests__/Layout.visual.test.tsx new file mode 100644 index 00000000..367f6454 --- /dev/null +++ b/src/blocks/Layout/__tests__/Layout.visual.test.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default} from './helpers'; + +test.describe('Layout', () => { + test('render stories ', async ({mount, expectScreenshot, defaultDelay}) => { + await mount(); + await defaultDelay(); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/blocks/Layout/__tests__/helpers.tsx b/src/blocks/Layout/__tests__/helpers.tsx new file mode 100644 index 00000000..f44751c8 --- /dev/null +++ b/src/blocks/Layout/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as LayoutStories from '../__stories__/Layout.stories'; + +export const {Default} = composeStories(LayoutStories); diff --git a/src/blocks/Media/__snapshots__/Media.visual.test.tsx-snapshots/Media-render-stories-Default-light-chromium-linux.png b/src/blocks/Media/__snapshots__/Media.visual.test.tsx-snapshots/Media-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..7c77fc3d Binary files /dev/null and b/src/blocks/Media/__snapshots__/Media.visual.test.tsx-snapshots/Media-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/Media/__snapshots__/Media.visual.test.tsx-snapshots/Media-render-stories-Default-light-webkit-linux.png b/src/blocks/Media/__snapshots__/Media.visual.test.tsx-snapshots/Media-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..fffe4205 Binary files /dev/null and b/src/blocks/Media/__snapshots__/Media.visual.test.tsx-snapshots/Media-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/Media/__tests__/Media.visual.test.tsx b/src/blocks/Media/__tests__/Media.visual.test.tsx new file mode 100644 index 00000000..936e9d57 --- /dev/null +++ b/src/blocks/Media/__tests__/Media.visual.test.tsx @@ -0,0 +1,21 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default} from './helpers'; + +const MEDIA_DELAY = 10 * 1000; + +test.describe('Media', () => { + test.skip('render stories ', async ({mount, expectScreenshot, delay, page}) => { + await mount(); + await delay(MEDIA_DELAY); + await expectScreenshot({ + skipTheme: 'dark', + mask: [ + page.locator('.bc-media__video'), + page.locator('.pc-media-component-data-lens__wrap'), + ], + }); + }); +}); diff --git a/src/blocks/Media/__tests__/helpers.tsx b/src/blocks/Media/__tests__/helpers.tsx new file mode 100644 index 00000000..b74dfe49 --- /dev/null +++ b/src/blocks/Media/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as MediaStories from '../__stories__/Media.stories'; + +export const {Default} = composeStories(MediaStories); diff --git a/src/blocks/Meta/__snapshots__/Meta.visual.test.tsx-snapshots/Meta-render-stories-Default-light-chromium-linux.png b/src/blocks/Meta/__snapshots__/Meta.visual.test.tsx-snapshots/Meta-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..23177f2b Binary files /dev/null and b/src/blocks/Meta/__snapshots__/Meta.visual.test.tsx-snapshots/Meta-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/Meta/__snapshots__/Meta.visual.test.tsx-snapshots/Meta-render-stories-Default-light-webkit-linux.png b/src/blocks/Meta/__snapshots__/Meta.visual.test.tsx-snapshots/Meta-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..13d8aa44 Binary files /dev/null and b/src/blocks/Meta/__snapshots__/Meta.visual.test.tsx-snapshots/Meta-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/Meta/__tests__/Meta.visual.test.tsx b/src/blocks/Meta/__tests__/Meta.visual.test.tsx new file mode 100644 index 00000000..379e08a6 --- /dev/null +++ b/src/blocks/Meta/__tests__/Meta.visual.test.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default} from './helpers'; + +test.describe('Meta', () => { + test('render stories ', async ({mount, expectScreenshot, defaultDelay}) => { + await mount(); + await defaultDelay(); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/blocks/Meta/__tests__/helpers.tsx b/src/blocks/Meta/__tests__/helpers.tsx new file mode 100644 index 00000000..c66a243c --- /dev/null +++ b/src/blocks/Meta/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as MetaStories from '../__stories__/Meta.stories'; + +export const {Default} = composeStories(MetaStories); diff --git a/src/blocks/Suggest/__snapshots__/Suggest.visual.test.tsx-snapshots/Suggest-render-stories-Default-light-chromium-linux.png b/src/blocks/Suggest/__snapshots__/Suggest.visual.test.tsx-snapshots/Suggest-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..35fa096d Binary files /dev/null and b/src/blocks/Suggest/__snapshots__/Suggest.visual.test.tsx-snapshots/Suggest-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/Suggest/__snapshots__/Suggest.visual.test.tsx-snapshots/Suggest-render-stories-Default-light-webkit-linux.png b/src/blocks/Suggest/__snapshots__/Suggest.visual.test.tsx-snapshots/Suggest-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..60c28e04 Binary files /dev/null and b/src/blocks/Suggest/__snapshots__/Suggest.visual.test.tsx-snapshots/Suggest-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/Suggest/__tests__/Suggest.visual.test.tsx b/src/blocks/Suggest/__tests__/Suggest.visual.test.tsx new file mode 100644 index 00000000..aeb2da9d --- /dev/null +++ b/src/blocks/Suggest/__tests__/Suggest.visual.test.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default} from './helpers'; + +test.describe('Suggest', () => { + test('render stories ', async ({mount, expectScreenshot, defaultDelay}) => { + await mount(); + await defaultDelay(); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/blocks/Suggest/__tests__/helpers.tsx b/src/blocks/Suggest/__tests__/helpers.tsx new file mode 100644 index 00000000..83be50c6 --- /dev/null +++ b/src/blocks/Suggest/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as SuggestStories from '../__stories__/Suggest.stories'; + +export const {Default} = composeStories(SuggestStories); diff --git a/src/blocks/YFM/__snapshots__/YFM.visual.test.tsx-snapshots/YFM-render-stories-Default-light-chromium-linux.png b/src/blocks/YFM/__snapshots__/YFM.visual.test.tsx-snapshots/YFM-render-stories-Default-light-chromium-linux.png new file mode 100644 index 00000000..09346da1 Binary files /dev/null and b/src/blocks/YFM/__snapshots__/YFM.visual.test.tsx-snapshots/YFM-render-stories-Default-light-chromium-linux.png differ diff --git a/src/blocks/YFM/__snapshots__/YFM.visual.test.tsx-snapshots/YFM-render-stories-Default-light-webkit-linux.png b/src/blocks/YFM/__snapshots__/YFM.visual.test.tsx-snapshots/YFM-render-stories-Default-light-webkit-linux.png new file mode 100644 index 00000000..e2d150c1 Binary files /dev/null and b/src/blocks/YFM/__snapshots__/YFM.visual.test.tsx-snapshots/YFM-render-stories-Default-light-webkit-linux.png differ diff --git a/src/blocks/YFM/__tests__/YFM.visual.test.tsx b/src/blocks/YFM/__tests__/YFM.visual.test.tsx new file mode 100644 index 00000000..6decb89d --- /dev/null +++ b/src/blocks/YFM/__tests__/YFM.visual.test.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default} from './helpers'; + +test.describe('YFM', () => { + test('render stories ', async ({mount, expectScreenshot, defaultDelay}) => { + await mount(); + await defaultDelay(); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/blocks/YFM/__tests__/helpers.tsx b/src/blocks/YFM/__tests__/helpers.tsx new file mode 100644 index 00000000..f7e2e61e --- /dev/null +++ b/src/blocks/YFM/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as YFMStories from '../__stories__/YFM.stories'; + +export const {Default} = composeStories(YFMStories); diff --git a/src/containers/BlogPage/BlogPage.tsx b/src/containers/BlogPage/BlogPage.tsx index a9e08b63..ae0e46fe 100644 --- a/src/containers/BlogPage/BlogPage.tsx +++ b/src/containers/BlogPage/BlogPage.tsx @@ -1,4 +1,4 @@ -import React, {SyntheticEvent, useMemo} from 'react'; +import React, {SyntheticEvent, useContext, useMemo} from 'react'; import { CustomConfig, @@ -23,6 +23,7 @@ import { Tag, ToggleLikeCallbackType, } from '../../models/common'; +import {SettingsContext} from '../../contexts/SettingsContext'; import './BlogPage.scss'; @@ -60,6 +61,7 @@ export const BlogPage = ({ isSignedInUser = false, onClickSignIn, }: BlogPageProps) => { + const {isAnimationEnabled} = useContext(SettingsContext); const {requireSignIn, ...promptSignInProps} = usePromptSignInProps(onClickSignIn); const likesContextData = useMemo( @@ -82,7 +84,10 @@ export const BlogPage = ({ pageCountForShowSupportButtons, }} > - + {metaData ? : null} Blog page; @@ -38,25 +39,26 @@ export default { }, } as Meta; -const WithNavigationTemplate: StoryFn = (args) => ( - `${pathPrefix ? `/${pathPrefix}` : ''}/blog/`, - }} - locale={{lang: Lang.En, pathPrefix: 'test'}} - > - - -); +const WithNavigationTemplate: StoryFn = (args) => { + const {isAnimationEnabled} = useContext(SettingsContext); -export const Default = { - render: (args: BlogPageProps, {globals}: StoryContext) => ( - + return ( + `${pathPrefix ? `/${pathPrefix}` : ''}/blog/`, + isAnimationEnabled, + }} + locale={{lang: Lang.En, pathPrefix: 'test'}} + > - ), + ); +}; + +export const Default = { + render: (args: BlogPageProps) => , }; export const WithNavigation = WithNavigationTemplate.bind({}); diff --git a/src/containers/BlogPage/__tests__/BlogPage.visual.test.tsx b/src/containers/BlogPage/__tests__/BlogPage.visual.test.tsx new file mode 100644 index 00000000..275af9d8 --- /dev/null +++ b/src/containers/BlogPage/__tests__/BlogPage.visual.test.tsx @@ -0,0 +1,21 @@ +import React from 'react'; + +import {test} from '../../../../playwright/core/index'; + +import {Default, WithNavigation} from './helpers'; + +const BLOG_POST_DALAY = 10 * 1000; + +test.describe('BlogPage', () => { + test('render stories ', async ({mount, expectScreenshot, delay}) => { + await mount(); + await delay(BLOG_POST_DALAY); + await expectScreenshot({skipTheme: 'dark'}); + }); + + test('render stories ', async ({mount, expectScreenshot, delay}) => { + await mount(); + await delay(BLOG_POST_DALAY); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/containers/BlogPage/__tests__/helpers.tsx b/src/containers/BlogPage/__tests__/helpers.tsx new file mode 100644 index 00000000..f12dfbf9 --- /dev/null +++ b/src/containers/BlogPage/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as BlogPageStories from '../__stories__/BlogPage.stories'; + +export const {Default, WithNavigation} = composeStories(BlogPageStories); diff --git a/src/containers/BlogPostPage/BlogPostPage.tsx b/src/containers/BlogPostPage/BlogPostPage.tsx index fc3af14b..737001d4 100644 --- a/src/containers/BlogPostPage/BlogPostPage.tsx +++ b/src/containers/BlogPostPage/BlogPostPage.tsx @@ -1,4 +1,4 @@ -import React, {SyntheticEvent, useMemo} from 'react'; +import React, {SyntheticEvent, useContext, useMemo} from 'react'; import {ShareOptions} from '@gravity-ui/components'; import { @@ -18,6 +18,7 @@ import {PostPageContext} from '../../contexts/PostPageContext'; import {useExtendedComponentMap} from '../../hooks/useExtendedComponentMap'; import {useLikes} from '../../hooks/useLikes'; import {MetaProps, PostData, ToggleLikeCallbackType} from '../../models/common'; +import {SettingsContext} from '../../contexts/SettingsContext'; import './BlogPostPage.scss'; @@ -53,6 +54,7 @@ export const BlogPostPage = ({ isSignedInUser = false, onClickSignIn, }: BlogPostPageProps) => { + const {isAnimationEnabled} = useContext(SettingsContext); const {hasUserLike, likesCount, handleLike} = useLikes({ hasLike: likes?.hasUserLike, count: likes?.likesCount, @@ -90,7 +92,10 @@ export const BlogPostPage = ({ shareOptions, }} > - + {metaData ? : null} { + test('render stories ', async ({mount, expectScreenshot, delay}) => { + await mount(); + await delay(BLOG_POST_PAGE_DALAY); + await expectScreenshot({skipTheme: 'dark'}); + }); + + test('render stories ', async ({mount, expectScreenshot, delay}) => { + await mount(); + await delay(BLOG_POST_PAGE_DALAY); + await expectScreenshot({skipTheme: 'dark'}); + }); +}); diff --git a/src/containers/BlogPostPage/__tests__/helpers.tsx b/src/containers/BlogPostPage/__tests__/helpers.tsx new file mode 100644 index 00000000..559f0f5b --- /dev/null +++ b/src/containers/BlogPostPage/__tests__/helpers.tsx @@ -0,0 +1,5 @@ +import {composeStories} from '@storybook/react'; + +import * as BlogPostPageStories from '../__stories__/BlogPostPage.stories'; + +export const {Default, WithNavigation} = composeStories(BlogPostPageStories); diff --git a/src/contexts/SettingsContext.ts b/src/contexts/SettingsContext.ts index 62fe37db..70a7fdf5 100644 --- a/src/contexts/SettingsContext.ts +++ b/src/contexts/SettingsContext.ts @@ -2,6 +2,7 @@ import React from 'react'; export interface SettingsContextProps { addNavigationLinkForPages?: boolean; + isAnimationEnabled?: boolean; getBlogPath?: (pathPrefix: string) => string; }