diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 732923ce2..369b101ff 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -1,10 +1,6 @@ name: Cypress Tests -on: - push: - branches: - - master - pull_request: +on: [push, pull_request] jobs: cypress: runs-on: ${{ matrix.os }} @@ -25,7 +21,7 @@ jobs: cache: 'npm' cache-dependency-path: frontend/package-lock.json - name: ${{ matrix.browser }} browser tests (Mempool) - uses: cypress-io/github-action@v2 + uses: cypress-io/github-action@v4 with: tag: ${{ github.event_name }} working-directory: frontend @@ -36,9 +32,9 @@ jobs: record: true parallel: true spec: | - cypress/integration/mainnet/*.spec.ts - cypress/integration/signet/*.spec.ts - cypress/integration/testnet/*.spec.ts + cypress/e2e/mainnet/*.spec.ts + cypress/e2e/signet/*.spec.ts + cypress/e2e/testnet/*.spec.ts group: Tests on ${{ matrix.browser }} (Mempool) browser: ${{ matrix.browser }} ci-build-id: '${{ github.sha }}-${{ github.workflow }}-${{ github.event_name }}' @@ -49,7 +45,7 @@ jobs: CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} - name: ${{ matrix.browser }} browser tests (Liquid) - uses: cypress-io/github-action@v2 + uses: cypress-io/github-action@v4 if: always() with: tag: ${{ github.event_name }} @@ -61,8 +57,8 @@ jobs: record: true parallel: true spec: | - cypress/integration/liquid/liquid.spec.ts - cypress/integration/liquidtestnet/liquidtestnet.spec.ts + cypress/e2e/liquid/liquid.spec.ts + cypress/e2e/liquidtestnet/liquidtestnet.spec.ts group: Tests on ${{ matrix.browser }} (Liquid) browser: ${{ matrix.browser }} ci-build-id: '${{ github.sha }}-${{ github.workflow }}-${{ github.event_name }}' @@ -73,7 +69,7 @@ jobs: CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} - name: ${{ matrix.browser }} browser tests (Bisq) - uses: cypress-io/github-action@v2 + uses: cypress-io/github-action@v4 if: always() with: tag: ${{ github.event_name }} @@ -84,7 +80,7 @@ jobs: wait-on-timeout: 120 record: true parallel: true - spec: cypress/integration/bisq/bisq.spec.ts + spec: cypress/e2e/bisq/bisq.spec.ts group: Tests on ${{ matrix.browser }} (Bisq) browser: ${{ matrix.browser }} ci-build-id: '${{ github.sha }}-${{ github.workflow }}-${{ github.event_name }}' diff --git a/frontend/cypress.config.ts b/frontend/cypress.config.ts new file mode 100644 index 000000000..14d36fc74 --- /dev/null +++ b/frontend/cypress.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'cypress' + +export default defineConfig({ + projectId: 'ry4br7', + videosFolder: 'cypress/videos', + screenshotsFolder: 'cypress/screenshots', + fixturesFolder: 'cypress/fixtures', + video: false, + retries: { + runMode: 3, + openMode: 0, + }, + chromeWebSecurity: false, + e2e: { + // We've imported your old cypress plugins here. + // You may want to clean this up later by importing these. + setupNodeEvents(on, config) { + return require('./cypress/plugins/index.js')(on, config) + }, + baseUrl: 'http://localhost:4200', + specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}', + }, +}) diff --git a/frontend/cypress.json b/frontend/cypress.json deleted file mode 100644 index cc66763d3..000000000 --- a/frontend/cypress.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "projectId": "ry4br7", - "integrationFolder": "cypress/integration", - "supportFile": "cypress/support/index.ts", - "videosFolder": "cypress/videos", - "screenshotsFolder": "cypress/screenshots", - "pluginsFile": "cypress/plugins/index.js", - "fixturesFolder": "cypress/fixtures", - "baseUrl": "http://localhost:4200", - "video": false, - "retries": { - "runMode": 3, - "openMode": 0 - }, - "chromeWebSecurity": false -} diff --git a/frontend/cypress/integration/bisq/bisq.spec.ts b/frontend/cypress/e2e/bisq/bisq.spec.ts similarity index 97% rename from frontend/cypress/integration/bisq/bisq.spec.ts rename to frontend/cypress/e2e/bisq/bisq.spec.ts index bc9e1e3b9..e81b17185 100644 --- a/frontend/cypress/integration/bisq/bisq.spec.ts +++ b/frontend/cypress/e2e/bisq/bisq.spec.ts @@ -35,13 +35,14 @@ describe('Bisq', () => { "Proposal", "Reimbursement request", "Transfer BSQ", "Unlock", "Vote reveal" ]; filters.forEach((filter) => { - it(`filters the transaction screen by ${filter}`, () => { + it.only(`filters the transaction screen by ${filter}`, () => { cy.visit(`${basePath}/transactions`); + cy.wait('@txs'); cy.waitForSkeletonGone(); cy.get('#filter').click(); cy.contains(filter).find('input').click(); - //TODO: change this waiter - cy.wait(1000); + cy.wait('@txs'); + cy.wait(500); cy.get('td:nth-of-type(2)').each(($td) => { expect($td.text().trim()).to.eq(filter); }); @@ -56,7 +57,7 @@ describe('Bisq', () => { filters.forEach((filter) => { cy.contains(filter).find('input').click(); //TODO: change this waiter - cy.wait(1000); + cy.wait(1500); }); cy.get('td:nth-of-type(2)').each(($td) => { const regex = new RegExp(`${filters.join('|')}`, 'g'); diff --git a/frontend/cypress/integration/liquid/liquid.spec.ts b/frontend/cypress/e2e/liquid/liquid.spec.ts similarity index 98% rename from frontend/cypress/integration/liquid/liquid.spec.ts rename to frontend/cypress/e2e/liquid/liquid.spec.ts index 732afa261..1e7c4649d 100644 --- a/frontend/cypress/integration/liquid/liquid.spec.ts +++ b/frontend/cypress/e2e/liquid/liquid.spec.ts @@ -124,7 +124,7 @@ describe('Liquid', () => { cy.visit(`${basePath}/assets`); cy.waitForSkeletonGone(); cy.get('.container-xl input').click().type('Liquid Bitcoin').then(() => { - cy.get('ngb-typeahead-window').should('have.length', 1); + cy.get('ngb-typeahead-window', { timeout: 30000 }).should('have.length', 1); }); }); @@ -132,7 +132,7 @@ describe('Liquid', () => { cy.visit(`${basePath}/assets`); cy.waitForSkeletonGone(); cy.get('.container-xl input').click().type('Liquid AUD').then(() => { - cy.get('ngb-typeahead-window:nth-of-type(1) button').click(); + cy.get('ngb-typeahead-window:nth-of-type(1) button', { timeout: 30000 }).click(); }); }); }); diff --git a/frontend/cypress/integration/liquidtestnet/liquidtestnet.spec.ts b/frontend/cypress/e2e/liquidtestnet/liquidtestnet.spec.ts similarity index 100% rename from frontend/cypress/integration/liquidtestnet/liquidtestnet.spec.ts rename to frontend/cypress/e2e/liquidtestnet/liquidtestnet.spec.ts diff --git a/frontend/cypress/integration/mainnet/mainnet.spec.ts b/frontend/cypress/e2e/mainnet/mainnet.spec.ts similarity index 99% rename from frontend/cypress/integration/mainnet/mainnet.spec.ts rename to frontend/cypress/e2e/mainnet/mainnet.spec.ts index c3d5d803c..400e09605 100644 --- a/frontend/cypress/integration/mainnet/mainnet.spec.ts +++ b/frontend/cypress/e2e/mainnet/mainnet.spec.ts @@ -189,7 +189,7 @@ describe('Mainnet', () => { cy.get('[data-cy="tx-2"] .table-tx-vin .highlight').invoke('text').should('contain', `${address}`); }); - it.only('highlights both input and output addresses in the same transaction', () => { + it('highlights both input and output addresses in the same transaction', () => { const address = 'bc1q03u63r6hm7a3v6em58zdqtp446w2pw30nm63mv'; cy.visit(`/address/${address}`); cy.waitForSkeletonGone(); @@ -241,7 +241,7 @@ describe('Mainnet', () => { cy.get('[ngbtooltip="Next Block"] > .ng-fa-icon > .svg-inline--fa').should('not.exist'); cy.get('[ngbtooltip="Previous Block"] > .ng-fa-icon > .svg-inline--fa').should('be.visible'); cy.document().left(); - cy.get('.title-block h1').invoke('text').should('equal', 'Next block'); + cy.get('.title-block h1').invoke('text').should('equal', 'Next Block'); }); }); diff --git a/frontend/cypress/integration/signet/signet.spec.ts b/frontend/cypress/e2e/signet/signet.spec.ts similarity index 100% rename from frontend/cypress/integration/signet/signet.spec.ts rename to frontend/cypress/e2e/signet/signet.spec.ts diff --git a/frontend/cypress/integration/testnet/testnet.spec.ts b/frontend/cypress/e2e/testnet/testnet.spec.ts similarity index 100% rename from frontend/cypress/integration/testnet/testnet.spec.ts rename to frontend/cypress/e2e/testnet/testnet.spec.ts diff --git a/frontend/cypress/support/commands.ts b/frontend/cypress/support/commands.ts index ea5e88996..0d698fca5 100644 --- a/frontend/cypress/support/commands.ts +++ b/frontend/cypress/support/commands.ts @@ -50,98 +50,98 @@ import { mockWebSocket } from './websocket'; /* global Cypress */ const codes = { - ArrowLeft: 37, - ArrowUp: 38, - ArrowRight: 39, - ArrowDown: 40 + ArrowLeft: 37, + ArrowUp: 38, + ArrowRight: 39, + ArrowDown: 40 } Cypress.Commands.add('waitForSkeletonGone', () => { - cy.waitUntil(() => { - return Cypress.$('.skeleton-loader').length === 0; - }, { verbose: true, description: "waitForSkeletonGone", errorMsg: "skeleton loaders never went away", timeout: 15000, interval: 50}); + cy.waitUntil(() => { + return Cypress.$('.skeleton-loader').length === 0; + }, { verbose: true, description: "waitForSkeletonGone", errorMsg: "skeleton loaders never went away", timeout: 15000, interval: 50 }); }); Cypress.Commands.add( - "waitForPageIdle", - () => { - console.warn("Waiting for page idle state"); - const pageIdleDetector = new PageIdleDetector(); - pageIdleDetector.WaitForPageToBeIdle(); - } + "waitForPageIdle", + () => { + console.warn("Waiting for page idle state"); + const pageIdleDetector = new PageIdleDetector(); + pageIdleDetector.WaitForPageToBeIdle(); + } ); Cypress.Commands.add('mockMempoolSocket', () => { mockWebSocket(); }); -Cypress.Commands.add('changeNetwork', (network: "testnet"|"signet"|"liquid"|"bisq"|"mainnet" ) => { - cy.get('.dropdown-toggle').click().then(() => { - cy.get(`.${network}`).click().then(() => { - cy.waitForPageIdle(); - if(network !== 'bisq'){ - cy.waitForSkeletonGone(); - } - }); +Cypress.Commands.add('changeNetwork', (network: "testnet" | "signet" | "liquid" | "bisq" | "mainnet") => { + cy.get('.dropdown-toggle').click().then(() => { + cy.get(`a.${network}`).click().then(() => { + cy.waitForPageIdle(); + if (network !== 'bisq') { + cy.waitForSkeletonGone(); + } }); + }); }); // https://github.com/bahmutov/cypress-arrows/blob/8f0303842a343550fbeaf01528d01d1ff213b70c/src/index.js -function keydownCommand ($el, key) { - const message = `sending the "${key}" keydown event` - const log = Cypress.log({ - name: `keydown: ${key}`, - message: message, - consoleProps: function () { - return { - Subject: $el - } +function keydownCommand($el, key) { + const message = `sending the "${key}" keydown event` + const log = Cypress.log({ + name: `keydown: ${key}`, + message: message, + consoleProps: function () { + return { + Subject: $el } - }) - - const e = $el.createEvent('KeyboardEvent') - - Object.defineProperty(e, 'key', { - get: function () { - return key - } - }) - - Object.defineProperty(e, 'keyCode', { - get: function () { - return this.keyCodeVal - } - }) - Object.defineProperty(e, 'which', { - get: function () { - return this.keyCodeVal - } - }) - var metaKey = false - - Object.defineProperty(e, 'metaKey', { - get: function () { - return metaKey - } - }) - - Object.defineProperty(e, 'shiftKey', { - get: function () { - return false - } - }) - e.keyCodeVal = codes[key] - - e.initKeyboardEvent('keydown', true, true, - $el.defaultView, false, false, false, false, e.keyCodeVal, e.keyCodeVal) - - $el.dispatchEvent(e) - log.snapshot().end() - return $el - } - - Cypress.Commands.add('keydown', { prevSubject: "dom" }, keydownCommand) - Cypress.Commands.add('left', { prevSubject: "dom" }, $el => keydownCommand($el, 'ArrowLeft')) - Cypress.Commands.add('right', { prevSubject: "dom" }, $el => keydownCommand($el, 'ArrowRight')) - Cypress.Commands.add('up', { prevSubject: "dom" }, $el => keydownCommand($el, 'ArrowUp')) - Cypress.Commands.add('down', { prevSubject: "dom" }, $el => keydownCommand($el, 'ArrowDown')) \ No newline at end of file + } + }) + + const e = $el.createEvent('KeyboardEvent') + + Object.defineProperty(e, 'key', { + get: function () { + return key + } + }) + + Object.defineProperty(e, 'keyCode', { + get: function () { + return this.keyCodeVal + } + }) + Object.defineProperty(e, 'which', { + get: function () { + return this.keyCodeVal + } + }) + var metaKey = false + + Object.defineProperty(e, 'metaKey', { + get: function () { + return metaKey + } + }) + + Object.defineProperty(e, 'shiftKey', { + get: function () { + return false + } + }) + e.keyCodeVal = codes[key] + + e.initKeyboardEvent('keydown', true, true, + $el.defaultView, false, false, false, false, e.keyCodeVal, e.keyCodeVal) + + $el.dispatchEvent(e) + log.snapshot().end() + return $el +} + +Cypress.Commands.add('keydown', { prevSubject: "dom" }, keydownCommand) +Cypress.Commands.add('left', { prevSubject: "dom" }, $el => keydownCommand($el, 'ArrowLeft')) +Cypress.Commands.add('right', { prevSubject: "dom" }, $el => keydownCommand($el, 'ArrowRight')) +Cypress.Commands.add('up', { prevSubject: "dom" }, $el => keydownCommand($el, 'ArrowUp')) +Cypress.Commands.add('down', { prevSubject: "dom" }, $el => keydownCommand($el, 'ArrowDown')) diff --git a/frontend/cypress/support/index.ts b/frontend/cypress/support/e2e.ts similarity index 100% rename from frontend/cypress/support/index.ts rename to frontend/cypress/support/e2e.ts diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9abadc0eb..6a0742c46 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -70,7 +70,7 @@ }, "optionalDependencies": { "@cypress/schematic": "^1.3.0", - "cypress": "^9.6.1", + "cypress": "^10.0.2", "cypress-fail-on-console-error": "^2.1.3", "cypress-wait-until": "^1.7.1", "mock-socket": "^9.0.3", @@ -6901,9 +6901,9 @@ "devOptional": true }, "node_modules/cypress": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.6.1.tgz", - "integrity": "sha512-ECzmV7pJSkk+NuAhEw6C3D+RIRATkSb2VAHXDY6qGZbca/F9mv5pPsj2LO6Ty6oIFVBTrwCyL9agl28MtJMe2g==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.0.2.tgz", + "integrity": "sha512-7+C4KHYBcfZrawss+Gt5PlS35rfc6ySc59JcHDVsIMm1E/J35dqE41UEXpdtwIq3549umCerNWnFADzqib4kcA==", "hasInstallScript": true, "optional": true, "dependencies": { @@ -22471,9 +22471,9 @@ "devOptional": true }, "cypress": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.6.1.tgz", - "integrity": "sha512-ECzmV7pJSkk+NuAhEw6C3D+RIRATkSb2VAHXDY6qGZbca/F9mv5pPsj2LO6Ty6oIFVBTrwCyL9agl28MtJMe2g==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.0.2.tgz", + "integrity": "sha512-7+C4KHYBcfZrawss+Gt5PlS35rfc6ySc59JcHDVsIMm1E/J35dqE41UEXpdtwIq3549umCerNWnFADzqib4kcA==", "optional": true, "requires": { "@cypress/request": "^2.88.10", diff --git a/frontend/package.json b/frontend/package.json index f20f498df..e3166f181 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -122,7 +122,7 @@ }, "optionalDependencies": { "@cypress/schematic": "^1.3.0", - "cypress": "^9.6.1", + "cypress": "^10.0.2", "cypress-fail-on-console-error": "^2.1.3", "cypress-wait-until": "^1.7.1", "mock-socket": "^9.0.3", diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.ts b/frontend/src/app/components/blocks-list/blocks-list.component.ts index 07b80a562..c565e9e30 100644 --- a/frontend/src/app/components/blocks-list/blocks-list.component.ts +++ b/frontend/src/app/components/blocks-list/blocks-list.component.ts @@ -80,7 +80,7 @@ export class BlocksList implements OnInit { this.stateService.blocks$ .pipe( switchMap((block) => { - if (block[0].height <= this.lastBlockHeight) { + if (block[0].height < this.lastBlockHeight) { return []; // Return an empty stream so the last pipe is not executed } this.lastBlockHeight = block[0].height; diff --git a/frontend/src/app/components/svg-images/svg-images.component.html b/frontend/src/app/components/svg-images/svg-images.component.html index e64d7ecc9..56762397f 100644 --- a/frontend/src/app/components/svg-images/svg-images.component.html +++ b/frontend/src/app/components/svg-images/svg-images.component.html @@ -15,10 +15,10 @@ - + - + diff --git a/frontend/src/app/components/svg-images/svg-images.component.ts b/frontend/src/app/components/svg-images/svg-images.component.ts index ee2de825f..287243202 100644 --- a/frontend/src/app/components/svg-images/svg-images.component.ts +++ b/frontend/src/app/components/svg-images/svg-images.component.ts @@ -6,6 +6,7 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class SvgImagesComponent { + randomId = Math.floor(Math.random() * 10000); @Input() name: string; @Input() class: string; @Input() style: string;