Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: E2E Tests

on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch: # allow manual trigger
Expand Down
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
legacy-peer-deps=true
43 changes: 43 additions & 0 deletions e2e/fixtures/local/w3c/tr_accept_surrender.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://trustvc.io/context/bill-of-lading-carrier.json",
"https://trustvc.io/context/attachments-context.json",
"https://trustvc.io/context/render-method-context-v2.json",
"https://trustvc.io/context/transferable-records-context.json",
"https://w3id.org/security/data-integrity/v2"
],
"renderMethod": [
{
"type": "EMBEDDED_RENDERER",
"templateName": "BILL_OF_LADING_CARRIER",
"id": "https://generic-templates.tradetrust.io"
}
],
"credentialSubject": {
"type": ["BillOfLadingCarrier"],
"blNumber": "232323",
"scac": "MAEU"
},
"type": ["VerifiableCredential"],
"credentialStatus": {
"type": "TransferableRecords",
"tokenNetwork": {
"chain": "ETH",
"chainId": 1337
},
"tokenRegistry": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
"tokenId": "08c94837a51152b18287ec2304c1115c4611b530f8a18290de2fe4192b22df9b"
},
"issuer": "did:web:trustvc.github.io:did:1",
"validFrom": "2025-08-28T03:31:39.440Z",
"id": "urn:uuid:019e8335-667c-7cc6-8633-3f56ce15ed63",
"proof": {
"type": "DataIntegrityProof",
"created": "2026-06-01T12:42:55Z",
"verificationMethod": "did:web:trustvc.github.io:did:1#multikey-1",
"cryptosuite": "ecdsa-sd-2023",
"proofPurpose": "assertionMethod",
"proofValue": "u2V0AhVhAnbvMfCuJT-Y2Hm2YTJ_AqlQPO2hjknc1Hh7gkxN7MtptShIVuWX7TAkTKIFPsywmoLoqK-K_E66q4VZ2e_jBmlgjgCQDi_mCpdxBQ_7N6uRAjvf-vuBgMbEwycehUWVM_nPor0xYICODl1NEMILZcbeyrBViJzWDpqx07b9CjHS-X_brwmAljlhA1a-RmJbUIrxTBoGUBiwxDiShGfY8MGybG0xJZEd7fo-EoIUhLaho32GfrrhASDERsDTRaOUDdtE0zXc8rjSlmFhATgTmZTbc6NVq3fJMV9QE3HIJdHGuUp3Cbtad5otxHGC41ZIVk4ufCbt4fnXXqgXv4v9PzoFDvwIs50tpDDKBSVhA5rPpfOr3xN_hIhc2X44-ZPNwDgLFcJII_92eNzhIhEYfqvTaTUt8KRFaV5juge7pd08oJ97bOYRohI54A0V2slhA-oYB3N8MdYlDW3SPdY9YWzVi1o4U8meHHdnMSiEUPbNVCEOupKoy6vDaq-EavbjPm23Ij4qBS0U9O9eQ6nRzQFhAyb6Lugc_7R86dU7aBE6hmoPEeU5E0V6LdRqxmuXeT2vgGsy3iZn6sohxgBmrUx931W3ykrJcMIra4XFpmJ0O-1hA7Dh_qM-nfLDUDxuMjvYQ109hpOXiJAfkonuUg0dF3avrZaS8rQfAx9r_FGJW1ZZ17ymrqky8WPikbU_B_89DM1hAiiJSvoocwPUMVvMdTH7nJapNsfqsIBr2N0f0ENVdnPTkz_IpcgQ5PzfjQQpPu_iOXlQEwGaPiZG6thFh3_7gslhASYThKvR12aI59TUgRzbLnqcTo61o6BBkgALevWTdJVnuzFCuIcl1HXjoC-3Rrc1AitT3GCf7nG2QaSbuF-3aW1hAkzYMpC-KuTm_vKUs1v_DOgy2L_z51Gvc6Aa8iD5N6pflbEDM8OmkYS5voXkXg6HwSH2hfw2huYdLt1tTBVhHOVhAJH0D8Ic3aFiL4NkB39l3R-8w9Sv0SByn-yl4O28GgS54_sjI1qpUFh7tQnJMqzgCop6illtoPrFwuLKYNsTZoVhAI-6ZpMR6oa2BUAN-ZFT7bI6ziwyB-uVjcBcnJZpVq2-0XXZrcd3faEXrd6owSEtOKODmAiYEsM6fcryKUHXcWFhAcMLgzs0SX1WZ1TrAER-3sr_2cZ4FSLBkHYtXN_-FlSt7RmraogU-3x1TrSVOarZjyOTVjM3HpeIPlZOQK1pfP1hAW3_xDpvG4y_vkoE_uvHpOxXtwgLL7hqU4KD77UGqBJ6NS47vJoBVoWPjejSjqfGFgP269dVCK0vmUNXiK4CyPVhA5EuT9JHjjvErid8cqGckJQdnNvl3cC22v21-JHXHgXInNvykPLyfCyGvFre2kWKDiay8pc7I_Q1L0vOpJbuCy4JnL2lzc3VlcmovdmFsaWRGcm9t"
}
}
43 changes: 43 additions & 0 deletions e2e/fixtures/local/w3c/tr_reject_surrender.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://trustvc.io/context/bill-of-lading-carrier.json",
"https://trustvc.io/context/attachments-context.json",
"https://trustvc.io/context/render-method-context-v2.json",
"https://trustvc.io/context/transferable-records-context.json",
"https://w3id.org/security/data-integrity/v2"
],
"renderMethod": [
{
"type": "EMBEDDED_RENDERER",
"templateName": "BILL_OF_LADING_CARRIER",
"id": "https://generic-templates.tradetrust.io"
}
],
"credentialSubject": {
"type": ["BillOfLadingCarrier"],
"blNumber": "232323",
"scac": "MAEU"
},
"type": ["VerifiableCredential"],
"credentialStatus": {
"type": "TransferableRecords",
"tokenNetwork": {
"chain": "ETH",
"chainId": 1337
},
"tokenRegistry": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
"tokenId": "8c67260e6f796368a680742e409d5fada0c58ac1abaa9baf38e9ebeacb7caf93"
},
"issuer": "did:web:trustvc.github.io:did:1",
"validFrom": "2025-09-28T03:31:39.440Z",
"id": "urn:uuid:019e8337-6604-711f-871c-8bcdf26ad76a",
"proof": {
"type": "DataIntegrityProof",
"created": "2026-06-01T12:45:06Z",
"verificationMethod": "did:web:trustvc.github.io:did:1#multikey-1",
"cryptosuite": "ecdsa-sd-2023",
"proofPurpose": "assertionMethod",
"proofValue": "u2V0AhVhAhH-THDccLgk-kGFXiT0Gm1Il8dmIsxFfCfiRy8Bvx620_6ctv67s7MFmnIQmI_Uk5m-LbL7CL0s7WOuXKSGvwVgjgCQCLIVwK1SzwbtKTwRv2ZLYuVkkUloho4ZatK0tztq9gv1YIOSpzh4waucKxiIn7LplaJKz1Nlixap6s0MuCw22cE_djlhAZ7xgk5BKgIgdVucZFp-4xMgwx80SVZQy7X9PBGlJjKu1xl-orf0Y0XBfm4GAYQCdzN6ovQIVFbDXramyLOHF6VhAZmEbNsxKgsC2DyeeLIinnqXz1USDqHguBJO8yro3AjYl71DSuvIy0egw-L_kfQ1MiT6KIbfeFWyDab3GV96rGVhAqqHdHGshTOgcadiFl090Vlrio_O0owGs2Ioiqt4AjquR-EKQLFYH5VGy4ov17b7x3k8I_j-YUKnI1pGUsmYpJFhA0kFRKW7BX9xbhLM1WUKHGZF4_HIOAO1kZTla9KbU6RLsCTF-KkusDkcnYrJeY4JijgTJKY3yOPTRKRbWHiBlSVhAI-8WNwwkQeTIEAtZA0s8YC58jQ0Np3896xZACnH05rM7Oq1mveZaD8AserBFxrG0kszHZ7dIm63LQPz4K_34aFhAQbgz0QHdywlF-B-5w6zPTVE3L2dv124cfr28mrE5LGFiN-B9n9LFO84rpn8T2UjQooDiizw6S0Ms9Fa6EN2bPVhASUSRsVCqqvNKEN6LymmczOxUOUzfO5mBAJu4Cl-wOlCnbz9Tf8d1QNthBEIHDWeFM4GknbRNlcNxXenvdcuhJFhA3lG5z5PctIC91yROIg0yPDRMviU_rjlhXhxTOyD1LFkjaycgAdrAXYF8gX6U3zMyEBPg7d0Gw_HaxutPJnakzVhAklFIK5YAjInODbDSHeMOtniALvYlEPuHc8PKvhR1qKJkSuUUViPtszRQWP4fq62kQz7S09G2wiDUSoJAAFqdHlhADWJWwFeVayrt9TI2pX78xpY2WYR2o_xTHY2mcL9K-cjbV3tOBPtJJ30UajeowVHYtLYcI7xawwICkcz--G34JFhAu0ERWg0cRqaaDKsFI9t94-yMak0DiATn1ppq6DwSFNDjbBUN1jKk5-qqzaWv5NqoUtiLhUMXrt5HiKKOdQt3xFhAorDjUPv32qY0mSOjkAp5y3wMTgk9LGdAK-rfaUlExUNWSE_1EWAdVGxNA_7yLX1ihDh4xOT2OnJRXD0zjPGrplhAtfvdCjsM5Eye15prlXTV9C5LFJuhYL9qDl8Xz-ku-mOJndJ1iVDYgVsiWUQoGyPWT8ld9yhutljPeEaP9nlRz1hA5XZyq3G58ZvCTzuR69CecMrg0SgtRcrUZyloizu74fIlk4awAnR2gO5wkUJpDjl-U-b4yiOmOwMjZWgvzsw6kYJnL2lzc3VlcmovdmFsaWRGcm9t"
}
}
21 changes: 19 additions & 2 deletions e2e/helpers/actions.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import type { Page } from '@playwright/test'
import { MetaMask } from '@synthetixio/synpress/playwright'

