Skip to content

Commit

Permalink
feat(papi): Support and add Papi tests (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tbaut authored Oct 23, 2024
1 parent 8363acb commit 5a7aeeb
Show file tree
Hide file tree
Showing 21 changed files with 2,603 additions and 839 deletions.
26 changes: 13 additions & 13 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ jobs:
# custom test command to run
command: yarn test:ci
# store the screenshots if the tests fail
- name: Store screenshots
uses: actions/upload-artifact@v1
if: failure()
with:
name: cypress-screenshots
path: packages/example/cypress/screenshots
# store the videos if the tests fail
- name: Store videos
uses: actions/upload-artifact@v1
if: failure()
with:
name: cypress-videos
path: packages/example/cypress/videos
# - name: Store screenshots
# uses: actions/upload-artifact@v1
# if: failure()
# with:
# name: cypress-screenshots
# path: packages/example/cypress/screenshots
# # store the videos if the tests fail
# - name: Store videos
# uses: actions/upload-artifact@v1
# if: failure()
# with:
# name: cypress-videos
# path: packages/example/cypress/videos
3 changes: 3 additions & 0 deletions packages/example/.papi/descriptors/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*
!.gitignore
!package.json
24 changes: 24 additions & 0 deletions packages/example/.papi/descriptors/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"version": "0.1.0-autogenerated.11858138475473992995",
"name": "@polkadot-api/descriptors",
"files": [
"dist"
],
"exports": {
".": {
"types": "./dist/index.d.ts",
"module": "./dist/index.mjs",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./package.json": "./package.json"
},
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"browser": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"sideEffects": false,
"peerDependencies": {
"polkadot-api": "*"
}
}
Binary file added packages/example/.papi/metadata/pas.scale
Binary file not shown.
10 changes: 10 additions & 0 deletions packages/example/.papi/polkadot-api.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"version": 0,
"descriptorPath": ".papi/descriptors",
"entries": {
"pas": {
"chain": "paseo",
"metadata": ".papi/metadata/pas.scale"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { waitForAuthRequest } from '../utils/waitForAuthRequests'

const Alice = {
address: '5Fsaew2ZtsgpaCUWDmBnz8Jn8i49dvJFQUaJ5TZ6NGC1EBeS',
addressWithPrefix0: '14osoGHdkexJ1jV2BQEo8H8vzL3oLDrPUyJnEkYSvMDXQcu7',
name: 'Alice',
type: 'sr25519',
mnemonic: 'blame only east lunar valve mother link pill expect eight quote table'
} as any

const EXAMPLE_DAPP_NAME = 'example-dapp'
const CUSTOM_WALLET_NAME = 'My-custom-wallet'
const TESTING_LANDING_PAGE = 'http://localhost:3333'

describe('test cypress-polkadot-wallet plugin', () => {
it('should check if plugin is installed', () => {
expect(cy).property('initWallet').to.be.a('function')
})

it('should init the wallet and connect accounts with authorization request', () => {
cy.visit(TESTING_LANDING_PAGE)
cy.initWallet([Alice])
cy.get('#connect-accounts-papi').click()
cy.getAuthRequests().then((authRequests) => {
const requests = Object.values(authRequests)
// we should have 1 connection request to the wallet
cy.wrap(requests.length).should('eq', 1)
// this request should be from the application EXAMPLE_DAPP_NAME
cy.wrap(requests[0].origin).should('eq', EXAMPLE_DAPP_NAME)
cy.approveAuth(requests[0].id, [Alice.address])
})

// check that the extension is injected
cy.get('#all-extensions').should('contain', 'polkadot-js')
// check that the accounts in papi is injected
cy.get('#all-accounts').should('contain', Alice.address)
cy.get('#injected-error').should('be.empty')
})

it('should init the wallet and connect accounts without authorization request', () => {
cy.visit(TESTING_LANDING_PAGE)
// because we pass the origin here, all the account will be automatically
// accepted by the wallet comming from this origin
cy.initWallet([Alice], EXAMPLE_DAPP_NAME)
cy.get('#connect-accounts-papi').click()

// Here, the wallet has not requested the user authorization, as if the user
// had already approved this Dapp in the past

// check that 'polkadot-js' is injected and that we get access to the
// injected accounts
cy.get('#all-extensions').should('contain', 'polkadot-js')
cy.get('#all-accounts').should('contain', Alice.address)
cy.get('#injected-error').should('be.empty')
})

it('should init the wallet and connect accounts without authorization request and a custom wallet name', () => {
cy.visit(TESTING_LANDING_PAGE)
cy.initWallet([Alice], EXAMPLE_DAPP_NAME, CUSTOM_WALLET_NAME)
cy.get('#connect-accounts-papi').click()

// check that the custom name is injected
// and that we get access to the injected accounts
cy.get('#all-extensions').should('contain', CUSTOM_WALLET_NAME)
cy.get('#all-accounts').should('contain', Alice.address)
cy.get('#injected-error').should('be.empty')
})

it('should init the wallet and reject connection', () => {
cy.visit(TESTING_LANDING_PAGE)
cy.initWallet([Alice])
cy.get('#connect-accounts-papi').click()
cy.getAuthRequests().then((authRequests) => {
const requests = Object.values(authRequests)
// we should have 1 connection request to the wallet
cy.wrap(requests.length).should('eq', 1)
cy.wrap(requests[0].origin).should('eq', EXAMPLE_DAPP_NAME)

const ERROR_MESSAGE = 'Cancelled by user'
// The reason 'Cancelled by user' is only printed in the console
// and the Dapp can't access it. It can only know that there are
// no injected wallet.
cy.rejectAuth(requests[0].id, ERROR_MESSAGE)

// check that the Dapp doesn't get access to any wallet
cy.get('#injected-error').should('contain', ERROR_MESSAGE)
cy.get('#injected').should('be.empty')

// check that no account got injected
cy.get('#all-accounts').should('be.empty')
})
})

it('should sign a transaction and succeed', () => {
cy.visit(TESTING_LANDING_PAGE)
cy.initWallet([Alice], EXAMPLE_DAPP_NAME)
cy.get('#connect-accounts-papi').click()
cy.get('#all-accounts').should('contain', Alice.address)
cy.get('#amount-input').type('{selectAll}{del}12345')
cy.get('#send-tx-papi').click()

// this is using wait-until to wait for the tx request
// to reach the wallet
waitForAuthRequest()

cy.getTxRequests().then((req) => {
const txRequests = Object.values(req)
cy.wrap(txRequests.length).should('eq', 1)
cy.wrap(txRequests[0].payload.address).should('eq', Alice.addressWithPrefix0)
cy.approveTx(txRequests[0].id)
cy.get('#tx-hash').should('not.be.empty')
cy.get('#tx-events', { timeout: 20000 }).should('contain', 'ExtrinsicSuccess')
cy.get('#tx-error').should('be.empty')
})
})

it.skip('should sign a transaction and get an error', () => {
cy.visit(TESTING_LANDING_PAGE)
cy.initWallet([Alice], EXAMPLE_DAPP_NAME)
cy.get('#connect-accounts-papi').click()
cy.get('#all-accounts').should('contain', Alice.address)
// Alice does not have enough funds the tx will be broadcasted
// but the blockchain should reject it
cy.get('#amount-input').type('{selectAll}{del}100000000000000')
cy.get('#send-tx-papi').click()

waitForAuthRequest()

cy.getTxRequests().then((req) => {
const txRequests = Object.values(req)
cy.wrap(txRequests.length).should('eq', 1)
cy.wrap(txRequests[0].payload.address).should('eq', Alice.addressWithPrefix0)
cy.approveTx(txRequests[0].id)
// the tx hash will be present, but the chain will reject the
// tx eventually
cy.get('#tx-hash').should('not.be.empty')
cy.get('#tx-events', { timeout: 20000 }).should('contain', 'ExtrinsicFailed')
cy.get('#tx-events').should('contain', 'FundsUnavailable')
})
})
})
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { InjectedAccountWitMnemonic } from '@chainsafe/cypress-polkadot-wallet/dist/types'
import { waitForAuthRequest } from '../utils/waitForAuthRequests'

const Alice = {
address: '5Fsaew2ZtsgpaCUWDmBnz8Jn8i49dvJFQUaJ5TZ6NGC1EBeS',
addressWithPrefix0: '14osoGHdkexJ1jV2BQEo8H8vzL3oLDrPUyJnEkYSvMDXQcu7',
name: 'Alice',
type: 'sr25519',
mnemonic: 'blame only east lunar valve mother link pill expect eight quote table'
} as InjectedAccountWitMnemonic
} as any

const EXAMPLE_DAPP_NAME = 'example-dapp'
const CUSTOM_WALLET_NAME = 'My-custom-wallet'
Expand All @@ -20,7 +20,7 @@ describe('test cypress-polkadot-wallet plugin', () => {
it('should init the wallet and connect accounts with authorization request', () => {
cy.visit(TESTING_LANDING_PAGE)
cy.initWallet([Alice])
cy.get('#connect-accounts').click()
cy.get('#connect-accounts-pjs').click()
cy.getAuthRequests().then((authRequests) => {
const requests = Object.values(authRequests)
// we should have 1 connection request to the wallet
Expand All @@ -43,7 +43,7 @@ describe('test cypress-polkadot-wallet plugin', () => {
// because we pass the origin here, all the account will be automatically
// accepted by the wallet comming from this origin
cy.initWallet([Alice], EXAMPLE_DAPP_NAME)
cy.get('#connect-accounts').click()
cy.get('#connect-accounts-pjs').click()

// Here, the wallet has not requested the user authorization, as if the user
// had already approved this Dapp in the past
Expand All @@ -58,7 +58,7 @@ describe('test cypress-polkadot-wallet plugin', () => {
it('should init the wallet and connect accounts without authorization request and a custom wallet name', () => {
cy.visit(TESTING_LANDING_PAGE)
cy.initWallet([Alice], EXAMPLE_DAPP_NAME, CUSTOM_WALLET_NAME)
cy.get('#connect-accounts').click()
cy.get('#connect-accounts-pjs').click()

// check that the custom name is injected
// and that we get access to the injected accounts
Expand All @@ -70,7 +70,7 @@ describe('test cypress-polkadot-wallet plugin', () => {
it('should init the wallet and reject connection', () => {
cy.visit(TESTING_LANDING_PAGE)
cy.initWallet([Alice])
cy.get('#connect-accounts').click()
cy.get('#connect-accounts-pjs').click()
cy.getAuthRequests().then((authRequests) => {
const requests = Object.values(authRequests)
// we should have 1 connection request to the wallet
Expand All @@ -94,10 +94,10 @@ describe('test cypress-polkadot-wallet plugin', () => {
it('should sign a transaction and succeed', () => {
cy.visit(TESTING_LANDING_PAGE)
cy.initWallet([Alice], EXAMPLE_DAPP_NAME)
cy.get('#connect-accounts').click()
cy.get('#connect-accounts-pjs').click()
cy.get('#all-accounts').should('contain', Alice.address)
cy.get('#amount-input').type('{selectAll}{del}12345')
cy.get('#send-tx').click()
cy.get('#send-tx-pjs').click()

// this is using wait-until to wait for the tx request
// to reach the wallet
Expand All @@ -106,7 +106,7 @@ describe('test cypress-polkadot-wallet plugin', () => {
cy.getTxRequests().then((req) => {
const txRequests = Object.values(req)
cy.wrap(txRequests.length).should('eq', 1)
cy.wrap(txRequests[0].payload.address).should('eq', Alice.address)
cy.wrap(txRequests[0].payload.address).should('eq', Alice.addressWithPrefix0)
cy.approveTx(txRequests[0].id)
cy.get('#tx-hash').should('not.be.empty')
cy.get('#tx-events', { timeout: 10000 }).should('contain', 'system.ExtrinsicSuccess')
Expand All @@ -117,19 +117,19 @@ describe('test cypress-polkadot-wallet plugin', () => {
it('should sign a transaction and get an error', () => {
cy.visit(TESTING_LANDING_PAGE)
cy.initWallet([Alice], EXAMPLE_DAPP_NAME)
cy.get('#connect-accounts').click()
cy.get('#connect-accounts-pjs').click()
cy.get('#all-accounts').should('contain', Alice.address)
// Alice doesn not have enough funds the tx will be broadcasted
// but the blockchain should reject it
cy.get('#amount-input').type('{selectAll}{del}100000000000000')
cy.get('#send-tx').click()
cy.get('#send-tx-pjs').click()

waitForAuthRequest()

cy.getTxRequests().then((req) => {
const txRequests = Object.values(req)
cy.wrap(txRequests.length).should('eq', 1)
cy.wrap(txRequests[0].payload.address).should('eq', Alice.address)
cy.wrap(txRequests[0].payload.address).should('eq', Alice.addressWithPrefix0)
cy.approveTx(txRequests[0].id)
// the tx hash will be present, but the chain will reject the
// tx eventually
Expand Down
7 changes: 5 additions & 2 deletions packages/example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
</head>
<body>
<div id="app">
<button id="connect-accounts">Connect</button>
<button id="connect-accounts-pjs">Connect with Pjs</button>
<button id="connect-accounts-papi">Connect with Papi</button>
<input id="amount-input" />
<button id="send-tx">Send Tx</button>
<button id="send-tx-pjs">Send Tx with Pjs</button>
<button id="send-tx-papi">Send Tx with Papi</button>
<div id="all-extensions"></div>
<div id="injected"></div>
<div id="injected-error"></div>
<div id="all-accounts"></div>
Expand Down
29 changes: 16 additions & 13 deletions packages/example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,26 @@
"test:ci": "cypress run --browser chrome --headless",
"lint": "yarn eslint './{src, cypress}/**/*.{ts, tsx, js, jsx, json, yml, yaml}'",
"format": "yarn prettier --write .",
"format-check": "yarn prettier --check ."
"format-check": "yarn prettier --check .",
"postinstall": "yarn papi"
},
"dependencies": {
"@polkadot/api": "^12.0.2",
"@polkadot/extension-dapp": "^0.48.1"
"@polkadot-api/descriptors": "portal:.papi/descriptors",
"@polkadot/api": "^14.1.1",
"@polkadot/extension-dapp": "^0.54.1",
"polkadot-api": "^1.6.2"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^7.14.1",
"@typescript-eslint/parser": "^7.14.1",
"cypress": "^13.12.0",
"cypress-wait-until": "^3.0.1",
"eslint": "^9.5.0",
"@typescript-eslint/eslint-plugin": "^8.11.0",
"@typescript-eslint/parser": "^8.11.0",
"cypress": "^13.15.0",
"cypress-wait-until": "^3.0.2",
"eslint": "^9.13.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-cypress": "^3.3.0",
"eslint-plugin-prettier": "^5.1.3",
"prettier": "^3.3.2",
"typescript": "^5.5.2",
"vite": "^5.3.2"
"eslint-plugin-cypress": "^4.0.0",
"eslint-plugin-prettier": "^5.2.1",
"prettier": "^3.3.3",
"typescript": "^5.6.3",
"vite": "^5.4.9"
}
}
Loading

0 comments on commit 5a7aeeb

Please sign in to comment.