From 06f8166969bbbde17373e5f10d77a832f37580b2 Mon Sep 17 00:00:00 2001 From: Richard Race <1273965+richrace@users.noreply.github.com> Date: Thu, 5 Sep 2024 14:15:30 +0100 Subject: [PATCH] Speed up tests (#721) * Use @swc/jest to speed up tests * Add 'workerThreads=true' to try to speed up tests * Use concurrency for unit tests; add a dev task for unit tests to runInBand * Upgrade node orb * Use cache on CircleCI * Use default cache location * Try to use cache * Try a different approach to cache node modules * Fix user being generated with incorrect values (creating notes) --- .circleci/config.yml | 27 ++-- .dockerignore | 3 + .gitignore | 5 +- .swcrc | 17 +++ cypress/e2e/case-list/index.cy.ts | 8 +- jest.config.js | 4 + package-lock.json | 244 ++++++++++++++++++++++++++++++ package.json | 11 +- 8 files changed, 304 insertions(+), 15 deletions(-) create mode 100644 .swcrc diff --git a/.circleci/config.yml b/.circleci/config.yml index b30e64727..eb1461673 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ version: 2.1 orbs: - node: circleci/node@5.2.0 + node: circleci/node@6.1.0 commands: ################### Helpers @@ -11,12 +11,24 @@ commands: name: Clone bichard7-next-core command: git clone --depth 1 https://github.com/ministryofjustice/bichard7-next-core.git ~/bichard7-next-core + install_npm_packages: + steps: + - restore_cache: + name: Load node_modules from the cache if they haven't changed + keys: + - v1-npm-deps-{{ .Branch }}-{{ checksum "package-lock.json" }} + - v1-npm-deps- + - run: + name: Install npm dependencies + command: npm i + - save_cache: + key: v1-npm-deps-{{ .Branch }}-{{ checksum "package-lock.json" }} + paths: node_modules setup: steps: - checkout - node_install - - node/install-packages: - include-branch-in-cache-key: true + - install_npm_packages - checkout_core - run: name: Set GB locale @@ -178,8 +190,7 @@ jobs: steps: - checkout - node_install - - node/install-packages: - include-branch-in-cache-key: true + - install_npm_packages - run: name: Check the code for linting errors command: npm run lint @@ -191,8 +202,7 @@ jobs: steps: - checkout - node_install - - node/install-packages: - include-branch-in-cache-key: true + - install_npm_packages - run: name: Run code-based unit tests command: npm run test:unit @@ -245,8 +255,7 @@ jobs: - checkout_core - install_ms_edge - node_install - - node/install-packages: - include-branch-in-cache-key: true + - install_npm_packages - run: name: Install Cypress command: ./.circleci/scripts/install-cypress.sh 2>&1 diff --git a/.dockerignore b/.dockerignore index 52d23f2ed..2c9e41d26 100644 --- a/.dockerignore +++ b/.dockerignore @@ -106,3 +106,6 @@ dist # Cypress artifacts cypress/videos cypress/screenshots + +# SWC cache +.swc/ diff --git a/.gitignore b/.gitignore index e131abad6..d97108866 100644 --- a/.gitignore +++ b/.gitignore @@ -133,4 +133,7 @@ public/images/govuk-mask-icon.svg public/images/govuk-opengraph-image.png # Ignore auto-generated zap.yaml -scripts/zap/zap.yaml \ No newline at end of file +scripts/zap/zap.yaml + +# SWC cache +.swc/ diff --git a/.swcrc b/.swcrc new file mode 100644 index 000000000..cdd204624 --- /dev/null +++ b/.swcrc @@ -0,0 +1,17 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript", + "tsx": false, + "decorators": true + }, + "transform": { + "legacyDecorator": true, + "decoratorMetadata": true + }, + "target": "esnext" + }, + "module": { + "type": "commonjs" + } +} diff --git a/cypress/e2e/case-list/index.cy.ts b/cypress/e2e/case-list/index.cy.ts index 9ec40d9c5..87e728585 100644 --- a/cypress/e2e/case-list/index.cy.ts +++ b/cypress/e2e/case-list/index.cy.ts @@ -32,7 +32,13 @@ describe("Case list", () => { }) it("Should display 0 cases when there are no cases 'locked to me' and hide the bottom pagination bar ", () => { - const lockUsernames = ["BichardForce02", "BichardForce03", null, "A really really really long.name"] + const lockUsernames = [ + "BichardForce01", + "BichardForce02", + "BichardForce03", + null, + "A really really really long.name" + ] cy.task( "insertCourtCasesWithFields", lockUsernames.map((username) => ({ diff --git a/jest.config.js b/jest.config.js index a75066432..9d47ae040 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,5 @@ /** @type {import('ts-jest').JestConfigWithTsJest} */ + module.exports = { preset: "ts-jest", setupFilesAfterEnv: ["/setupTests.ts"], @@ -11,5 +12,8 @@ module.exports = { "^entities/(.*)$": "/src/entities/$1", "^services/(.*)$": "/src/services/$1", "^middleware/(.*)$": "/src/middleware/$1" + }, + transform: { + "^.+\\.(t|j)sx?$": "@swc/jest" } } diff --git a/package-lock.json b/package-lock.json index f52d30640..9fe8b78e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,6 +52,8 @@ "@next/eslint-plugin-next": "^14.2.7", "@stdlib/random-base-exponential": "^0.2.1", "@stdlib/random-sample": "^0.2.1", + "@swc/core": "^1.7.23", + "@swc/jest": "^0.2.36", "@testing-library/cypress": "^10.0.2", "@testing-library/jest-dom": "^6.5.0", "@types/cookie-signature": "^1.1.2", @@ -2437,6 +2439,18 @@ "node": ">=8" } }, + "node_modules/@jest/create-cache-key-function": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", + "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@jest/environment": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", @@ -9815,6 +9829,204 @@ "url": "https://opencollective.com/stdlib" } }, + "node_modules/@swc/core": { + "version": "1.7.23", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.23.tgz", + "integrity": "sha512-VDNkpDvDlreGh2E3tlDj8B3piiuLhhQA/7rIVZpiLUvG1YpucAa6N7iDXA7Gc/+Hah8spaCg/qvEaBkCmcIYCQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.12" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.7.23", + "@swc/core-darwin-x64": "1.7.23", + "@swc/core-linux-arm-gnueabihf": "1.7.23", + "@swc/core-linux-arm64-gnu": "1.7.23", + "@swc/core-linux-arm64-musl": "1.7.23", + "@swc/core-linux-x64-gnu": "1.7.23", + "@swc/core-linux-x64-musl": "1.7.23", + "@swc/core-win32-arm64-msvc": "1.7.23", + "@swc/core-win32-ia32-msvc": "1.7.23", + "@swc/core-win32-x64-msvc": "1.7.23" + }, + "peerDependencies": { + "@swc/helpers": "*" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.7.23", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.23.tgz", + "integrity": "sha512-yyOHPfti6yKlQulfVWMt7BVKst+SyEZYCWuQSGMn1KgmNCH/bYufRWfQXIhkGSj44ZkEepJmsJ8tDyIb4k5WyA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.7.23", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.23.tgz", + "integrity": "sha512-GzqHwQ0Y1VyjdI/bBKFX2GKm5HD3PIB6OhuAQtWZMTtEr2yIrlT0YK2T+XKh7oIg31JwxGBeQdBk3KTI7DARmQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.7.23", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.23.tgz", + "integrity": "sha512-qwX4gB41OS6/OZkHcpTqLFGsdmvoZyffnJIlgB/kZKwH3lfeJWzv6vx57zXtNpM/t7GoQEe0VZUVdmNjxSxBZw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.7.23", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.23.tgz", + "integrity": "sha512-TsrbUZdMaUwzI7+g/8rHPLWbntMKYSu5Bn5IBSqVKPeyqaXxNnlIUnWXgXcUcRAc+T+Y8ADfr7EiFz9iz5DuSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.7.23", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.23.tgz", + "integrity": "sha512-JEdtwdthazKq4PBz53KSubwwK8MvqODAihGSAzc8u3Unq4ojcvaS8b0CwLBeD+kTQ78HpxOXTt3DsFIxpgaCAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.7.23", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.23.tgz", + "integrity": "sha512-V51gFPWaVAHbI1yg9ahsoya3aB4uawye3SZ5uQWgcP7wdCdiv60dw4F5nuPJf5Z1oXD3U/BslXuamv8Oh9vXqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.7.23", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.23.tgz", + "integrity": "sha512-BBqQi4+UdeRqag3yM4IJjaHG4yc1o3l9ksENHToE0o/u2DT0FY5+K/DiYGZLC1JHbSFzNqRCYsa7DIzRtZ0A1A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.7.23", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.23.tgz", + "integrity": "sha512-JPk6pvCKncL6bXG7p+NLZf8PWx4FakVvKNdwGeMrYunb+yk1IZf7qf9LJk8+GDGF5QviDXPs8opZrTrfsW80fA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.7.23", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.23.tgz", + "integrity": "sha512-2Whxi8d+bLQBzJcQ5qYPHlk02YYVGsMVav0fWk+FnX2z1QRREIu1L1xvrpi7gBpjXp6BIU40ya8GiKeekNT2bg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.7.23", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.23.tgz", + "integrity": "sha512-82fARk4/yJ40kwWKY/gdKDisPdtgJE9jgpl/vkNG3alyJxrCzuNM7+CtiKoYbXLeqM8GQTS3wlvCaJu9oQ8dag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, "node_modules/@swc/counter": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", @@ -9831,6 +10043,32 @@ "tslib": "^2.4.0" } }, + "node_modules/@swc/jest": { + "version": "0.2.36", + "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.36.tgz", + "integrity": "sha512-8X80dp81ugxs4a11z1ka43FPhP+/e+mJNXJSxiNYk8gIX/jPBtY4gQTrKu/KIoco8bzKuPI5lUxjfLiGsfvnlw==", + "dev": true, + "dependencies": { + "@jest/create-cache-key-function": "^29.7.0", + "@swc/counter": "^0.1.3", + "jsonc-parser": "^3.2.0" + }, + "engines": { + "npm": ">= 7.0.0" + }, + "peerDependencies": { + "@swc/core": "*" + } + }, + "node_modules/@swc/types": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.12.tgz", + "integrity": "sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==", + "dev": true, + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, "node_modules/@testing-library/cypress": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/@testing-library/cypress/-/cypress-10.0.2.tgz", @@ -20694,6 +20932,12 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", diff --git a/package.json b/package.json index 6e85a6cb0..c11e2a694 100644 --- a/package.json +++ b/package.json @@ -19,11 +19,12 @@ "cypress:run:file": "cypress run --spec", "cypress:run:docker:file": "cypress run --config baseUrl='https://localhost:4443' --spec", "test": "npm run test:unit && npm run test:integration && npm run test:ui:e2e", - "test:unit": "jest --testPathIgnorePatterns=\"integration\" \"e2e\" --runInBand", + "test:unit": "jest --testPathIgnorePatterns=\"integration\" \"e2e\" --maxWorkers=80%", + "test:unit:dev": "jest --testPathIgnorePatterns=\"integration\" \"e2e\" --runInBand --workerThreads=true", "test:unit:update": "npm run test:unit -- -u", - "test:integration": "jest --testPathPattern=\"integration\" --runInBand --testNamePattern=", + "test:integration": "jest --testPathPattern=\"integration\" --runInBand --workerThreads=true --testNamePattern=", "test:integration:update": "npm run test:integration -- -u", - "test:file": "jest --runInBand --testPathPattern", + "test:file": "jest --runInBand --testPathPattern --workerThreads=true", "test:ui:e2e": "concurrently --kill-others --success first \"npm run start\" \"npm run cypress:run\"", "install:hooks": "./scripts/install-git-hooks.sh", "update-deps": "ncu -u && npm install", @@ -32,8 +33,8 @@ "zap": "./scripts/zap/zap-scan.sh" }, "dependencies": { - "@govuk-react/table": "^0.10.7", "@govuk-react/select": "^0.10.7", + "@govuk-react/table": "^0.10.7", "@ministryofjustice/frontend": "^2.2.0", "@moj-bichard7-developers/bichard7-next-core": "^2.0.9", "@moj-bichard7-developers/bichard7-next-data": "^2.0.205", @@ -76,6 +77,8 @@ "@next/eslint-plugin-next": "^14.2.7", "@stdlib/random-base-exponential": "^0.2.1", "@stdlib/random-sample": "^0.2.1", + "@swc/core": "^1.7.23", + "@swc/jest": "^0.2.36", "@testing-library/cypress": "^10.0.2", "@testing-library/jest-dom": "^6.5.0", "@types/cookie-signature": "^1.1.2",