diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 00000000..375d6b6c --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,38 @@ +name: Test end-to-end + +on: + push: + branches: [ "main" ] + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + +# Declare default permissions as read only. +permissions: read-all + +env: + API_KEY: ${{ secrets.E2E_API_KEY }} + API_SECRET: ${{ secrets.E2E_API_SECRET }} + DEFENDER_API_URL: $E2E_DEFENDER_API_URL + DEFENDER_POOL_ID: $E2E_DEFENDER_POOL_ID + DEFENDER_POOL_CLIENT_ID: $E2E_DEFENDER_POOL_CLIENT_ID + +jobs: + build-test: + name: Run build & e2e test + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.5.4 + + - name: Prepare pre-requisites + uses: ./.github/actions/prepare + + - name: Build + run: | + pnpm nx-build-skip-cache + + - name: Test end-to-end + run: | + pnpm test:e2e diff --git a/e2e/.env.example b/e2e/.env.example new file mode 100644 index 00000000..6ceaed06 --- /dev/null +++ b/e2e/.env.example @@ -0,0 +1,7 @@ +API_KEY= +API_SECRET= + +# OPTIONAL FOR LOWER ENVIRONMENTS +DEFENDER_API_URL= +DEFENDER_POOL_ID= +DEFENDER_POOL_CLIENT_ID= diff --git a/e2e/jest.config.js b/e2e/jest.config.js new file mode 100644 index 00000000..0b889af9 --- /dev/null +++ b/e2e/jest.config.js @@ -0,0 +1,5 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/src/**/*.test.ts'], +}; diff --git a/e2e/package.json b/e2e/package.json new file mode 100644 index 00000000..c3725569 --- /dev/null +++ b/e2e/package.json @@ -0,0 +1,23 @@ +{ + "name": "e2e", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "jest", + "test:watch": "jest --watch" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@types/jest": "^29.5.12", + "axios": "^1.7.2", + "jest": "^29.7.0", + "ts-jest": "^29.1.2" + }, + "dependencies": { + "@openzeppelin/defender-sdk": "workspace:^", + "dotenv": "^16.4.5" + } +} diff --git a/e2e/project.json b/e2e/project.json new file mode 100644 index 00000000..d1723e1f --- /dev/null +++ b/e2e/project.json @@ -0,0 +1,15 @@ +{ + "name": "e2e", + "root": "e2e", + "sourceRoot": "e2e/src", + "projectType": "application", + "targets": { + "test": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm test", + "cwd": "e2e" + } + } + } +} diff --git a/e2e/src/actions.test.ts b/e2e/src/actions.test.ts new file mode 100644 index 00000000..07c0bb62 --- /dev/null +++ b/e2e/src/actions.test.ts @@ -0,0 +1,17 @@ +require('dotenv').config(); +import { Defender } from '@openzeppelin/defender-sdk'; + +// Default timeout is not enough, using 15s timeout instead. +jest.setTimeout(15 * 1000); + +describe('actions', () => { + const actionClient = new Defender({ + apiKey: process.env.API_KEY, + apiSecret: process.env.API_SECRET, + }).action; + + it('should list actions', async () => { + const result = await actionClient.list(); + expect(result.items).toBeDefined(); + }); +}); diff --git a/package.json b/package.json index f9a65a28..52d45860 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "lint:fix": "pnpm prettier:fix && pnpm lint:check && pnpm prettier:check", "prettier:check": "prettier -u --check '**/*.{js,ts,tsx,md}' '!**/.nx/**'", "prettier:fix": "prettier -u --write '**/*.{js,ts,tsx,md}' '!**/.nx/**'", - "test": "nx run-many -t test --parallel=1", + "test": "nx run-many -t test --exclude=e2e --parallel=1", + "test:e2e": "nx run e2e:test", "build:changed": "nx affected:build --base=origin/main --skip-nx-cache --parallel=1", "test:changed": "nx affected:test --base=origin/main --skip-nx-cache --parallel=1", "style": "pnpm lint:fix", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b815323f..3a6e7bae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -82,6 +82,28 @@ importers: specifier: ^4.9.3 version: 4.9.5 + e2e: + dependencies: + '@openzeppelin/defender-sdk': + specifier: workspace:^ + version: link:../packages/defender-sdk + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + devDependencies: + '@types/jest': + specifier: ^29.5.12 + version: 29.5.12 + axios: + specifier: ^1.7.2 + version: 1.7.2 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@20.12.13) + ts-jest: + specifier: ^29.1.2 + version: 29.1.2(@babel/core@7.22.8)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.22.8))(jest@29.7.0(@types/node@20.12.13))(typescript@5.4.5) + examples/create-action: dependencies: '@openzeppelin/defender-sdk': @@ -219,7 +241,7 @@ importers: version: 16.4.5 ethers: specifier: ^5.6.1 - version: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + version: 5.7.2 examples/ethers-signer-v6: dependencies: @@ -1164,6 +1186,7 @@ packages: '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} @@ -1171,6 +1194,7 @@ packages: '@humanwhocodes/object-schema@2.0.2': resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + deprecated: Use @eslint/object-schema instead '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} @@ -1201,10 +1225,6 @@ packages: resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jest/expect-utils@29.6.4': - resolution: {integrity: sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jest/expect-utils@29.7.0': resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2662,10 +2682,6 @@ packages: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} - expect@29.6.4: - resolution: {integrity: sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3205,10 +3221,6 @@ packages: ts-node: optional: true - jest-diff@29.6.4: - resolution: {integrity: sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-diff@29.7.0: resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3237,18 +3249,10 @@ packages: resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-matcher-utils@29.6.4: - resolution: {integrity: sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-matcher-utils@29.7.0: resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-message-util@29.6.3: - resolution: {integrity: sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-message-util@29.7.0: resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3869,10 +3873,6 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - pretty-format@29.6.3: - resolution: {integrity: sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4025,6 +4025,7 @@ packages: rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true ripemd160@2.0.2: @@ -5896,10 +5897,6 @@ snapshots: '@types/node': 20.12.13 jest-mock: 29.7.0 - '@jest/expect-utils@29.6.4': - dependencies: - jest-get-type: 29.6.3 - '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 @@ -6612,8 +6609,8 @@ snapshots: '@types/jest@29.5.12': dependencies: - expect: 29.6.4 - pretty-format: 29.6.3 + expect: 29.7.0 + pretty-format: 29.7.0 '@types/json-schema@7.0.12': {} @@ -7573,7 +7570,7 @@ snapshots: ethereum-cryptography: 0.1.3 rlp: 2.2.7 - ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): + ethers@5.7.2: dependencies: '@ethersproject/abi': 5.7.0 '@ethersproject/abstract-provider': 5.7.0 @@ -7655,14 +7652,6 @@ snapshots: exit@0.1.2: {} - expect@29.6.4: - dependencies: - '@jest/expect-utils': 29.6.4 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.6.4 - jest-message-util: 29.6.3 - jest-util: 29.6.3 - expect@29.7.0: dependencies: '@jest/expect-utils': 29.7.0 @@ -8322,13 +8311,6 @@ snapshots: - babel-plugin-macros - supports-color - jest-diff@29.6.4: - dependencies: - chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.6.3 - jest-diff@29.7.0: dependencies: chalk: 4.1.2 @@ -8380,13 +8362,6 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 - jest-matcher-utils@29.6.4: - dependencies: - chalk: 4.1.2 - jest-diff: 29.6.4 - jest-get-type: 29.6.3 - pretty-format: 29.6.3 - jest-matcher-utils@29.7.0: dependencies: chalk: 4.1.2 @@ -8394,18 +8369,6 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 - jest-message-util@29.6.3: - dependencies: - '@babel/code-frame': 7.22.13 - '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.1 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.5 - pretty-format: 29.6.3 - slash: 3.0.0 - stack-utils: 2.0.6 - jest-message-util@29.7.0: dependencies: '@babel/code-frame': 7.22.13 @@ -9110,12 +9073,6 @@ snapshots: prettier@2.8.8: {} - pretty-format@29.6.3: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.2.0 - pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 @@ -9618,6 +9575,23 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.22.8) + ts-jest@29.1.2(@babel/core@7.22.8)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.22.8))(jest@29.7.0(@types/node@20.12.13))(typescript@5.4.5): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + jest: 29.7.0(@types/node@20.12.13) + jest-util: 29.6.3 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.6.2 + typescript: 5.4.5 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.22.8 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.22.8) + tsconfig-paths@4.2.0: dependencies: json5: 2.2.3 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 15989339..fa48ea2e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,4 @@ packages: - 'packages/*' - 'examples/*' + - 'e2e'