diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4a2cc5882..1ba59d5b7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,6 +41,25 @@ jobs: exit 1 fi + test-node: + name: Node Unit Tests + runs-on: ubuntu-latest + steps: + - name: Checkout Branch + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version-file: "package.json" + cache: "npm" + + - name: Install Node Packages + run: npm ci + + - name: Run Node Unit Tests + run: npm test + build: name: Build runs-on: macos-latest diff --git a/Testing.md b/Testing.md index 684260b1c..20685a7b1 100644 --- a/Testing.md +++ b/Testing.md @@ -8,7 +8,17 @@ Tests are located in the `/tests` folder. ## Local Testing -To run this locally you'll need the browsers installed along with the corresponding driver: +### Local Node.js Unit Testing + +You can run the unit tests directly in Node.js using: + +```bash +npm run test:node +``` + +### In-Browser Testing + +To run the in-browser tests locally, you'll need the browsers installed along with the corresponding driver: - [chromedriver](https://chromedriver.chromium.org/getting-started) - [geckodriver](https://github.com/mozilla/geckodriver/releases) diff --git a/package.json b/package.json index f0884b94b..94b1f7a39 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "license": "SEE LICENSE IN LICENSE", "scripts": { "dev": "node tests/server.mjs", - "lint:check": "eslint **/*.{js,mjs,jsx,ts,tsx}", + "lint:check": "eslint \"**/*.{js,mjs,jsx,ts,tsx}\"", "lint:fix": "eslint \"**/*.{js,mjs,jsx,ts,tsx}\" --fix", "pretty:check": "prettier --check ./", "pretty:fix": "prettier --write ./", @@ -29,7 +29,9 @@ "test-e2e:chrome": "node tests/run-end2end.mjs --browser chrome", "test-e2e:firefox": "node tests/run-end2end.mjs --browser firefox", "test-e2e:safari": "node tests/run-end2end.mjs --browser safari", - "test-e2e:edge": "node tests/run-end2end.mjs --browser edge" + "test-e2e:edge": "node tests/run-end2end.mjs --browser edge", + "test": "npm run test:node", + "test:node": "mocha --require ./tests/setup-node.mjs \"tests/unittests/*.mjs\"" }, "devDependencies": { "@babel/core": "^7.21.3", diff --git a/resources/shared/helpers.mjs b/resources/shared/helpers.mjs index b6b004542..9c8df3c5b 100644 --- a/resources/shared/helpers.mjs +++ b/resources/shared/helpers.mjs @@ -53,3 +53,9 @@ export function forceLayout(body, layoutMode = "getBoundingRectAndElementFromPoi throw Error(`Invalid layoutMode: ${layoutMode}`); } } + +export function skipInShell(context) { + if (typeof window === "undefined" || typeof document === "undefined") + // Skip in non-browser environments + context.skip(); +} diff --git a/tests/setup-node.mjs b/tests/setup-node.mjs new file mode 100644 index 000000000..35dae8cbf --- /dev/null +++ b/tests/setup-node.mjs @@ -0,0 +1,11 @@ +import expect from "expect.js"; +import sinon from "sinon"; + +globalThis.expect = expect; +globalThis.sinon = sinon; + +export const mochaHooks = { + afterEach() { + sinon.restore(); + }, +}; diff --git a/tests/unittests/benchmark-runner.mjs b/tests/unittests/benchmark-runner.mjs index 928ab8452..b512c799d 100644 --- a/tests/unittests/benchmark-runner.mjs +++ b/tests/unittests/benchmark-runner.mjs @@ -2,6 +2,7 @@ import { BenchmarkRunner } from "../../resources/benchmark-runner.mjs"; import { SuiteRunner } from "../../resources/suite-runner.mjs"; import { StepRunner } from "../../resources/shared/step-runner.mjs"; import { defaultParams } from "../../resources/shared/params.mjs"; +import { skipInShell } from "../../resources/shared/helpers.mjs"; function TEST_FIXTURE(name) { return { @@ -35,7 +36,8 @@ describe("BenchmarkRunner", () => { const { spy, stub, assert } = sinon; let runner; - before(() => { + before(function () { + skipInShell(this); runner = new BenchmarkRunner(SUITES_FIXTURE, CLIENT_FIXTURE); });