name: Reusable Tests permissions: contents: read on: workflow_call: # This workflow can be called by other workflows inputs: node-version: required: false type: string description: "Specific Node.js version for single test" default: "" use-matrix: required: false type: boolean description: "Whether to run tests on multiple Node.js versions" default: false jobs: # This job is used to cache node_modules and build output # 1. Install latest dependencies # 2. Cache node_modules # 3. Build package # 4. Cache build output install-and-build: if: ${{ inputs.use-matrix == true }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false - name: Use Node.js ${{ vars.DEFAULT_NODE_VERSION }} uses: actions/setup-node@v6 with: node-version: ${{ vars.DEFAULT_NODE_VERSION }} cache: "npm" cache-dependency-path: "**/package-lock.json" - name: Try to restore modern node_modules cache id: node_modules_cache uses: actions/cache@v6 with: path: node_modules key: ${{ runner.os }}-modern-node-modules-${{ hashFiles('**/package-lock.json') }} - name: Install dependencies if: steps.node_modules_cache.outputs.cache-hit != 'true' run: npm ci - name: Check if artifact exists id: check_node_modules_artifact run: | ARTIFACT_NAME="modern-node-modules-${{ hashFiles('**/package-lock.json') }}" ARTIFACT_EXISTS=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ "https://api.github.com/repos/${{ github.repository }}/actions/artifacts" | \ jq --arg name "$ARTIFACT_NAME" '.artifacts[] | select(.name == $name) | .id' | wc -l) echo "artifact_exists=$ARTIFACT_EXISTS" >> $GITHUB_ENV if [ "$ARTIFACT_EXISTS" -gt "0" ]; then echo "artifact_exists=true" >> $GITHUB_OUTPUT else echo "artifact_exists=false" >> $GITHUB_OUTPUT fi - name: Upload node_modules to artifacts if: steps.check_node_modules_artifact.outputs.artifact_exists == 'false' uses: actions/upload-artifact@v6 with: name: modern-node-modules-${{ hashFiles('**/package-lock.json') }} path: node_modules - name: Build package run: npm run build - name: Cache modern package build output uses: actions/cache@v6 with: path: | tslib tses lib es es-legacy umd key: ${{ runner.os }}-modern-build-output-${{ github.sha }} - name: Upload build output to artifacts uses: actions/upload-artifact@v6 with: name: ${{ runner.os }}-modern-build-output-${{ github.sha }} path: | tslib tses lib es es-legacy umd node-modules-legacy-cache: if: ${{ inputs.use-matrix == true }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false - name: Use Node.js ${{ vars.DEFAULT_NODE_VERSION }} uses: actions/setup-node@v6 with: node-version: ${{ vars.DEFAULT_NODE_VERSION }} - name: Try to restore legacy node_modules cache id: node_modules_cache uses: actions/cache@v6 with: path: node_modules key: ${{ runner.os }}-legacy-node-modules-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/package-legacy-node.json') }} - name: Downgrade package.json legacy dependencies if: steps.node_modules_cache.outputs.cache-hit != 'true' run: npm run legacy-package - name: Install dependencies if: steps.node_modules_cache.outputs.cache-hit != 'true' run: npm install --legacy-peer-deps --ignore-scripts --no-package-lock # Run ts-tests on default Node.js version run-node-test: if: ${{ inputs.use-matrix == true }} runs-on: ubuntu-latest needs: install-and-build steps: - uses: actions/checkout@v6 with: persist-credentials: false - name: Use Node.js ${{ vars.DEFAULT_NODE_VERSION }} uses: actions/setup-node@v6 with: node-version: ${{ vars.DEFAULT_NODE_VERSION }} - name: Restore modern node_modules cache uses: actions/cache@v6 with: path: | node_modules key: ${{ runner.os }}-modern-node-modules-${{ hashFiles('**/package-lock.json') }} - name: Run unit tests from source codes run: npm test # Run Node.js CJS unit tests on multiple modern node versions run-jest-tests: if: ${{ inputs.use-matrix == true }} runs-on: ubuntu-latest needs: install-and-build strategy: matrix: node-version: [ 14.x, 15.x, 16.x, 17.x, 18.x, 19.x, 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x, ] steps: - uses: actions/checkout@v6 with: persist-credentials: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} - name: Restore modern node_modules cache uses: actions/cache@v6 with: path: | node_modules key: ${{ runner.os }}-modern-node-modules-${{ hashFiles('**/package-lock.json') }} - name: Restore modern build output cache uses: actions/cache@v6 with: path: | tslib tses lib es es-legacy umd key: ${{ runner.os }}-modern-build-output-${{ github.sha }} - name: Run unit tests for CJS modules run: npm run test:jest-cjs # Run CJS unit tests on multiple legacy node versions run-legacy-jest-tests: if: ${{ inputs.use-matrix == true }} runs-on: ubuntu-latest needs: [install-and-build, node-modules-legacy-cache] strategy: matrix: node-version: [7.x, 8.x, 9.x, 10.x, 11.x, 12.x, 13.x] steps: - uses: actions/checkout@v6 with: persist-credentials: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} - name: Restore legacy node_modules cache uses: actions/cache@v6 with: path: | node_modules key: ${{ runner.os }}-legacy-node-modules-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/package-legacy-node.json') }} - name: Restore modern build output cache uses: actions/cache@v6 with: path: | tslib tses lib es es-legacy umd key: ${{ runner.os }}-modern-build-output-${{ github.sha }} - name: Run unit tests for legacy CJS modules run: npm run test:jest-cjs # Run ESM unit tests on node versions that support Node.js ESM run-esm-tests: if: ${{ inputs.use-matrix == true }} runs-on: ubuntu-latest needs: install-and-build strategy: matrix: node-version: [16.x, 17.x, 18.x, 19.x, 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x] steps: - uses: actions/checkout@v6 with: persist-credentials: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} - name: Restore modern node_modules cache uses: actions/cache@v6 with: path: | node_modules key: ${{ runner.os }}-modern-node-modules-${{ hashFiles('**/package-lock.json') }} - name: Restore modern build output cache uses: actions/cache@v6 with: path: | tslib tses lib es es-legacy umd key: ${{ runner.os }}-modern-build-output-${{ github.sha }} - name: Run unit tests for ESM modules run: npm run test:jest-esm # Run esm-legacy unit tests on node versions that support Node.js ESM run-esm-legacy-node-tests: if: ${{ inputs.use-matrix == true }} runs-on: ubuntu-latest needs: install-and-build strategy: matrix: node-version: [16.x, 17.x, 18.x, 19.x, 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x] steps: - uses: actions/checkout@v6 with: persist-credentials: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} - name: Restore modern node_modules cache uses: actions/cache@v6 with: path: | node_modules key: ${{ runner.os }}-modern-node-modules-${{ hashFiles('**/package-lock.json') }} - name: Restore modern build output cache uses: actions/cache@v6 with: path: | tslib tses lib es es-legacy umd key: ${{ runner.os }}-modern-build-output-${{ github.sha }} - name: Run unit tests for esm-legacy modules run: npm run test:jest-legacy run-e2e-tests: if: ${{ inputs.use-matrix == true }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false - name: Use Node.js ${{ vars.DEFAULT_NODE_VERSION }} uses: actions/setup-node@v6 with: node-version: ${{ vars.DEFAULT_NODE_VERSION }} cache: "npm" - name: Install Playwright dependencies run: npx playwright install-deps webkit - name: Restore modern node_modules cache id: node_modules_cache uses: actions/cache@v6 with: path: | node_modules key: ${{ runner.os }}-modern-node-modules-${{ hashFiles('**/package-lock.json') }} - name: Install dependencies if: steps.node_modules_cache.outputs.cache-hit != 'true' run: npm ci - name: Install playwright browsers run: npx playwright install - name: Download build output from artifacts id: download_build_output uses: actions/download-artifact@v6 continue-on-error: true with: name: ${{ runner.os }}-modern-build-output-${{ github.sha }} - name: Build package if: steps.download_build_output.outcome != 'success' run: npm run build - name: Run browser tests run: npm run e2e # Run tests on single specified Node.js version run-test-single: if: ${{ inputs.use-matrix == false }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false - name: Use Node.js ${{ inputs.node-version }} uses: actions/setup-node@v6 with: node-version: ${{ inputs.node-version || vars.DEFAULT_NODE_VERSION }} - name: Try to restore modern node_modules cache id: node_modules_cache uses: actions/cache@v6 with: path: node_modules key: ${{ runner.os }}-modern-node-modules-${{ hashFiles('**/package-lock.json') }} - name: Install dependencies if: steps.node_modules_cache.outputs.cache-hit != 'true' run: npm ci - name: Run unit tests from source codes run: npm test