diff --git a/.github/workflows/actions/restore-cache/action.yaml b/.github/workflows/actions/restore-cache/action.yaml index 35133dd0ca..b1f534e068 100644 --- a/.github/workflows/actions/restore-cache/action.yaml +++ b/.github/workflows/actions/restore-cache/action.yaml @@ -25,7 +25,7 @@ runs: uses: actions/cache/restore@v4 id: restore-cache with: - key: ${{ steps.cache-primary-key-builder.outputs.CACHE_PRIMARY_KEY_PREFIX }}-${{ github.sha }} + key: ${{ steps.cache-primary-key-builder.outputs.CACHE_PRIMARY_KEY_PREFIX }}-${{ github.sha }} restore-keys: ${{ steps.cache-primary-key-builder.outputs.CACHE_PRIMARY_KEY_PREFIX }}- path: | .cache diff --git a/.github/workflows/ci-front.yaml b/.github/workflows/ci-front.yaml index 89a1c09c9d..8d3f73d2fb 100644 --- a/.github/workflows/ci-front.yaml +++ b/.github/workflows/ci-front.yaml @@ -11,7 +11,8 @@ concurrency: cancel-in-progress: true env: - STORYBOOK_BUILD_CACHE_KEY: storybook-build-depot-ubuntu-24.04-8-runner + STORYBOOK_BUILD_CACHE_KEY_FOR_RESTORE_ACTION: storybook-build-depot-ubuntu-24.04-8-runner + STORYBOOK_BUILD_CACHE_KEY_FOR_SAVE_ACTION: v3-storybook-build-depot-ubuntu-24.04-8-runner-${{ github.ref_name }}-${{ github.sha }} jobs: changed-files-check: @@ -23,7 +24,7 @@ jobs: packages/twenty-ui/** packages/twenty-shared/** front-sb-build: - needs: [changed-files-check] + needs: changed-files-check if: needs.changed-files-check.outputs.any_changed == 'true' timeout-minutes: 30 runs-on: depot-ubuntu-24.04-8 @@ -42,11 +43,6 @@ jobs: uses: ./.github/workflows/actions/yarn-install - name: Diagnostic disk space issue run: df -h - - name: Restore storybook build cache - id: restore-storybook-build-cache - uses: ./.github/workflows/actions/restore-cache - with: - key: ${{ env.STORYBOOK_BUILD_CACHE_KEY }} - name: Front / Write .env run: npx nx reset:env twenty-front - name: Front / Build storybook @@ -54,7 +50,7 @@ jobs: - name: Save storybook build cache uses: ./.github/workflows/actions/save-cache with: - key: ${{ steps.restore-storybook-build-cache.outputs.cache-primary-key }} + key: ${{ env.STORYBOOK_BUILD_CACHE_KEY_FOR_SAVE_ACTION }} front-sb-test: timeout-minutes: 30 runs-on: depot-ubuntu-24.04-8 @@ -79,7 +75,7 @@ jobs: - name: Restore storybook build cache uses: ./.github/workflows/actions/restore-cache with: - key: ${{ env.STORYBOOK_BUILD_CACHE_KEY }} + key: ${{ env.STORYBOOK_BUILD_CACHE_KEY_FOR_RESTORE_ACTION }} - name: Front / Write .env run: npx nx reset:env twenty-front - name: Run storybook tests diff --git a/packages/twenty-front/.storybook/main.ts b/packages/twenty-front/.storybook/main.ts index ada8c335bd..b710e79da7 100644 --- a/packages/twenty-front/.storybook/main.ts +++ b/packages/twenty-front/.storybook/main.ts @@ -73,6 +73,7 @@ const config: StorybookConfig = { 'react-dom/client': 'react-dom/profiling', }, }, + logLevel: 'warn', }); }, diff --git a/packages/twenty-front/.storybook/preview.tsx b/packages/twenty-front/.storybook/preview.tsx index 7f14f6ff7a..6734aef0a9 100644 --- a/packages/twenty-front/.storybook/preview.tsx +++ b/packages/twenty-front/.storybook/preview.tsx @@ -90,8 +90,6 @@ const preview: Preview = { tokenPair: `{%22accessOrWorkspaceAgnosticToken%22:{%22token%22:%22${mockedUserJWT}%22%2C%22expiresAt%22:%222023-07-18T15:06:40.704Z%22%2C%22__typename%22:%22AuthToken%22}%2C%22refreshToken%22:{%22token%22:%22${mockedUserJWT}%22%2C%22expiresAt%22:%222023-10-15T15:06:41.558Z%22%2C%22__typename%22:%22AuthToken%22}%2C%22__typename%22:%22AuthTokenPair%22}`, }, }, - - tags: ['autodocs'], }; export default preview; diff --git a/packages/twenty-front/.storybook/test-runner-jest.config.js b/packages/twenty-front/.storybook/test-runner-jest.config.js index b08d8e6af5..38ce8b92c8 100644 --- a/packages/twenty-front/.storybook/test-runner-jest.config.js +++ b/packages/twenty-front/.storybook/test-runner-jest.config.js @@ -12,4 +12,10 @@ export default { * @see https://jestjs.io/docs/configuration */ testTimeout: 5 * MINUTES_IN_MS, + modulePathIgnorePatterns: [ + "/.nx/cache/*", + "/packages/twenty-server/dist/*", + "/packages/twenty-front/dist/*", + "/packages/twenty-ui/dist/*" + ], }; diff --git a/packages/twenty-front/.storybook/test-runner.ts b/packages/twenty-front/.storybook/test-runner.ts new file mode 100644 index 0000000000..73c63c93d8 --- /dev/null +++ b/packages/twenty-front/.storybook/test-runner.ts @@ -0,0 +1,9 @@ +import type { TestRunnerConfig } from '@storybook/test-runner'; + +const config: TestRunnerConfig = { + tags: { + exclude: ['no-tests'], + }, +}; + +export default config; diff --git a/packages/twenty-front/__mocks__/imageMock.js b/packages/twenty-front/__mocks__/imageMockFront.js similarity index 100% rename from packages/twenty-front/__mocks__/imageMock.js rename to packages/twenty-front/__mocks__/imageMockFront.js diff --git a/packages/twenty-front/jest.config.mjs b/packages/twenty-front/jest.config.mjs index 110b19291d..f7ddd9949e 100644 --- a/packages/twenty-front/jest.config.mjs +++ b/packages/twenty-front/jest.config.mjs @@ -51,7 +51,7 @@ const jestConfig = { }, moduleNameMapper: { '\\.(jpg|jpeg|png|gif|webp|svg|svg\\?react)$': - '/__mocks__/imageMock.js', + '/__mocks__/imageMockFront.js', '\\.css$': '/__mocks__/styleMock.js', ...pathsToModuleNameMapper(tsConfig.compilerOptions.paths, { prefix: '/../../', diff --git a/packages/twenty-front/src/loading/components/__stories__/PrefetchLoading.stories.tsx b/packages/twenty-front/src/loading/components/__stories__/PrefetchLoading.stories.tsx index 20ebfc567c..f6a0ca09a8 100644 --- a/packages/twenty-front/src/loading/components/__stories__/PrefetchLoading.stories.tsx +++ b/packages/twenty-front/src/loading/components/__stories__/PrefetchLoading.stories.tsx @@ -22,6 +22,7 @@ const meta: Meta = { msw: graphqlMocks, prefetchLoadingSetDelay: 1000, }, + tags: ['no-tests'], }; export default meta; diff --git a/packages/twenty-front/src/loading/components/__stories__/UserOrMetadataLoader.stories.tsx b/packages/twenty-front/src/loading/components/__stories__/UserOrMetadataLoader.stories.tsx index 69c240bdd5..48a605e5ca 100644 --- a/packages/twenty-front/src/loading/components/__stories__/UserOrMetadataLoader.stories.tsx +++ b/packages/twenty-front/src/loading/components/__stories__/UserOrMetadataLoader.stories.tsx @@ -1,6 +1,6 @@ import { getOperationName } from '@apollo/client/utilities'; -import { expect, within } from '@storybook/test'; import { type Meta, type StoryObj } from '@storybook/react'; +import { expect, within } from '@storybook/test'; import { HttpResponse, graphql, http } from 'msw'; import { GET_PUBLIC_WORKSPACE_DATA_BY_DOMAIN } from '@/auth/graphql/queries/getPublicWorkspaceDataByDomain'; @@ -70,6 +70,7 @@ const meta: Meta = { parameters: { msw: graphqlMocks, }, + tags: ['no-tests'], }; export default meta; diff --git a/packages/twenty-front/src/modules/object-record/record-group/hooks/useReorderRecordGroups.ts b/packages/twenty-front/src/modules/object-record/record-group/hooks/useReorderRecordGroups.ts index 024550d5a7..4ba9540b76 100644 --- a/packages/twenty-front/src/modules/object-record/record-group/hooks/useReorderRecordGroups.ts +++ b/packages/twenty-front/src/modules/object-record/record-group/hooks/useReorderRecordGroups.ts @@ -32,6 +32,7 @@ export const useReorderRecordGroups = ({ const visibleRecordGroupIdsFamilySelector = useRecoilComponentCallbackState( visibleRecordGroupIdsComponentFamilySelector, + viewBarId, ); const { saveViewGroups } = useSaveCurrentViewGroups(); diff --git a/packages/twenty-front/src/modules/settings/accounts/components/__stories__/SettingsAccountsCalendarChannelsGeneral.stories.tsx b/packages/twenty-front/src/modules/settings/accounts/components/__stories__/SettingsAccountsCalendarChannelsGeneral.stories.tsx index cde0c02cf7..c63ae04261 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/__stories__/SettingsAccountsCalendarChannelsGeneral.stories.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/__stories__/SettingsAccountsCalendarChannelsGeneral.stories.tsx @@ -1,9 +1,10 @@ import { type Meta, type StoryObj } from '@storybook/react'; import { SettingsAccountsCalendarChannelsGeneral } from '@/settings/accounts/components/SettingsAccountsCalendarChannelsGeneral'; +import { ComponentDecorator } from 'twenty-ui/testing'; +import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator'; import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator'; import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; -import { ComponentDecorator } from 'twenty-ui/testing'; const meta: Meta = { title: @@ -13,6 +14,7 @@ const meta: Meta = { ComponentDecorator, ObjectMetadataItemsDecorator, SnackBarDecorator, + I18nFrontDecorator, ], }; diff --git a/packages/twenty-front/vite.config.ts b/packages/twenty-front/vite.config.ts index d28bea9535..e486a70dee 100644 --- a/packages/twenty-front/vite.config.ts +++ b/packages/twenty-front/vite.config.ts @@ -9,8 +9,8 @@ import { visualizer } from 'rollup-plugin-visualizer'; import { defineConfig, loadEnv, - searchForWorkspaceRoot, type PluginOption, + searchForWorkspaceRoot, } from 'vite'; import checker from 'vite-plugin-checker'; import svgr from 'vite-plugin-svgr'; @@ -46,7 +46,7 @@ export default defineConfig(({ command, mode }) => { // Please don't increase this limit for main index chunk // If it gets too big then find modules in the code base // that can be loaded lazily, there are more! - const MAIN_CHUNK_SIZE_LIMIT = 4.7 * 1024 * 1024; // 4.7MB for main index chunk + const MAIN_CHUNK_SIZE_LIMIT = 4.8 * 1024 * 1024; // 4.7MB for main index chunk const OTHER_CHUNK_SIZE_LIMIT = 5 * 1024 * 1024; // 5MB for other chunks const checkers: Checkers = { @@ -119,44 +119,45 @@ export default defineConfig(({ command, mode }) => { configPath: path.resolve(__dirname, './lingui.config.ts'), }), checker(checkers), - // TODO: fix this, we have to restrict the include to only the components that are using linaria - // Otherwise the build will fail because wyw tries to include emotion styled components - wyw({ - include: [ - '**/CurrencyDisplay.tsx', - '**/EllipsisDisplay.tsx', - '**/ContactLink.tsx', - '**/BooleanDisplay.tsx', - '**/LinksDisplay.tsx', - '**/RoundedLink.tsx', - '**/OverflowingTextWithTooltip.tsx', - '**/Chip.tsx', - '**/Tag.tsx', - '**/MultiSelectFieldDisplay.tsx', - '**/RatingInput.tsx', - '**/RecordTableCellContainer.tsx', - '**/RecordTableCellDisplayContainer.tsx', - '**/Avatar.tsx', - '**/RecordTableBodyDroppable.tsx', - '**/RecordTableCellBaseContainer.tsx', - '**/RecordTableCellTd.tsx', - '**/RecordTableTd.tsx', - '**/RecordTableHeaderDragDropColumn.tsx', - '**/ActorDisplay.tsx', - '**/BooleanDisplay.tsx', - '**/CurrencyDisplay.tsx', - '**/TextDisplay.tsx', - '**/EllipsisDisplay.tsx', - '**/AvatarChip.tsx', - '**/URLDisplay.tsx', - '**/EmailsDisplay.tsx', - '**/PhonesDisplay.tsx', - '**/MultiSelectDisplay.tsx', - ], - babelOptions: { - presets: ['@babel/preset-typescript', '@babel/preset-react'], - }, - }), + { + ...wyw({ + include: [ + '**/CurrencyDisplay.tsx', + '**/EllipsisDisplay.tsx', + '**/ContactLink.tsx', + '**/BooleanDisplay.tsx', + '**/LinksDisplay.tsx', + '**/RoundedLink.tsx', + '**/OverflowingTextWithTooltip.tsx', + '**/Chip.tsx', + '**/Tag.tsx', + '**/MultiSelectFieldDisplay.tsx', + '**/RatingInput.tsx', + '**/RecordTableCellContainer.tsx', + '**/RecordTableCellDisplayContainer.tsx', + '**/Avatar.tsx', + '**/RecordTableBodyDroppable.tsx', + '**/RecordTableCellBaseContainer.tsx', + '**/RecordTableCellTd.tsx', + '**/RecordTableTd.tsx', + '**/RecordTableHeaderDragDropColumn.tsx', + '**/ActorDisplay.tsx', + '**/BooleanDisplay.tsx', + '**/CurrencyDisplay.tsx', + '**/TextDisplay.tsx', + '**/EllipsisDisplay.tsx', + '**/AvatarChip.tsx', + '**/URLDisplay.tsx', + '**/EmailsDisplay.tsx', + '**/PhonesDisplay.tsx', + '**/MultiSelectDisplay.tsx', + ], + babelOptions: { + presets: ['@babel/preset-typescript', '@babel/preset-react'], + }, + }), + enforce: 'pre', + }, visualizer({ open: true, gzipSize: true, diff --git a/packages/twenty-ui/__mocks__/imageMock.js b/packages/twenty-shared/__mocks__/imageMockShared.js similarity index 100% rename from packages/twenty-ui/__mocks__/imageMock.js rename to packages/twenty-shared/__mocks__/imageMockShared.js diff --git a/packages/twenty-shared/jest.config.mjs b/packages/twenty-shared/jest.config.mjs index 52a03ef33b..377358c2c4 100644 --- a/packages/twenty-shared/jest.config.mjs +++ b/packages/twenty-shared/jest.config.mjs @@ -27,7 +27,7 @@ const jestConfig = { */ '/^@/(.*)$/': './src/$1', '\\.(jpg|jpeg|png|gif|webp|svg|svg\\?react)$': - '/__mocks__/imageMock.js', + '/__mocks__/imageMockShared.js', }, moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], extensionsToTreatAsEsm: ['.ts', '.tsx'], diff --git a/packages/twenty-shared/vite.config.ts b/packages/twenty-shared/vite.config.ts index 497de8bd19..8be82b25ac 100644 --- a/packages/twenty-shared/vite.config.ts +++ b/packages/twenty-shared/vite.config.ts @@ -58,6 +58,7 @@ export default defineConfig(() => { ], }, }, + logLevel: 'warn' }; }); diff --git a/packages/twenty-ui/.storybook/test-runner-jest.config.js b/packages/twenty-ui/.storybook/test-runner-jest.config.js new file mode 100644 index 0000000000..3169654645 --- /dev/null +++ b/packages/twenty-ui/.storybook/test-runner-jest.config.js @@ -0,0 +1,21 @@ +import { getJestConfig } from '@storybook/test-runner'; + +const MINUTES_IN_MS = 60 * 1000; + +/** + * @type {import('@jest/types').Config.InitialOptions} + */ +export default { + // The default configuration comes from @storybook/test-runner + ...getJestConfig(), + /** Add your own overrides below + * @see https://jestjs.io/docs/configuration + */ + testTimeout: 5 * MINUTES_IN_MS, + modulePathIgnorePatterns: [ + '/.nx/cache/*', + '/packages/twenty-server/dist/*', + '/packages/twenty-front/dist/*', + '/packages/twenty-ui/dist/*', + ], +}; diff --git a/packages/twenty-ui/__mocks__/imageMockUi.js b/packages/twenty-ui/__mocks__/imageMockUi.js new file mode 100644 index 0000000000..602eb23ee2 --- /dev/null +++ b/packages/twenty-ui/__mocks__/imageMockUi.js @@ -0,0 +1 @@ +export default 'test-file-stub'; diff --git a/packages/twenty-ui/jest.config.mjs b/packages/twenty-ui/jest.config.mjs index 12170ef44c..3b28a111cd 100644 --- a/packages/twenty-ui/jest.config.mjs +++ b/packages/twenty-ui/jest.config.mjs @@ -27,7 +27,7 @@ const jestConfig = { ], }, moduleNameMapper: { - '\\.(jpg|jpeg|png|gif|webp|svg|svg)$': '/__mocks__/imageMock.js', + '\\.(jpg|jpeg|png|gif|webp|svg|svg)$': '/__mocks__/imageMockUi.js', ...pathsToModuleNameMapper(tsConfig.compilerOptions.paths, { prefix: '/', }), diff --git a/packages/twenty-ui/package.json b/packages/twenty-ui/package.json index d36989f015..9a0cad138d 100644 --- a/packages/twenty-ui/package.json +++ b/packages/twenty-ui/package.json @@ -46,6 +46,7 @@ }, "files": [ "dist", + "assets", "accessibility", "assets", "components", diff --git a/packages/twenty-ui/src/components/avatar-chip/__stories__/AvatarChip.stories.tsx b/packages/twenty-ui/src/components/avatar-chip/__stories__/AvatarChip.stories.tsx index b2db483149..dfbadbac94 100644 --- a/packages/twenty-ui/src/components/avatar-chip/__stories__/AvatarChip.stories.tsx +++ b/packages/twenty-ui/src/components/avatar-chip/__stories__/AvatarChip.stories.tsx @@ -1,12 +1,12 @@ import { type Meta, type StoryObj } from '@storybook/react'; -import { ComponentDecorator } from '@ui/testing'; import { IconBuildingSkyscraper, IconUser } from '@ui/display'; +import { ComponentDecorator, RecoilRootDecorator } from '@ui/testing'; import { AvatarChip } from '../AvatarChip'; const meta: Meta = { title: 'UI/Components/AvatarChip', component: AvatarChip, - decorators: [ComponentDecorator], + decorators: [ComponentDecorator, RecoilRootDecorator], }; export default meta; diff --git a/packages/twenty-ui/src/json-visualizer/__stories__/JsonTree.stories.tsx b/packages/twenty-ui/src/json-visualizer/__stories__/JsonTree.stories.tsx index 76241cc892..4266e4ee2c 100644 --- a/packages/twenty-ui/src/json-visualizer/__stories__/JsonTree.stories.tsx +++ b/packages/twenty-ui/src/json-visualizer/__stories__/JsonTree.stories.tsx @@ -107,7 +107,7 @@ export const ArraySimple: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const node = await canvas.findByText('[3]'); + const node = await canvas.findByText('3'); expect(node).toBeVisible(); }, diff --git a/packages/twenty-ui/vite.config.ts b/packages/twenty-ui/vite.config.ts index a9dec809c2..f97b861472 100644 --- a/packages/twenty-ui/vite.config.ts +++ b/packages/twenty-ui/vite.config.ts @@ -95,7 +95,6 @@ export default defineConfig(({ command }) => { }, }), ], - // Configuration for building your library. // See: https://vitejs.dev/guide/build.html#library-mode build: { @@ -142,5 +141,6 @@ export default defineConfig(({ command }) => { ], }, }, + logLevel: 'error', }; });