diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a29e9184..6d2fc387f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -251,17 +251,7 @@ jobs: strategy: fail-fast: false matrix: - module: ["mempool", "liquid"] - include: - - module: "mempool" - spec: | - cypress/e2e/mainnet/*.spec.ts - cypress/e2e/signet/*.spec.ts - cypress/e2e/testnet4/*.spec.ts - - module: "liquid" - spec: | - cypress/e2e/liquid/liquid.spec.ts - cypress/e2e/liquidtestnet/liquidtestnet.spec.ts + module: ["mempool", "liquid", "testnet4"] name: E2E tests for ${{ matrix.module }} steps: @@ -310,8 +300,10 @@ jobs: - name: Unzip assets before building (src/resources) run: unzip -o promo-video-assets.zip -d ${{ matrix.module }}/frontend/src/resources/promo-video - + + # mempool - name: Chrome browser tests (${{ matrix.module }}) + if: ${{ matrix.module == 'mempool' }} uses: cypress-io/github-action@v5 with: tag: ${{ github.event_name }} @@ -322,7 +314,9 @@ jobs: wait-on-timeout: 120 record: true parallel: true - spec: ${{ matrix.spec }} + spec: | + cypress/e2e/mainnet/*.spec.ts + cypress/e2e/signet/*.spec.ts group: Tests on Chrome (${{ matrix.module }}) browser: "chrome" ci-build-id: "${{ github.sha }}-${{ github.workflow }}-${{ github.event_name }}" @@ -332,6 +326,56 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} + # liquid + - name: Chrome browser tests (${{ matrix.module }}) + if: ${{ matrix.module == 'liquid' }} + uses: cypress-io/github-action@v5 + with: + tag: ${{ github.event_name }} + working-directory: ${{ matrix.module }}/frontend + build: npm run config:defaults:${{ matrix.module }} + start: npm run start:local-staging + wait-on: "http://localhost:4200" + wait-on-timeout: 120 + record: true + parallel: true + spec: | + cypress/e2e/liquid/liquid.spec.ts + cypress/e2e/liquidtestnet/liquidtestnet.spec.ts + group: Tests on Chrome (${{ matrix.module }}) + browser: "chrome" + ci-build-id: "${{ github.sha }}-${{ github.workflow }}-${{ github.event_name }}" + env: + COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }} + CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} + + # testnet + - name: Chrome browser tests (${{ matrix.module }}) + if: ${{ matrix.module == 'testnet4' }} + uses: cypress-io/github-action@v5 + with: + tag: ${{ github.event_name }} + working-directory: ${{ matrix.module }}/frontend + build: npm run config:defaults:mempool + start: npm run start:local-staging + wait-on: "http://localhost:4200" + wait-on-timeout: 120 + record: true + parallel: true + spec: | + cypress/e2e/testnet4/*.spec.ts + group: Tests on Chrome (${{ matrix.module }}) + browser: "chrome" + ci-build-id: "${{ github.sha }}-${{ github.workflow }}-${{ github.event_name }}" + env: + CYPRESS_REROUTE_TESTNET: true + COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }} + CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} + validate_docker_json: if: "!contains(github.event.pull_request.labels.*.name, 'ops') && !contains(github.head_ref, 'ops/')" runs-on: "ubuntu-latest" @@ -359,4 +403,4 @@ jobs: - name: Validate JSON syntax run: | cat mempool-config.json | jq - working-directory: docker/docker/backend + working-directory: docker/docker/backend \ No newline at end of file diff --git a/frontend/cypress/e2e/mainnet/mainnet.spec.ts b/frontend/cypress/e2e/mainnet/mainnet.spec.ts index a1082b769..7e17c09cd 100644 --- a/frontend/cypress/e2e/mainnet/mainnet.spec.ts +++ b/frontend/cypress/e2e/mainnet/mainnet.spec.ts @@ -344,7 +344,9 @@ describe('Mainnet', () => { cy.visit('/'); cy.waitForSkeletonGone(); - cy.changeNetwork('testnet4'); + //TODO(knorrium): add a check for the proxied server + // cy.changeNetwork('testnet4'); + cy.changeNetwork('signet'); cy.changeNetwork('mainnet'); }); diff --git a/frontend/proxy.conf.staging.js b/frontend/proxy.conf.staging.js index e24662038..260b222c0 100644 --- a/frontend/proxy.conf.staging.js +++ b/frontend/proxy.conf.staging.js @@ -3,8 +3,10 @@ const fs = require('fs'); let PROXY_CONFIG = require('./proxy.conf'); PROXY_CONFIG.forEach(entry => { - entry.target = entry.target.replace("mempool.space", "mempool-staging.fra.mempool.space"); - entry.target = entry.target.replace("liquid.network", "liquid-staging.fra.mempool.space"); + const hostname = process.env.CYPRESS_REROUTE_TESTNET === 'true' ? 'mempool-staging.fra.mempool.space' : 'node201.fmt.mempool.space'; + console.log(`e2e tests running against ${hostname}`); + entry.target = entry.target.replace("mempool.space", hostname); + entry.target = entry.target.replace("liquid.network", "liquid-staging.fmt.mempool.space"); }); module.exports = PROXY_CONFIG; diff --git a/frontend/src/app/components/stratum/stratum-list/stratum-list.component.ts b/frontend/src/app/components/stratum/stratum-list/stratum-list.component.ts index 0af9f0976..6f252babe 100644 --- a/frontend/src/app/components/stratum/stratum-list/stratum-list.component.ts +++ b/frontend/src/app/components/stratum/stratum-list/stratum-list.component.ts @@ -8,8 +8,10 @@ import { SinglePoolStats } from '../../../interfaces/node-api.interface'; type MerkleCellType = ' ' | '┬' | '├' | '└' | '│' | '─' | 'leaf'; + interface TaggedStratumJob extends StratumJob { tag: string; + merkleBranchIds: string[]; } interface MerkleCell { @@ -46,6 +48,18 @@ function parseTag(scriptSig: string): string { return (ascii.match(/\/.*\//)?.[0] || ascii).trim(); } +function getMerkleBranchIds(merkleBranches: string[], numBranches: number): string[] { + let lastHash = ''; + const ids: string[] = []; + for (let i = 0; i < numBranches; i++) { + if (merkleBranches[i]) { + lastHash = merkleBranches[i]; + } + ids.push(`${i}-${lastHash}`); + } + return ids; +} + @Component({ selector: 'app-stratum-list', templateUrl: './stratum-list.component.html', @@ -81,16 +95,15 @@ export class StratumList implements OnInit, OnDestroy { } processJobs(rawJobs: Record): PoolRow[] { + const numBranches = Math.max(...Object.values(rawJobs).map(job => job.merkleBranches.length)); const jobs: Record = {}; for (const [id, job] of Object.entries(rawJobs)) { - jobs[id] = { ...job, tag: parseTag(job.scriptsig) }; + jobs[id] = { ...job, tag: parseTag(job.scriptsig), merkleBranchIds: getMerkleBranchIds(job.merkleBranches, numBranches) }; } if (Object.keys(jobs).length === 0) { return []; } - const numBranches = Math.max(...Object.values(jobs).map(job => job.merkleBranches.length)); - let trees: MerkleTree[] = Object.keys(jobs).map(job => ({ job, size: 1, @@ -100,12 +113,13 @@ export class StratumList implements OnInit, OnDestroy { for (let col = numBranches - 1; col >= 0; col--) { const groups: Record = {}; for (const tree of trees) { - const hash = jobs[tree.job].merkleBranches[col]; - if (!groups[hash]) { - groups[hash] = []; + const branchId = jobs[tree.job].merkleBranchIds[col]; + if (!groups[branchId]) { + groups[branchId] = []; } - groups[hash].push(tree); + groups[branchId].push(tree); } + trees = Object.values(groups).map(group => ({ hash: jobs[group[0].job].merkleBranches[col], job: group[0].job, diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts index e78e74a9c..153b3dc1b 100644 --- a/frontend/src/app/shared/shared.module.ts +++ b/frontend/src/app/shared/shared.module.ts @@ -7,7 +7,7 @@ import { faFilter, faAngleDown, faAngleUp, faAngleRight, faAngleLeft, faBolt, fa faFileAlt, faRedoAlt, faArrowAltCircleRight, faExternalLinkAlt, faBook, faListUl, faDownload, faQrcode, faArrowRightArrowLeft, faArrowsRotate, faCircleLeft, faFastForward, faWallet, faUserClock, faWrench, faUserFriends, faQuestionCircle, faHistory, faSignOutAlt, faKey, faSuitcase, faIdCardAlt, faNetworkWired, faUserCheck, faCircleCheck, faUserCircle, faCheck, faRocket, faScaleBalanced, faHourglassStart, faHourglassHalf, faHourglassEnd, faWandMagicSparkles, faFaucetDrip, faTimeline, - faCircleXmark, faCalendarCheck, faMoneyBillTrendUp, faRobot, faCreditCard } from '@fortawesome/free-solid-svg-icons'; + faCircleXmark, faCalendarCheck, faMoneyBillTrendUp, faRobot, faShareNodes, faCreditCard } from '@fortawesome/free-solid-svg-icons'; import { InfiniteScrollModule } from 'ngx-infinite-scroll'; import { MenuComponent } from '@components/menu/menu.component'; import { PreviewTitleComponent } from '@components/master-page-preview/preview-title.component'; @@ -459,6 +459,7 @@ export class SharedModule { library.addIcons(faCalendarCheck); library.addIcons(faMoneyBillTrendUp); library.addIcons(faRobot); + library.addIcons(faShareNodes); library.addIcons(faCreditCard); } }