diff --git a/README.md b/README.md
index 22964a33d..034bfc61d 100644
--- a/README.md
+++ b/README.md
@@ -116,9 +116,9 @@ Supports [evergreen](https://nuxt.com/blog/v3#the-browser-and-nodejs-support) br
The core browser set targets the 2 most recent major versions of Chrome, Firefox, and Edge on a monthly basis and Safari
on a yearly basis.
-## Tooling
+## Testing
-This project uses [Applitools Visual AI](https://applitools.com/) as part of its automated testing.
+This project uses [Cypress](https://cypress.io/) for e2e testing. Tests can be executed using the command ```yarn e2e:open```.
## Contribution
diff --git a/cypress.config.ts b/cypress.config.ts
new file mode 100644
index 000000000..b4d6f9b24
--- /dev/null
+++ b/cypress.config.ts
@@ -0,0 +1,23 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ env: {
+ accountAddress: 'ak_gZ55FLJoGEfF5gJ2xJU7j9uSH3fEjoTZq3ygQG8gYA4no6GFW',
+ contractAddress: 'ct_s5ZB6cGCqS5QbUboQBK8CWwpknKRSajrt8b1EQRp4t4R5D47e',
+ microblockAddress: 'mh_27HKqcut9U9xDwEAf3Lz6evTxY4rfy7odKeSnQaqu45iQesjyj',
+ nftAddress: 'ct_2UVjVLvt2NycqbfJWywixyYm68iVvkiVS9wubiQRjp9WeQtfpK',
+ transactionAddress: 'th_2Yafj84tsuxskvJnzqGcvthrpDUX8gZE84RXVUwXvkSJxmxbc1',
+ oracleAddress: 'ok_2w2Gkp9mwThn6jWdJi5Leuh3P5Zj7oJ6gyoHa8KnKzWwEVSnKf',
+ tokenAddress: 'ct_2qyFRzXzTyPCtPKZQ32EPXqxxAcgiWqtADV3amcBVVPYQRKZm7',
+ stateChannelAddress: 'ch_2Qo4r6u3Bq1ZMnPL7GpjLLsATaEgMK5BnYnoi68hzLL5QuKbev',
+ name: 'testaensrawpointers.chain',
+ keyblockId: '947025',
+ },
+ e2e: {
+ baseUrl: 'http://localhost:8080',
+ experimentalRunAllSpecs: true,
+ },
+ viewportWidth: 1280,
+ viewportHeight: 720,
+ defaultCommandTimeout: 30000,
+})
diff --git a/cypress/e2e/app/accountDetail.cy.js b/cypress/e2e/app/accountDetail.cy.js
new file mode 100644
index 000000000..b291ea948
--- /dev/null
+++ b/cypress/e2e/app/accountDetail.cy.js
@@ -0,0 +1,17 @@
+describe('account detail', () => {
+ it('should display account detail', () => {
+ cy.visit(`/accounts/${Cypress.env('accountAddress')}`)
+
+ cy.get('.account-details-panel').should('be.visible')
+ cy.get('.account-activities-panel table').should('be.visible')
+
+ cy.contains('.tabs__item', 'Transactions').click()
+ cy.get('.account-transactions-panel table').should('be.visible')
+
+ cy.contains('.tabs__item', 'AENS Names').click()
+ cy.get('.account-names-panel table').should('be.visible')
+
+ cy.contains('.tabs__item', 'Tokens').click()
+ cy.get('.account-tokens-panel table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/contractDetail.cy.js b/cypress/e2e/app/contractDetail.cy.js
new file mode 100644
index 000000000..07b9731ab
--- /dev/null
+++ b/cypress/e2e/app/contractDetail.cy.js
@@ -0,0 +1,15 @@
+describe('contract detail', () => {
+ it('should display contract detail', () => {
+ cy.visit(`/contracts/${Cypress.env('contractAddress')}`)
+
+ cy.get('.contract-details-panel').should('be.visible')
+ cy.get('.contract-call-transactions-panel table').should('be.visible')
+
+ cy.contains('.tabs__item', 'Events').click()
+ cy.get('.contract-events-panel table').should('be.visible')
+
+ cy.contains('.tabs__item', 'Contract').click()
+ cy.get('.contract-verified-table').should('be.visible')
+ cy.get('.code-editor').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/contracts.cy.js b/cypress/e2e/app/contracts.cy.js
new file mode 100644
index 000000000..57f03c5d2
--- /dev/null
+++ b/cypress/e2e/app/contracts.cy.js
@@ -0,0 +1,8 @@
+describe('contracts', () => {
+ it('should display contracts', () => {
+ cy.visit('/contracts')
+
+ cy.get('.contracts-table').should('be.visible')
+ cy.get('.line-chart').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/homepage.cy.js b/cypress/e2e/app/homepage.cy.js
new file mode 100644
index 000000000..893bb7d97
--- /dev/null
+++ b/cypress/e2e/app/homepage.cy.js
@@ -0,0 +1,12 @@
+describe('homepage', () => {
+ it('should display homepage', () => {
+ cy.visit('/')
+
+ cy.get('.stats-panel').should('be.visible')
+ cy.get('.dashboard-state-channels-panel table').should('be.visible')
+ cy.get('.dashboard-auctions-panel table').should('be.visible')
+ cy.get('.dashboard-names-panel table').should('be.visible')
+ cy.get('.dashboard-keyblock-panel table').should('be.visible')
+ cy.get('.search-bar').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/keyblockDetail.cy.js b/cypress/e2e/app/keyblockDetail.cy.js
new file mode 100644
index 000000000..9342395a5
--- /dev/null
+++ b/cypress/e2e/app/keyblockDetail.cy.js
@@ -0,0 +1,8 @@
+describe('keyblock details', () => {
+ it('should display keyblock detail', () => {
+ cy.visit(`/keyblocks/${Cypress.env('keyblockId')}`)
+
+ cy.get('.keyblock-details-panel__controls').should('be.visible')
+ cy.get('.keyblock-microblock-panel').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/microblockDetail.cy.js b/cypress/e2e/app/microblockDetail.cy.js
new file mode 100644
index 000000000..7ba1145f4
--- /dev/null
+++ b/cypress/e2e/app/microblockDetail.cy.js
@@ -0,0 +1,8 @@
+describe('microblock details', () => {
+ it('should display microblock detail', () => {
+ cy.visit(`/microblocks/${Cypress.env('microblockAddress')}`)
+
+ cy.get('.microblock-details-panel table').should('be.visible')
+ cy.get('.microblock-transactions-panel table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/nameDetail.cy.js b/cypress/e2e/app/nameDetail.cy.js
new file mode 100644
index 000000000..e4a3c14b3
--- /dev/null
+++ b/cypress/e2e/app/nameDetail.cy.js
@@ -0,0 +1,9 @@
+describe('name detail', () => {
+ it('should display name detail', () => {
+ cy.visit(`/names/${Cypress.env('name')}`)
+
+ cy.get('.name-details-panel').should('be.visible')
+ cy.get('.name-pointers-special-panel table').should('be.visible')
+ cy.get('.name-history-panel table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/names.cy.js b/cypress/e2e/app/names.cy.js
new file mode 100644
index 000000000..0a70c9bec
--- /dev/null
+++ b/cypress/e2e/app/names.cy.js
@@ -0,0 +1,14 @@
+describe('names', () => {
+ it('should display names', () => {
+ cy.visit('/names')
+
+ cy.get('.line-chart').should('be.visible')
+ cy.get('.names-active-table').should('be.visible')
+
+ cy.contains('.tabs__item', 'In Auction').click()
+ cy.get('.names-in-auction-table').should('be.visible')
+
+ cy.contains('.tabs__item', 'Expired').click()
+ cy.get('.names-expired-table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/nftDetail.cy.js b/cypress/e2e/app/nftDetail.cy.js
new file mode 100644
index 000000000..dbe668902
--- /dev/null
+++ b/cypress/e2e/app/nftDetail.cy.js
@@ -0,0 +1,11 @@
+describe('nft detail', () => {
+ it('should display nft detail', () => {
+ cy.visit(`/nfts/${Cypress.env('nftAddress')}`)
+
+ cy.get('.nfts-details-panel table').should('be.visible')
+ cy.get('.nfts-transfers-table').should('be.visible')
+
+ cy.contains('.tabs__item', 'Inventory').click()
+ cy.get('.nfts-owners-panel__table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/nfts.cy.js b/cypress/e2e/app/nfts.cy.js
new file mode 100644
index 000000000..9888ccad7
--- /dev/null
+++ b/cypress/e2e/app/nfts.cy.js
@@ -0,0 +1,7 @@
+describe('nfts', () => {
+ it('should display nfts', () => {
+ cy.visit('/nfts')
+
+ cy.get('.nfts-table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/oracleDetail.cy.js b/cypress/e2e/app/oracleDetail.cy.js
new file mode 100644
index 000000000..40e2ce1af
--- /dev/null
+++ b/cypress/e2e/app/oracleDetail.cy.js
@@ -0,0 +1,8 @@
+describe('oracle detail', () => {
+ it('should display oracle detail', () => {
+ cy.visit(`/oracles/${Cypress.env('oracleAddress')}`)
+
+ cy.get('.oracle-details-panel table').should('be.visible')
+ cy.get('.oracle-events-panel table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/oracles.cy.js b/cypress/e2e/app/oracles.cy.js
new file mode 100644
index 000000000..c3bf8d35e
--- /dev/null
+++ b/cypress/e2e/app/oracles.cy.js
@@ -0,0 +1,7 @@
+describe('oracles', () => {
+ it('should display oracles', () => {
+ cy.visit('/oracles')
+
+ cy.get('.oracles-table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/search.cy.js b/cypress/e2e/app/search.cy.js
new file mode 100644
index 000000000..edd7b2763
--- /dev/null
+++ b/cypress/e2e/app/search.cy.js
@@ -0,0 +1,19 @@
+describe('search', () => {
+ it('should display search', () => {
+ cy.visit('/')
+
+ // loading waiting workaround
+ cy.get('.stats-panel').should('be.visible')
+
+ cy.get('.search-bar__input').type('c')
+ cy.get('.search-bar__submit').click()
+
+ cy.get('.search-names-table').should('be.visible')
+
+ cy.contains('.tabs__item', 'Tokens').click()
+ cy.get('.search-tokens-table').should('be.visible')
+
+ cy.contains('.tabs__item', 'NFTs').click()
+ cy.get('.search-nfts-table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/stateChannelDetail.cy.js b/cypress/e2e/app/stateChannelDetail.cy.js
new file mode 100644
index 000000000..f75319f38
--- /dev/null
+++ b/cypress/e2e/app/stateChannelDetail.cy.js
@@ -0,0 +1,8 @@
+describe('state channel detail', () => {
+ it('should display state channel detail', () => {
+ cy.visit(`/state-channels/${Cypress.env('stateChannelAddress')}`)
+
+ cy.get('.state-channel-details-panel table').should('be.visible')
+ cy.get('.state-channel-transactions-panel table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/stateChannels.cy.js b/cypress/e2e/app/stateChannels.cy.js
new file mode 100644
index 000000000..2e95672f6
--- /dev/null
+++ b/cypress/e2e/app/stateChannels.cy.js
@@ -0,0 +1,7 @@
+describe('state channels', () => {
+ it('should display oracles', () => {
+ cy.visit('/state-channels')
+
+ cy.get('.state-channels-table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/tokenDetail.cy.js b/cypress/e2e/app/tokenDetail.cy.js
new file mode 100644
index 000000000..c93a8a8fb
--- /dev/null
+++ b/cypress/e2e/app/tokenDetail.cy.js
@@ -0,0 +1,11 @@
+describe('token detail', () => {
+ it('should display token detail', () => {
+ cy.visit(`/tokens/${Cypress.env('tokenAddress')}`)
+
+ cy.get('.token-details-panel table').should('be.visible')
+ cy.get('.token-holders-panel table').should('be.visible')
+
+ cy.contains('.tabs__item', 'Events').click()
+ cy.get('.token-events-panel table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/tokens.cy.js b/cypress/e2e/app/tokens.cy.js
new file mode 100644
index 000000000..149a2df78
--- /dev/null
+++ b/cypress/e2e/app/tokens.cy.js
@@ -0,0 +1,7 @@
+describe('tokens', () => {
+ it('should display tokens', () => {
+ cy.visit('/tokens')
+
+ cy.get('.tokens-panel').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/transactionDetail.cy.js b/cypress/e2e/app/transactionDetail.cy.js
new file mode 100644
index 000000000..6213a90f9
--- /dev/null
+++ b/cypress/e2e/app/transactionDetail.cy.js
@@ -0,0 +1,8 @@
+describe('transaction detail', () => {
+ it('transaction detail', () => {
+ cy.visit(`/transactions/${Cypress.env('transactionAddress')}`)
+
+ cy.get('.transaction-general-panel table').should('be.visible')
+ cy.get('.transaction-type-panel table').should('be.visible')
+ })
+})
diff --git a/cypress/e2e/app/transactions.cy.js b/cypress/e2e/app/transactions.cy.js
new file mode 100644
index 000000000..996c3b92e
--- /dev/null
+++ b/cypress/e2e/app/transactions.cy.js
@@ -0,0 +1,9 @@
+describe('transactions', () => {
+ it('should display transactions', () => {
+ cy.visit('/transactions')
+
+ cy.get('.transactions-table').should('be.visible')
+ cy.get('.line-chart').should('be.visible')
+ cy.get('.transaction-statistics__panel').should('be.visible')
+ })
+})
diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts
new file mode 100644
index 000000000..95857aea4
--- /dev/null
+++ b/cypress/support/commands.ts
@@ -0,0 +1,37 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts
new file mode 100644
index 000000000..ed5730de1
--- /dev/null
+++ b/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/e2e.ts is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/package.json b/package.json
index 2ff3f6bc0..876cbb5bd 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,9 @@
"lint:fix": "yarn lint:js --fix && yarn lint:style --fix",
"lint:js": "eslint --ext .ts,.js,.vue src",
"lint:style": "stylelint \"./src/**/*.vue\" \"src/**/*.css\"",
- "reinstall": "rm -rf node_modules/ && yarn cache clean && yarn install"
+ "reinstall": "rm -rf node_modules/ && yarn cache clean && yarn install",
+ "e2e:run": "cypress run",
+ "e2e:open": "cypress open"
},
"dependencies": {
"@aeternity/aepp-sdk": "^13.3.2",
@@ -56,6 +58,7 @@
"@nuxtjs/plausible": "^0.2.4",
"@pinia/nuxt": "^0.5.1",
"@vitejs/plugin-vue": "^5.0.4",
+ "cypress": "^13.8.1",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-config-standard": "^17.1.0",
diff --git a/src/components/ContractVerifiedTable.vue b/src/components/ContractVerifiedTable.vue
index e4ceaa0c8..066162cbf 100644
--- a/src/components/ContractVerifiedTable.vue
+++ b/src/components/ContractVerifiedTable.vue
@@ -1,5 +1,5 @@
-