// Pages that already have the popover auto-dismiss handler registered.
const popoverHandlerRegistered = new WeakSet<Page>()

/**
* Dismisses the MetaMask "What's new" popover and any other blocking popups.
* Must be called after navigating to the MetaMask home page.
* MetaMask renders announcement popovers asynchronously after home.html
* loads, so a one-shot visibility check can miss one that appears late and
* then blocks every subsequent click. addLocatorHandler makes Playwright
* auto-dismiss the popover whenever it shows up, including mid-action.
*/
async function dismissMetaMaskPopups(metamaskPage: Page) {
const popoverClose = metamaskPage.locator('[data-testid="popover-close"]')

if (!popoverHandlerRegistered.has(metamaskPage)) {
popoverHandlerRegistered.add(metamaskPage)
await metamaskPage.addLocatorHandler(popoverClose, async () => {
await popoverClose.click()
})
}

// Also dismiss immediately if it is already showing.
if (await popoverClose.isVisible({ timeout: 3000 }).catch(() => false)) {
await popoverClose.click()
await metamaskPage.waitForTimeout(500)
Expand Down Expand Up @@ -130,6 +145,8 @@ export async function addMetaMaskAccount(
await metamaskPage.goto(`chrome-extension://${extensionId}/home.html`)
await metamaskPage.waitForLoadState('domcontentloaded')

await dismissMetaMaskPopups(metamaskPage)

await metamaskPage.locator('[data-testid="account-menu-icon"]').click()
await metamaskPage
.locator('[data-testid="multichain-account-menu-popover-add-account"]')
Expand Down Expand Up @@ -190,7 +207,7 @@ export async function hardhatRpcNode(method: string, params: unknown[] = []) {

export async function revokeMetamaskPermissions(
page: Page,
metamask: MetaMask
_metamask: MetaMask
) {
// Revoke dapp permissions so the next connect uses Account 2 (not the cached Account 1)
await page.evaluate(async () => {
Expand Down
5 changes: 3 additions & 2 deletions e2e/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { defineConfig, devices } from '@playwright/test'
export default defineConfig({
testDir: './tests',
// Verification (read-only) specs run via playwright.verify.config.ts — no MetaMask.
testIgnore: /verify-.*\.spec\.ts/,
// Excludes: verify-*.spec.ts, amoy-verify.spec.ts, pol-verify.spec.ts
testIgnore: /.*verify.*\.spec\.ts/,
timeout: 120_000, // per-test timeout (2 min)
expect: { timeout: 30_000 }, // per-assertion timeout
fullyParallel: false,
forbidOnly: !!process.env.CI,
retries: 0,
retries: process.env.CI ? 2 : 0,
workers: 1, // MetaMask requires a single browser context
reporter: 'html',
use: {
Expand Down
1 change: 0 additions & 1 deletion e2e/setup-contracts.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ const v5Contracts = require('@trustvc/trustvc/token-registry-v5/contracts')
// Transfer/Reject Holder
tokenId:
'0x31884d9f2926120a5779cad07bc5c83ee4ddcf99e88307c8bddf78509cfb2467',

...defaultToken,
},
{
Expand Down
2 changes: 0 additions & 2 deletions e2e/tests/nominate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { uploadAndVerify, connectMetaMask } from '../helpers/actions'

const __dirname = path.dirname(fileURLToPath(import.meta.url))

const NEW_HOLDER = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8' // Hardhat account #1

const NEW_BENEFICIARY = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8' // Hardhat account #1
const DOCUMENT_PATH = path.resolve(
__dirname,
Expand Down
3 changes: 0 additions & 3 deletions e2e/tests/reject-return-to-issuer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,5 @@ test.describe('Return to Issuer → Reject Return to Issuer', () => {
timeout: 10_000,
})
})
// ── Step 2: Accept Return to Issuer ─────────────────────────────────
// Continues on the same page — dismiss overlay, then accept.
// Requires: RestorerRole on the Token Registry (Account #0 as deployer)
})
})
11 changes: 0 additions & 11 deletions e2e/tests/transfer-and-reject-beneficiary.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,6 @@ test.describe
)
await connectMetaMask(page, metamask)

// await page.locator('[data-testid="connectToWallet"]').click()
// await page
// .locator('[data-testid="connectToMetamask"]')
// .waitFor({ state: 'visible', timeout: 10_000 })
// await page.locator('[data-testid="connectToMetamask"]').click()
// await metamask.connectToDapp()
// await page
// .locator('[data-testid="connect-blockchain-continue"]')
// .waitFor({ state: 'visible', timeout: 15_000 })
// await page.locator('[data-testid="connect-blockchain-continue"]').click()

await expect(
page.locator('[data-testid="manageAssetDropdown"]')
).toBeVisible({ timeout: 15_000 })
Expand Down
7 changes: 0 additions & 7 deletions e2e/tests/transfer-and-reject-owners.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,6 @@ test.describe.serial('Transfer Owners → Reject Transfer Owners', () => {
await expect(
page.locator('text=Transfer Ownership/Holdership Success')
).toBeVisible({ timeout: 60_000 })
// const dialog = page.getByRole('dialog')
// await expect(dialog.getByText(NEW_OWNER, { exact: false })).toBeVisible({
// timeout: 10_000,
// })
// await expect(dialog.getByText(NEW_HOLDER, { exact: false })).toBeVisible({
// timeout: 10_000,
// })
})

// ── Test 2: Reject Transfer Owners ──────────────────────────────────────
Expand Down
Loading
Loading