diff --git a/.changeset/clever-eagles-repeat.md b/.changeset/clever-eagles-repeat.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/clever-eagles-repeat.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/dry-turkeys-lay.md b/.changeset/dry-turkeys-lay.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/dry-turkeys-lay.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.eslintrc.js b/.eslintrc.js index c081b89da1d..b6cb63a3371 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -39,7 +39,7 @@ module.exports = { "sort-imports-es6-autofix", "ssr-friendly", "jsx-a11y", - "jest", + "vitest", ], rules: { "@typescript-eslint/adjacent-overload-signatures": "error", @@ -177,19 +177,19 @@ module.exports = { pathGroupsExcludedImportTypes: [], }, ], - "jest/consistent-test-it": ["error", { fn: "it" }], - "jest/expect-expect": "error", - "jest/no-commented-out-tests": "error", - "jest/no-conditional-expect": "error", - "jest/no-focused-tests": "error", - "jest/no-disabled-tests": "error", - "jest/no-standalone-expect": "error", - "jest/no-test-return-statement": "error", - "jest/prefer-equality-matcher": "error", - "jest/require-top-level-describe": "error", - "jest/valid-describe-callback": "error", - "jest/valid-expect": "error", - "jest/valid-title": "error", + "vitest/consistent-test-it": ["error", { fn: "it" }], + "vitest/expect-expect": "error", + "vitest/no-commented-out-tests": "error", + "vitest/no-conditional-expect": "error", + "vitest/no-focused-tests": "error", + "vitest/no-disabled-tests": "error", + "vitest/no-standalone-expect": "error", + "vitest/no-test-return-statement": "error", + "vitest/prefer-equality-matcher": "error", + "vitest/require-top-level-describe": "error", + "vitest/valid-describe-callback": "error", + "vitest/valid-expect": "error", + "vitest/valid-title": "error", "jsdoc/check-alignment": "off", "jsdoc/check-indentation": "off", "jsdoc/newline-after-description": "off", @@ -320,7 +320,7 @@ module.exports = { }, }, { - files: ["**/bin/**", "jest.setup.ts"], + files: ["**/bin/**", "vitest.setup.ts"], rules: { "no-console": "off", }, diff --git a/.github/actions/branch-preview/action.yml b/.github/actions/branch-preview/action.yml index 4d6d295d411..794ed94dd98 100644 --- a/.github/actions/branch-preview/action.yml +++ b/.github/actions/branch-preview/action.yml @@ -29,7 +29,7 @@ runs: body-includes: ":sparkles: Here is your branch preview! :sparkles:" - name: Create or update comment - uses: peter-evans/create-or-update-comment@v3 + uses: peter-evans/create-or-update-comment@v4 with: comment-id: ${{ steps.findComment.outputs.comment-id }} issue-number: ${{ inputs.prNumber }} diff --git a/.github/workflows/ci.yml b/.github/workflows/lint.yml similarity index 86% rename from .github/workflows/ci.yml rename to .github/workflows/lint.yml index a4190e39046..11009b4f3f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/lint.yml @@ -1,4 +1,4 @@ -name: ci +name: lint on: push: @@ -53,12 +53,3 @@ jobs: - uses: actions/checkout@v4 - uses: ./.github/actions/setup - run: pnpm lint:styles - - jest: - if: github.head_ref != 'changeset-release/main' - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/setup - - run: pnpm test:ci diff --git a/.github/workflows/test-stories.yaml b/.github/workflows/test-stories.yaml index f92c0635bdf..4d0c0024699 100644 --- a/.github/workflows/test-stories.yaml +++ b/.github/workflows/test-stories.yaml @@ -62,7 +62,7 @@ jobs: with: artifactName: ${{ env.ARTIFACT_NAME }} - name: Storybook tests (1/3) - run: pnpm -F @docs/storybook test -- --shard 1/3 + run: pnpm turbo @docs/storybook#test:storybook -- --shard 1/3 storybook-tests-2: name: "test-storybook" @@ -78,7 +78,7 @@ jobs: with: artifactName: ${{ env.ARTIFACT_NAME }} - name: Storybook tests (2/3) - run: pnpm -F @docs/storybook test -- --shard 2/3 + run: pnpm turbo @docs/storybook#test:storybook -- --shard 2/3 storybook-tests-3: name: "test-storybook" @@ -94,7 +94,7 @@ jobs: with: artifactName: ${{ env.ARTIFACT_NAME }} - name: Storybook tests (3/3) - run: pnpm -F @docs/storybook test -- --shard 3/3 + run: pnpm turbo @docs/storybook#test:storybook -- --shard 3/3 chromatic: needs: run-check diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml new file mode 100644 index 00000000000..fdc3458cd19 --- /dev/null +++ b/.github/workflows/test-unit.yml @@ -0,0 +1,52 @@ +name: test unit + +on: + push: + branches-ignore: + - main + + # When Changesets opens a PR it does not trigger GitHub actions, + # because its token does not have permission to. This is a hack + # to allow one of us to trigger GitHub actions for a changesets PR + # by enabling automerge on the PR. + pull_request_target: + types: + - auto_merge_enabled + branches: + - main # the target branch of the PR + paths: + - "**/CHANGELOG.md" # only changesets releases touch changelogs + +jobs: + unit-tests: + if: github.head_ref != 'changeset-release/main' + name: "vitest" + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup + - name: Unit tests (1/3) + run: pnpm test -- -- --run --shard=1/3 + + unit-tests-2: + if: github.head_ref != 'changeset-release/main' + name: "vitest" + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup + - name: Unit tests (2/3) + run: pnpm test -- -- --run --shard=2/3 + + unit-tests-3: + if: github.head_ref != 'changeset-release/main' + name: "vitest" + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup + - name: Unit tests (3/3) + run: pnpm test -- -- --run --shard=3/3 diff --git a/docs/.storybook/main.ts b/docs/.storybook/main.ts index e9c3fa5a909..3347383cc20 100644 --- a/docs/.storybook/main.ts +++ b/docs/.storybook/main.ts @@ -1,6 +1,6 @@ import path, { join, dirname } from "path" import type { StorybookConfig } from "@storybook/react-vite" -import { mergeAlias } from "vite" +import { nodePolyfills } from "vite-plugin-node-polyfills" /** * This function is used to resolve the absolute path of a package. @@ -25,6 +25,14 @@ const config: StorybookConfig = { "storybook-addon-pseudo-states", ], framework: "@storybook/react-vite", + core: { + builder: { + name: "@storybook/builder-vite", + options: { + viteConfigPath: path.resolve(__dirname, "../../vite.config.ts"), + }, + }, + }, staticDirs: [ { from: "../assets", @@ -46,43 +54,10 @@ const config: StorybookConfig = { }, }, }, - viteFinal: viteConfig => ({ - ...viteConfig, - resolve: { - alias: mergeAlias( - [ - { - // this is required for the SCSS modules - find: /^~(.*)$/, - replacement: "$1", - }, - { - // monorepo workspace aliases - find: /^\@kaizen(.*)$/, - replacement: path.resolve(__dirname, "../../packages$1"), - }, - ], - { - "~storybook": path.resolve(__dirname, "../"), - "~components": path.resolve( - __dirname, - "../../packages/components/src" - ), - "~design-tokens": path.resolve( - __dirname, - "../../packages/design-tokens/src" - ), - "~tailwind": path.resolve(__dirname, "../../packages/tailwind/src"), - // i18n-react-intl package attempts to import locales from this path. - // When rollup attempts to import from the 'find' path, it will be - // redirected to import from the replacement path (Same as KAIO rollup config). - "__@cultureamp/i18n-react-intl/locales": path.resolve( - __dirname, - "../../packages/components/locales" - ), - } - ), - }, - }), + viteFinal: config => { + config?.plugins?.push(nodePolyfills()) + + return config + }, } export default config diff --git a/docs/package.json b/docs/package.json index 4defadfc8a8..f8aea1e547f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -12,7 +12,7 @@ "build:test": "storybook build --test", "build:chromatic": "storybook build --webpack-stats-json", "build:tailwind": "npx tailwindcss -i ./tailwind.css -o ./.storybook/preview.css", - "test": "test-storybook --skipTags='skip-test' --url http://127.0.0.1:6006", + "test:storybook": "test-storybook --skipTags='skip-test' --url http://127.0.0.1:6006", "clean": "rimraf './storybook-static' './node_modules' '.turbo'" }, "dependencies": { @@ -24,6 +24,7 @@ "@kaizen/design-tokens": "workspace:*", "@kaizen/tailwind": "workspace:*", "@rollup/plugin-alias": "^5.1.0", + "@storybook/builder-vite": "^8.2.9", "@storybook/manager-api": "^8.2.9", "@storybook/react-vite": "^8.2.9", "@storybook/test-runner": "^0.19.1", @@ -33,10 +34,14 @@ "classnames": "^2.5.1", "globals": "^15.9.0", "highlight.js": "^11.10.0", + "jest-axe": "^9.0.0", "sass": "^1.77.8", "storybook": "^8.2.9", "tailwindcss": "^3.4.10", - "vite": "^5.4.2" + "vite-plugin-node-polyfills": "^0.22.0" + }, + "peerDependencies": { + "vite": ">=5.4.2" }, "eslintConfig": { "extends": [ diff --git a/jest.config.ts b/jest.config.ts deleted file mode 100644 index 55f26467cba..00000000000 --- a/jest.config.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { JestConfigWithTsJest } from "ts-jest" - -const jestConfig: JestConfigWithTsJest = { - preset: "ts-jest", - testEnvironment: "jsdom", - testMatch: ["**/*.spec.ts?(x)"], - setupFilesAfterEnv: ["jest-canvas-mock", "/jest.setup.ts"], - moduleNameMapper: { - "\\.(jpe?g|png|webm|mp4)$": "jest-static-stubs/$1", - "\\.s?css$": "identity-obj-proxy", - }, - transformIgnorePatterns: ["[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"], -} - -export default jestConfig - -process.env.TZ = "UTC" diff --git a/jest.setup.ts b/jest.setup.ts deleted file mode 100644 index bd218cf0411..00000000000 --- a/jest.setup.ts +++ /dev/null @@ -1,16 +0,0 @@ -import "@testing-library/jest-dom" - -/** @ts-ignore */ -global.IS_REACT_ACT_ENVIRONMENT = true - -const CONSOLE_FAIL_TYPES = ["error", "warn"] as const - -// Throw errors when a `console.error` or `console.warn` happens -// by overriding the functions -CONSOLE_FAIL_TYPES.forEach(type => { - console[type] = message => { - throw new Error( - `Failing due to console.${type} while running test!\n\n${message}` - ) - } -}) diff --git a/package.json b/package.json index a6910c7eac0..7c5c2bf68e1 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,10 @@ "build": "pnpm turbo build", "clean": "pnpm turbo clean && rimraf node_modules && pnpm store prune", "test": "pnpm turbo test", - "test:ci": "pnpm turbo test:ci", - "jest:debug": "node --inspect-brk node_modules/.bin/jest --runInBand --no-cache", - "eslint-config": "pnpm eslint -c .eslintrc.js --max-warnings=0", "lint": "pnpm lint:js && pnpm lint:md && pnpm lint:format && pnpm lint:styles", "lint:ts": "pnpm turbo lint:ts", - "lint:js": "pnpm eslint-config '**/*.{ts,tsx,mjs,js}'", - "lint:md": "pnpm eslint-config '**/*.{md,mdx}'", + "lint:js": "pnpm eslint '**/*.{ts,tsx,mjs,js}' --max-warnings=0", + "lint:md": "pnpm eslint '**/*.{md,mdx}' --max-warnings=0", "lint:format": "pnpm prettier --check '**/*'", "lint:scss": "pnpm stylelint '**/*.scss' --config .stylelintrc-scss.json", "lint:css": "pnpm stylelint '**/*.css' --config .stylelintrc-css.mjs", @@ -58,12 +55,9 @@ "@storybook/test": "^8.2.9", "@storybook/theming": "^8.2.9", "@stylistic/eslint-plugin": "^2.6.4", - "@testing-library/dom": "^10.4.0", - "@testing-library/jest-dom": "^6.4.8", + "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.5.2", - "@types/jest": "^29.5.12", - "@types/jest-axe": "^3.5.9", "@types/node": "^20.14.12", "@types/react": "^18.3.4", "@types/react-dom": "^18.3.0", @@ -74,18 +68,13 @@ "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jest": "^27.9.0", "eslint-plugin-jsx-a11y": "^6.9.0", "eslint-plugin-mdx": "^3.1.5", "eslint-plugin-react": "^7.35.0", "eslint-plugin-sort-imports-es6-autofix": "^0.6.0", "eslint-plugin-ssr-friendly": "^1.3.0", "eslint-plugin-storybook": "^0.8.0", - "jest": "^29.7.0", - "jest-axe": "^9.0.0", - "jest-canvas-mock": "^2.5.2", - "jest-environment-jsdom": "^29.7.0", - "jest-static-stubs": "^0.0.1", + "eslint-plugin-vitest": "^0.5.4", "node-fetch": "^3.3.2", "playwright": "^1.46.1", "plop": "^4.0.1", @@ -95,15 +84,16 @@ "stylelint": "^16.8.2", "stylelint-config-standard": "^36.0.1", "stylelint-config-standard-scss": "^13.1.0", - "ts-jest": "^29.2.4", - "ts-node": "^10.9.2", "turbo": "^2.0.14", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "vite": "^5.4.2", + "vitest": "^2.0.5", + "vitest-axe": "^0.1.0" }, "devDependenciesComments": { - "ts-node": "Required for jest", "@storybook/*": "Required for Storybook stories across all packages", "chromatic": "Required for Storybook stories across all packages", - "playwright": "Required for github actions setup" + "playwright": "Required for github actions setup", + "vite-plugin-node-polyfills": "Adds the node `assert` polyfill to Vite for prosemirror to run in storybook" } } diff --git a/packages/components/__tests__/index.ts b/packages/components/__tests__/index.ts index de336a4484f..413be08733e 100644 --- a/packages/components/__tests__/index.ts +++ b/packages/components/__tests__/index.ts @@ -1 +1 @@ -export * from "./renderWithIntl" +export * from "./reactIntlMock" diff --git a/packages/components/__tests__/reactIntlMock.ts b/packages/components/__tests__/reactIntlMock.ts new file mode 100644 index 00000000000..428c373d3ed --- /dev/null +++ b/packages/components/__tests__/reactIntlMock.ts @@ -0,0 +1,42 @@ +import { MessageDescriptor } from "@cultureamp/i18n-react-intl" +import { vi } from "vitest" + +const replaceInputValue = (str: string, value: string): string => { + const regex = /{([^}]+)}/g + return str.replace(regex, (match, capturedValue) => { + if (capturedValue) { + return value[capturedValue] + } + // Handle other captured values here if needed + return match + }) +} + +// Note: This mock does not exist to enable testing of internationalisation, +// but to silence the errors from components that requires `useIntl` +// and `FormattedMessage` from `@cultureamp/i18n-react-intl` +// +// If you need to test internationalisation, you should use Storybook stories +export const reactIntlMock = (): any => { + const mocks = vi.hoisted(() => ({ + useIntl: vi.fn(), + FormattedMessage: vi.fn(), + })) + + vi.mock("@cultureamp/i18n-react-intl", () => ({ + StaticIntlProvider: ({ children }: { children: React.ReactNode }) => + children, + useIntl: () => ({ + formatMessage: (message: MessageDescriptor, values: any) => + values + ? replaceInputValue(message.defaultMessage as string, values) + : message.defaultMessage, + }), + FormattedMessage: (message: MessageDescriptor & { values: any }) => + message.values + ? replaceInputValue(message.defaultMessage as string, message.values) + : message.defaultMessage, + })) + + return mocks +} diff --git a/packages/components/__tests__/renderWithIntl.tsx b/packages/components/__tests__/renderWithIntl.tsx deleted file mode 100644 index 9c5489a383d..00000000000 --- a/packages/components/__tests__/renderWithIntl.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from "react" -import { StaticIntlProvider } from "@cultureamp/i18n-react-intl" -import { render } from "@testing-library/react" - -/** - * i18n is async, so ensure your test is `async` and you `await waitFor` your result - */ -export const renderWithIntl = ( - children: React.ReactNode -): ReturnType => - render({children}) diff --git a/packages/components/codemods/utils/__snapshots__/transformSource.spec.ts.snap b/packages/components/codemods/utils/__snapshots__/transformSource.spec.ts.snap index 74325cf4157..82debc5ae8d 100644 --- a/packages/components/codemods/utils/__snapshots__/transformSource.spec.ts.snap +++ b/packages/components/codemods/utils/__snapshots__/transformSource.spec.ts.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`transformSource updates the value of Pancakes topping to jam 1`] = ` +exports[`transformSource > updates the value of Pancakes topping to jam 1`] = ` "import * as React from "react"; // @ts-ignore import { Pancakes } from "@kaizen/components"; diff --git a/packages/components/jest.config.ts b/packages/components/jest.config.ts deleted file mode 100644 index d48a15af325..00000000000 --- a/packages/components/jest.config.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { JestConfigWithTsJest } from "ts-jest" -import sharedConfig from "../../jest.config" - -const jestConfig: JestConfigWithTsJest = { - ...sharedConfig, - roots: [""], - moduleNameMapper: { - ...sharedConfig.moduleNameMapper, - "~tests": "/__tests__/index", - "~tests/(.*)$": "/__tests__/$1", - "~components/(.*)$": "/src/$1", - "^__@cultureamp/i18n-react-intl/locales/(.*)": "/locales/$1", - }, -} - -export default jestConfig diff --git a/packages/components/jest.setup.ts b/packages/components/jest.setup.ts deleted file mode 100644 index 017691afb46..00000000000 --- a/packages/components/jest.setup.ts +++ /dev/null @@ -1 +0,0 @@ -import "../../jest.setup" diff --git a/packages/components/package.json b/packages/components/package.json index 0152ad8015d..9276fe82d3d 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -40,8 +40,7 @@ "build:global-styles": "postcss ./styles/global.css --output dist/global.css", "build:combine-styles": "concat-cli -f ./dist/global.css ./dist/styles.css -o ./dist/styles.css && rm ./dist/global.css", "build:styles": "pnpm build:global-styles && pnpm build:combine-styles", - "test": "FORCE_COLOR=1 jest", - "test:ci": "pnpm test -- --ci", + "test": "FORCE_COLOR=1 vitest --config ../../vite.config.ts", "update-icons": "./src/Icon/bin/update-icons.sh", "i18n:extract": "pnpm i18n-extract", "clean": "rimraf 'dist' 'node_modules' '.turbo'", @@ -107,6 +106,8 @@ "@kaizen/design-tokens": "workspace:*", "@kaizen/package-bundler": "workspace:*", "@tanstack/react-query": "^5.51.23", + "@testing-library/dom": "^10.4.0", + "@types/jest-axe": "^3.5.9", "@types/lodash.debounce": "^4.0.9", "@types/react-highlight": "^0.12.8", "@types/react-textfit": "^1.1.4", @@ -114,6 +115,7 @@ "autoprefixer": "^10.4.20", "concat-cli": "^4.0.0", "identity-obj-proxy": "^3.0.0", + "jest-axe": "^9.0.0", "lodash.isempty": "^4.4.0", "normalize.css": "^8.0.1", "postcss": "^8.4.41", @@ -130,7 +132,6 @@ "sass": "^1.77.8", "serialize-query-params": "^2.0.2", "svgo": "^3.3.2", - "ts-jest": "^29.2.4", "tslib": "^2.6.3", "tsx": "^4.17.0" }, diff --git a/packages/components/src/Avatar/Avatar.spec.tsx b/packages/components/src/Avatar/Avatar.spec.tsx index 915282e8841..e01f23ce4a2 100644 --- a/packages/components/src/Avatar/Avatar.spec.tsx +++ b/packages/components/src/Avatar/Avatar.spec.tsx @@ -6,7 +6,7 @@ describe("", () => { // there is an issue with react-textfit that is only flagged in a test suite // this solution silences that specific case https://github.com/malte-wessel/react-textfit/issues/35 beforeEach(() => { - jest.spyOn(console, "warn").mockImplementation(() => "") + vi.spyOn(console, "warn").mockImplementation(() => "") }) it("renders user initials if the image link is broken", () => { diff --git a/packages/components/src/Calendar/utils/setFocusInCalendar.spec.tsx b/packages/components/src/Calendar/utils/setFocusInCalendar.spec.tsx index 468309fb10a..8bd309c5561 100644 --- a/packages/components/src/Calendar/utils/setFocusInCalendar.spec.tsx +++ b/packages/components/src/Calendar/utils/setFocusInCalendar.spec.tsx @@ -2,13 +2,13 @@ import React from "react" import { render, screen, within } from "@testing-library/react" import { format } from "date-fns" import { enUS } from "date-fns/locale" +import { vi } from "vitest" import { CalendarSingle, CalendarSingleProps } from "../CalendarSingle" import { setFocusInCalendar } from "./setFocusInCalendar" - const CalendarWrapper = (props: Partial): JSX.Element => ( setFocusInCalendar(calendarElement, props.selected) diff --git a/packages/components/src/Checkbox/Checkbox/Checkbox.spec.tsx b/packages/components/src/Checkbox/Checkbox/Checkbox.spec.tsx index 000c35d11b2..f9fc7737176 100644 --- a/packages/components/src/Checkbox/Checkbox/Checkbox.spec.tsx +++ b/packages/components/src/Checkbox/Checkbox/Checkbox.spec.tsx @@ -1,9 +1,9 @@ import React from "react" import { render, waitFor } from "@testing-library/react" import userEvent from "@testing-library/user-event" +import { vi } from "vitest" import { CheckboxProps } from "./Checkbox" import { Checkbox } from "." - const user = userEvent.setup() const defaultProps = { @@ -11,7 +11,7 @@ const defaultProps = { checkedStatus: "off", disabled: false, name: "someCheckboxName", - onCheck: jest.fn(), + onCheck: vi.fn(), } satisfies CheckboxProps describe("", () => { diff --git a/packages/components/src/Collapsible/Collapsible/Collapsible.spec.tsx b/packages/components/src/Collapsible/Collapsible/Collapsible.spec.tsx index 46854381a1d..0fd2833f4f5 100644 --- a/packages/components/src/Collapsible/Collapsible/Collapsible.spec.tsx +++ b/packages/components/src/Collapsible/Collapsible/Collapsible.spec.tsx @@ -1,23 +1,11 @@ import React from "react" import { queryByTestId, render, waitFor } from "@testing-library/react" import userEvent from "@testing-library/user-event" +import { vi } from "vitest" import { Collapsible } from "./Collapsible" - const user = userEvent.setup() describe("", () => { - it("includes the 'sticky' class on buttons when the 'sticky' prop is specified", () => { - const { getByTestId } = render( - - First panel content - - ) - - const collapsibleContainer = getByTestId("collapsible-header-1") - - expect(collapsibleContainer.classList.contains("sticky")).toBeTruthy() - }) - it("toggles the height of the section on click of the button", async () => { const { getByTestId } = render( @@ -74,7 +62,7 @@ describe("", () => { }) it("runs the onToggle callback", async () => { - const onToggle = jest.fn() + const onToggle = vi.fn() const { getByTestId } = render( diff --git a/packages/components/src/Collapsible/Collapsible/_docs/Collapsible.stickersheet.stories.tsx b/packages/components/src/Collapsible/Collapsible/_docs/Collapsible.stickersheet.stories.tsx index e13bc87c537..b70e6dd7ca6 100644 --- a/packages/components/src/Collapsible/Collapsible/_docs/Collapsible.stickersheet.stories.tsx +++ b/packages/components/src/Collapsible/Collapsible/_docs/Collapsible.stickersheet.stories.tsx @@ -1,6 +1,8 @@ import React from "react" import { Meta } from "@storybook/react" +import { within } from "@storybook/test" import { Heading } from "~components/Heading" +import { Text } from "~components/Text" import { StickerSheet, StickerSheetStory, @@ -73,3 +75,50 @@ export const StickerSheetRTL: StickerSheetStory = { name: "Sticker Sheet (RTL)", parameters: { textDirection: "rtl" }, } + +export const Sticky: StickerSheetStory = { + render: () => ( + + + +
+ + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Phasellus ac scelerisque sem, vel ultricies justo. Donec eu + porttitor ante, nec gravida orci. Nulla facilisi. Cras varius + erat id fermentum mattis. Mauris bibendum vestibulum erat, quis + blandit metus viverra sit amet. Vivamus pretium vitae turpis ut + condimentum. Sed vulputate magna nisl, in cursus urna hendrerit + et. Aenean semper, est non feugiat sodales, nisl ligula aliquet + lorem, sit amet scelerisque arcu quam a sapien. Donec in viverra + urna. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Phasellus ac scelerisque sem, vel ultricies justo. Donec eu + porttitor ante, nec gravida orci. Nulla facilisi. Cras varius + erat id fermentum mattis. Mauris bibendum vestibulum erat, quis + blandit metus viverra sit amet. Vivamus pretium vitae turpis ut + condimentum. Sed vulputate magna nisl, in cursus urna hendrerit + et. Aenean semper, est non feugiat sodales, nisl ligula aliquet + lorem, sit amet scelerisque arcu quam a sapien. Donec in viverra + urna. + + +
+
+
+
+ ), + play: async ({ canvasElement }) => { + const canvas = within(canvasElement) + const element = canvas.getByTestId("bottom-content") + element.scrollIntoView({ behavior: "instant", block: "end" }) + }, +} diff --git a/packages/components/src/Collapsible/Collapsible/_docs/Collapsible.stories.tsx b/packages/components/src/Collapsible/Collapsible/_docs/Collapsible.stories.tsx index 7a81b86a748..29db0efce90 100644 --- a/packages/components/src/Collapsible/Collapsible/_docs/Collapsible.stories.tsx +++ b/packages/components/src/Collapsible/Collapsible/_docs/Collapsible.stories.tsx @@ -88,17 +88,6 @@ export const CustomHeader: Story = { ), } -export const Sticky: Story = { - args: { - title: "Sticky header", - }, - render: ({ title }) => ( - - This does not work in Storybook docs, so use this as a code example only. - - ), -} - const controlledSourceCode = ` const [isOpen, setIsOpen] = useState(false) return () diff --git a/packages/components/src/DateInput/DateInputDescription/DateInputDescription.spec.tsx b/packages/components/src/DateInput/DateInputDescription/DateInputDescription.spec.tsx index 4d6defd338b..10a2e71188d 100644 --- a/packages/components/src/DateInput/DateInputDescription/DateInputDescription.spec.tsx +++ b/packages/components/src/DateInput/DateInputDescription/DateInputDescription.spec.tsx @@ -1,19 +1,18 @@ import React from "react" -import { waitFor } from "@testing-library/react" +import { waitFor, render } from "@testing-library/react" import { enUS } from "date-fns/locale" -import { renderWithIntl } from "~tests" import { DateInputDescription } from "./DateInputDescription" describe("DateInputDescription", () => { it("returns template string when description is undefined", async () => { - const { container } = renderWithIntl() + const { container } = render() await waitFor(() => { expect(container).toHaveTextContent("Input format:mm/dd/yyyy") }) }) it("returns template string when description is empty string", async () => { - const { container } = renderWithIntl( + const { container } = render( ) await waitFor(() => { @@ -22,7 +21,7 @@ describe("DateInputDescription", () => { }) it("returns template string when description is a string", async () => { - const { container } = renderWithIntl( + const { container } = render( { }) it("returns template string when description is an element", async () => { - const { container } = renderWithIntl( + const { container } = render( Custom description span} locale={enUS} diff --git a/packages/components/src/DateInput/DateInputWithIconButton/DateInputWithIconButton.spec.tsx b/packages/components/src/DateInput/DateInputWithIconButton/DateInputWithIconButton.spec.tsx index a75139e0bc3..8d9316df9b6 100644 --- a/packages/components/src/DateInput/DateInputWithIconButton/DateInputWithIconButton.spec.tsx +++ b/packages/components/src/DateInput/DateInputWithIconButton/DateInputWithIconButton.spec.tsx @@ -1,6 +1,7 @@ import React, { useRef } from "react" import { render, screen } from "@testing-library/react" import userEvent from "@testing-library/user-event" +import { vi } from "vitest" import { DateInputWithIconButton, DateInputWithIconButtonProps, @@ -11,7 +12,7 @@ const user = userEvent.setup() const defaultProps: DateInputWithIconButtonProps = { id: "test__date-input-with-icon-button", labelText: "Due date", - onButtonClick: jest.fn(), + onButtonClick: vi.fn(), } const DateInputWithIconButtonWrapper = ( @@ -52,10 +53,7 @@ describe("", () => { describe("Refs", () => { it("correctly passes through input and button refs", async () => { - const onButtonClick = jest.fn< - void, - [string | null | undefined, string | null | undefined] - >() + const onButtonClick = vi.fn() const Wrapper = (): JSX.Element => { const inputRef = useRef(null) @@ -74,7 +72,7 @@ describe("", () => { ref={ref} id="test__date-input-field--ref" labelText="label" - onButtonClick={jest.fn()} + onButtonClick={vi.fn()} />