From 7fd04be6846a96bd1709e2dcef62c7344a41599d Mon Sep 17 00:00:00 2001 From: Martin Vere Cihlar Date: Tue, 10 Dec 2024 14:46:56 +0100 Subject: [PATCH] Convert suite settings (coins, custom-firmware) + refactors desktop pipeline (#15869) * feat(e2e): Convert coins.test.ts from cy to pw minor refactoring some verification commented out and will be part of future refactoring * feat(e2e): Convert cy test file custom-firmware.test.ts to PW * fix(e2e): Stabilizing new pw tests for desktop adds logic to use correct API url based on web/desktop/local/CI removes flakyness of Coins test * refactor(e2e): #15868 Refactor desktop e2e test pipeline better matrix move docker pull from tests step to improve readability pull only what is need Attach playwright report for devs who dont have currents add --forbid-only to both pipelines * fix(e2e): Fix start and name of electron-regtest --- .github/workflows/test-suite-desktop-e2e.yml | 81 ++++++----- .github/workflows/test-suite-web-e2e-pw.yml | 27 ++-- .../e2e/fixtures/trezor-2.5.1.bin | Bin .../e2e/playwright.config.ts | 6 +- .../suite-desktop-core/e2e/support/common.ts | 15 +- .../e2e/support/customMatchers.ts | 26 ++++ .../e2e/support/fixtures.ts | 9 +- .../support/pageActions/settingsActions.ts | 10 +- .../e2e/tests/settings/coins.test.ts | 112 +++++++++++++++ .../tests/settings/custom-firmware.test.ts | 35 +++++ .../settings/t2b1-device-settings.test.ts | 4 +- .../e2e/tests/settings/coins.test.ts | 133 ------------------ .../tests/settings/custom-firmware.test.ts | 64 --------- .../firmware/SelectCustomFirmware.tsx | 11 +- 14 files changed, 270 insertions(+), 263 deletions(-) rename packages/{suite-web => suite-desktop-core}/e2e/fixtures/trezor-2.5.1.bin (100%) create mode 100644 packages/suite-desktop-core/e2e/support/customMatchers.ts create mode 100644 packages/suite-desktop-core/e2e/tests/settings/coins.test.ts create mode 100644 packages/suite-desktop-core/e2e/tests/settings/custom-firmware.test.ts delete mode 100644 packages/suite-web/e2e/tests/settings/coins.test.ts delete mode 100644 packages/suite-web/e2e/tests/settings/custom-firmware.test.ts diff --git a/.github/workflows/test-suite-desktop-e2e.yml b/.github/workflows/test-suite-desktop-e2e.yml index bd76b541cec..49d9bc376d3 100644 --- a/.github/workflows/test-suite-desktop-e2e.yml +++ b/.github/workflows/test-suite-desktop-e2e.yml @@ -27,10 +27,20 @@ jobs: fail-fast: false matrix: include: - - TEST_FILE: "spawn-bridge spawn-bridge-daemon suite-guide wallet-discovery" - CONTAINERS: "trezor-user-env-unix" - - TEST_FILE: "electrum" + # - TEST_GROUP: "@group=suite" + # CONTAINERS: "trezor-user-env-unix" + # - TEST_GROUP: "@group=device-management" + # CONTAINERS: "trezor-user-env-unix" + - TEST_GROUP: "@group=settings" CONTAINERS: "trezor-user-env-unix electrum-regtest" + # - TEST_GROUP: "@group=metadata" + # CONTAINERS: "trezor-user-env-unix" + # - TEST_GROUP: "@group=passphrase" + # CONTAINERS: "trezor-user-env-unix" + # - TEST_GROUP: "@group=other" + # CONTAINERS: "trezor-user-env-unix" + - TEST_GROUP: "@group=wallet" + CONTAINERS: "trezor-user-env-unix" steps: - name: Checkout @@ -38,67 +48,66 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha }} - - name: Run and store git values for Currents - run: | - echo "COMMIT_MESSAGE=$(git show -s --pretty=%s)" >> $GITHUB_ENV - echo "COMMIT_EMAIL=$(git show -s --pretty=%ae)" >> $GITHUB_ENV - echo "COMMIT_AUTHOR=$(git show -s --pretty=%an)" >> $GITHUB_ENV - echo "COMMIT_SHA=$(git show -s --pretty=%H)" >> $GITHUB_ENV - echo "COMMIT_TIMESTAMP=$(git show -s --pretty=%ct)" >> $GITHUB_ENV - - name: Setup node uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: yarn - - name: Install deps and build libs + - name: Install dependencies, build libs and pull docker images + env: + COMPOSE_FILE: ./docker/docker-compose.suite-desktop-ci.yml run: | yarn install --immutable yarn message-system-sign-config yarn workspace @trezor/suite-data build:lib yarn workspace @trezor/transport-bridge build:lib + docker compose pull ${{ matrix.CONTAINERS }} - - name: Build app.js for tests + - name: Build electron app.js for tests run: | yarn workspace @trezor/suite-desktop build:app yarn workspace @trezor/suite-desktop build:ui - - name: Run e2e desktop tests + - name: Run Playwright e2e desktop tests env: - GITHUB_WORKFLOW: ${{github.workflow}} + COMPOSE_FILE: ./docker/docker-compose.suite-desktop-ci.yml GITHUB_ACTION: true - GITHUB_EVENT_NAME: ${{github.event_name}} - GITHUB_RUN_ID: ${{github.run_id}} - GITHUB_RUN_ATTEMPT: ${{github.run_attempt}} - GITHUB_REPOSITORY: ${{github.repository}} - COMMIT_INFO_BRANCH: ${{github.head_ref}} - COMMIT_INFO_MESSAGE: ${{env.COMMIT_MESSAGE}} - COMMIT_INFO_EMAIL: ${{env.COMMIT_EMAIL}} - COMMIT_INFO_AUTHOR: ${{env.COMMIT_AUTHOR}} - COMMIT_INFO_SHA: ${{env.COMMIT_SHA}} - COMMIT_INFO_TIMESTAMP: ${{env.COMMIT_TIMESTAMP}} - COMMIT_INFO_REMOTE: ${{github.repository}} CURRENTS_PROJECT_ID: 4ytF0E CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }} CURRENTS_CI_BUILD_ID: pr-run-${{github.run_id}} - COMPOSE_FILE: ./docker/docker-compose.suite-desktop-ci.yml - TEST_FILE: ${{ matrix.TEST_FILE }} run: | - docker compose pull docker compose up -d ${{ matrix.CONTAINERS }} - yarn workspace @trezor/suite-desktop-core test:e2e:desktop ${{ env.TEST_FILE }} + echo "Starting Playwright Desktop test group ${{ matrix.TEST_GROUP }}" + yarn workspace @trezor/suite-desktop-core test:e2e:desktop --forbid-only --grep=${{ matrix.TEST_GROUP }} - - name: cleanup + - name: Extract Trezor-user-env logs + if: ${{ ! cancelled() }} + run: | + docker cp docker-trezor-user-env-unix-1:/trezor-user-env/logs/debugging.log trezor-user-env-debugging.log || true + docker cp docker-trezor-user-env-unix-1:/trezor-user-env/logs/emulator_bridge.log tenv-emulator-bridge-debugging.log || true + docker cp docker-trezor-user-env-unix-1:/trezor-user-env/docker/version.txt trezor-user-env-version.txt || true + + - name: Upload Trezor-user-env logs + if: ${{ ! cancelled() }} + uses: actions/upload-artifact@v4 + with: + name: emulator-logs-${{ matrix.TEST_GROUP }} + path: | + trezor-user-env-debugging.log + tenv-emulator-bridge-debugging.log + trezor-user-env-version.txt + retention-days: 30 + + - name: Docker compose down env: COMPOSE_FILE: ./docker/docker-compose.suite-desktop-ci.yml run: docker compose down - # TODO: currently only uploads trace.zip, figure out why screens are not uploaded - - name: Upload artifacts + - name: Upload Playwright report if: ${{ ! cancelled() }} uses: actions/upload-artifact@v4 with: - name: test-artifacts-${{ matrix.TEST_FILE }} - path: | - ./packages/suite-desktop-core/e2e/test-results + name: playwright-report-${{ matrix.TEST_GROUP }} + path: ./packages/suite-desktop-core/playwright-report/ + retention-days: 30 diff --git a/.github/workflows/test-suite-web-e2e-pw.yml b/.github/workflows/test-suite-web-e2e-pw.yml index 67010647fa7..5c14ba1f5e9 100644 --- a/.github/workflows/test-suite-web-e2e-pw.yml +++ b/.github/workflows/test-suite-web-e2e-pw.yml @@ -107,12 +107,14 @@ jobs: # CONTAINERS: "trezor-user-env-unix" - TEST_GROUP: "@group=wallet" CONTAINERS: "trezor-user-env-unix bitcoin-regtest" + steps: - name: Checkout uses: actions/checkout@v4 with: ref: ${{github.event.after}} fetch-depth: 2 + - name: Setup node uses: actions/setup-node@v4 with: @@ -124,16 +126,6 @@ jobs: run: | echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT - - name: Extract commit message - id: extract_commit_message - run: | - if [ "${{ github.event_name }}" == "pull_request" ]; then - git fetch origin +refs/pull/${{ github.event.pull_request.number }}/merge: --depth=1 - echo "message=$(git log --no-merges -1 --pretty=format:"%s")" >> $GITHUB_OUTPUT - else - echo "message=$(git log --no-merges -1 --pretty=format:"%s")" >> $GITHUB_OUTPUT - fi - - name: Install dependencies and pull docker images env: COMPOSE_FILE: ./docker/docker-compose.suite-ci-pw.yml @@ -144,21 +136,18 @@ jobs: npx playwright install --with-deps chromium docker compose pull ${{ matrix.CONTAINERS }} - - name: Run Playwright e2e tests + - name: Run Playwright e2e web tests env: COMPOSE_FILE: ./docker/docker-compose.suite-ci-pw.yml BASE_URL: https://dev.suite.sldev.cz/suite-web/${{ steps.extract_branch.outputs.branch }}/web/ - ## Keep retries enabled once stabilized - ALLOW_RETRY: true - TEST_GROUP: ${{ matrix.TEST_GROUP }} GITHUB_ACTION: true CURRENTS_PROJECT_ID: Og0NOQ CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }} CURRENTS_CI_BUILD_ID: pr-run-${{github.run_id}} run: | docker compose up -d ${{ matrix.CONTAINERS }} - echo "Starting Playwright Web test group ${TEST_GROUP}" - yarn workspace @trezor/suite-desktop-core test:e2e:web --grep=${TEST_GROUP} + echo "Starting Playwright Web test group ${{ matrix.TEST_GROUP }}" + yarn workspace @trezor/suite-desktop-core test:e2e:web --forbid-only --grep=${{ matrix.TEST_GROUP }} - name: Extract Trezor-user-env logs if: ${{ ! cancelled() }} @@ -176,6 +165,12 @@ jobs: trezor-user-env-debugging.log tenv-emulator-bridge-debugging.log trezor-user-env-version.txt + retention-days: 30 + + - name: Docker compose down + env: + COMPOSE_FILE: ./docker/docker-compose.suite-ci-pw.yml + run: docker compose down - name: Upload Playwright report if: ${{ ! cancelled() }} diff --git a/packages/suite-web/e2e/fixtures/trezor-2.5.1.bin b/packages/suite-desktop-core/e2e/fixtures/trezor-2.5.1.bin similarity index 100% rename from packages/suite-web/e2e/fixtures/trezor-2.5.1.bin rename to packages/suite-desktop-core/e2e/fixtures/trezor-2.5.1.bin diff --git a/packages/suite-desktop-core/e2e/playwright.config.ts b/packages/suite-desktop-core/e2e/playwright.config.ts index 80bc55de55b..7c634ae0e9c 100644 --- a/packages/suite-desktop-core/e2e/playwright.config.ts +++ b/packages/suite-desktop-core/e2e/playwright.config.ts @@ -5,6 +5,8 @@ export enum PlaywrightProjects { Web = 'web', Desktop = 'desktop', } +const timeoutCIRun = 1000 * 60; +const timeoutLocalRun = 1000 * 30; const config: PlaywrightTestConfig = { projects: [ @@ -12,7 +14,7 @@ const config: PlaywrightTestConfig = { name: PlaywrightProjects.Web, use: { browserName: 'chromium', - baseURL: process.env.BASE_URL || 'http://localhost:8000', + baseURL: process.env.BASE_URL || 'http://localhost:8000/', }, grepInvert: /@desktopOnly/, }, @@ -34,7 +36,7 @@ const config: PlaywrightTestConfig = { reporter: process.env.GITHUB_ACTION ? [['list'], ['@currents/playwright'], ['html', { open: 'never' }]] : [['list'], ['html', { open: 'never' }]], - timeout: 1000 * 60 * 5, + timeout: process.env.GITHUB_ACTION ? timeoutCIRun : timeoutLocalRun, outputDir: path.join(__dirname, 'test-results'), }; diff --git a/packages/suite-desktop-core/e2e/support/common.ts b/packages/suite-desktop-core/e2e/support/common.ts index 92bce7f1090..52f7e210d3d 100644 --- a/packages/suite-desktop-core/e2e/support/common.ts +++ b/packages/suite-desktop-core/e2e/support/common.ts @@ -1,11 +1,13 @@ /* eslint-disable no-console */ -import { _electron as electron } from '@playwright/test'; +import { _electron as electron, TestInfo } from '@playwright/test'; import path from 'path'; import fse from 'fs-extra'; import { TrezorUserEnvLink } from '@trezor/trezor-user-env-link'; +import { PlaywrightProjects } from '../playwright.config'; + // specific version of legacy bridge is requested & expected export const LEGACY_BRIDGE_VERSION = '2.0.33'; const disableHashCheckArgument = '--state.suite.settings.isFirmwareHashCheckDisabled=true'; @@ -100,3 +102,14 @@ export const launchSuite = async (params: LaunchSuiteParams = {}) => { return { electronApp, window }; }; + +export const getApiUrl = (webBaseUrl: string | undefined, testInfo: TestInfo) => { + const electronApiURL = 'file:///'; + const apiURL = + testInfo.project.name === PlaywrightProjects.Desktop ? electronApiURL : webBaseUrl; + if (!apiURL) { + throw new Error('apiURL is not defined'); + } + + return apiURL; +}; diff --git a/packages/suite-desktop-core/e2e/support/customMatchers.ts b/packages/suite-desktop-core/e2e/support/customMatchers.ts new file mode 100644 index 00000000000..c42b8456e53 --- /dev/null +++ b/packages/suite-desktop-core/e2e/support/customMatchers.ts @@ -0,0 +1,26 @@ +import { Locator, expect as baseExpect } from '@playwright/test'; + +export const expect = baseExpect.extend({ + async toBeEnabledCoin(locator: Locator) { + const isActive = await locator.getAttribute('data-active'); + + return { + pass: isActive === 'true', + message: () => + isActive === null + ? `expected ${locator} to have attribute 'data-active', but it does not have this attribute at all` + : `expected ${locator} to have attribute 'data-active' set to 'true', but got '${isActive}'`, + }; + }, + async toBeDisabledCoin(locator: Locator) { + const isActive = await locator.getAttribute('data-active'); + + return { + pass: isActive === 'false', + message: () => + isActive === null + ? `expected ${locator} to have attribute 'data-active', but it does not have this attribute at all` + : `expected ${locator} to have attribute 'data-active' set to 'false', but got '${isActive}'`, + }; + }, +}); diff --git a/packages/suite-desktop-core/e2e/support/fixtures.ts b/packages/suite-desktop-core/e2e/support/fixtures.ts index 4500e15088c..11ca4ae10d5 100644 --- a/packages/suite-desktop-core/e2e/support/fixtures.ts +++ b/packages/suite-desktop-core/e2e/support/fixtures.ts @@ -1,5 +1,4 @@ /* eslint-disable react-hooks/rules-of-hooks */ - import { test as base, ElectronApplication, Page } from '@playwright/test'; import { @@ -10,7 +9,7 @@ import { } from '@trezor/trezor-user-env-link'; import { DashboardActions } from './pageActions/dashboardActions'; -import { launchSuite } from './common'; +import { getApiUrl, launchSuite } from './common'; import { SettingsActions } from './pageActions/settingsActions'; import { SuiteGuide } from './pageActions/suiteGuideActions'; import { WalletActions } from './pageActions/walletActions'; @@ -18,6 +17,7 @@ import { OnboardingActions } from './pageActions/onboardingActions'; import { PlaywrightProjects } from '../playwright.config'; type Fixtures = { + apiURL: string; startEmulator: boolean; emulatorStartConf: StartEmu; emulatorSetupConf: SetupEmu; @@ -35,6 +35,9 @@ const test = base.extend({ startEmulator: true, emulatorStartConf: {}, emulatorSetupConf: {}, + apiURL: async ({ baseURL }, use, testInfo) => { + await use(getApiUrl(baseURL, testInfo)); + }, /* eslint-disable-next-line no-empty-pattern */ trezorUserEnvLink: async ({}, use) => { await use(TrezorUserEnvLink); @@ -115,4 +118,4 @@ const test = base.extend({ }); export { test }; -export { expect } from '@playwright/test'; +export { expect } from './customMatchers'; diff --git a/packages/suite-desktop-core/e2e/support/pageActions/settingsActions.ts b/packages/suite-desktop-core/e2e/support/pageActions/settingsActions.ts index ccf20402d98..294efddc2c3 100644 --- a/packages/suite-desktop-core/e2e/support/pageActions/settingsActions.ts +++ b/packages/suite-desktop-core/e2e/support/pageActions/settingsActions.ts @@ -1,7 +1,9 @@ -import { expect, Locator, Page } from '@playwright/test'; +import { Locator, Page } from '@playwright/test'; import { BackendType, NetworkSymbol } from '@suite-common/wallet-config'; +import { expect } from '../customMatchers'; + export class SettingsActions { private readonly window: Page; private readonly TIMES_CLICK_TO_SET_DEBUG_MODE = 5; @@ -56,7 +58,7 @@ export class SettingsActions { async navigateTo() { await this.settingsMenuButton.click(); - await expect(this.settingsHeader).toHaveText('Settings'); + await expect(this.settingsHeader).toHaveText('Settings', { timeout: 10000 }); } async toggleDebugModeInSettings() { @@ -79,12 +81,12 @@ export class SettingsActions { async enableCoin(coin: NetworkSymbol) { await this.coinNetworkButton(coin).click(); - await expect(this.coinNetworkButton(coin)).toHaveAttribute('data-active', 'true'); + await expect(this.coinNetworkButton(coin)).toBeEnabledCoin(); } async disableCoin(coin: NetworkSymbol) { await this.coinNetworkButton(coin).click(); - await expect(this.coinNetworkButton(coin)).toHaveAttribute('data-active', 'false'); + await expect(this.coinNetworkButton(coin)).toBeDisabledCoin(); } async changeCoinBackend(backend: BackendType, backendUrl: string) { diff --git a/packages/suite-desktop-core/e2e/tests/settings/coins.test.ts b/packages/suite-desktop-core/e2e/tests/settings/coins.test.ts new file mode 100644 index 00000000000..07695d8879f --- /dev/null +++ b/packages/suite-desktop-core/e2e/tests/settings/coins.test.ts @@ -0,0 +1,112 @@ +import { SuiteAnalyticsEvent } from '@trezor/suite-analytics'; +import { Requests, EventPayload } from '@trezor/suite-web/e2e/support/types'; +import { urlSearchParams } from '@trezor/suite/src/utils/suite/metadata'; +import { NetworkSymbol } from '@suite-common/wallet-config'; + +import { test, expect } from '../../support/fixtures'; + +//TODO: #15811 To be refactored +export const findAnalyticsEventByType = ( + requests: Requests, + eventType: T['type'], +) => { + const event = requests.find(req => req.c_type === eventType) as EventPayload; + + if (!event) { + throw new Error(`Event with type ${eventType} not found.`); + } + + return event; +}; + +let requests: Requests; + +test.describe('Coin Settings', { tag: ['@group=settings'] }, () => { + test.use({ emulatorStartConf: { wipe: true } }); + test.beforeEach(async ({ onboardingPage, dashboardPage, settingsPage }) => { + await onboardingPage.completeOnboarding(); + await dashboardPage.discoveryShouldFinish(); + await settingsPage.navigateTo(); + await settingsPage.coinsTabButton.click(); + + requests = []; + + //TODO: #15811 To be refactored + await onboardingPage.window.route('**://data.trezor.io/suite/log/**', route => { + const url = route.request().url(); + const params = urlSearchParams(url); + requests.push(params); + route.continue(); + }); + }); + + test('go to wallet settings page, check BTC, activate all coins, deactivate all coins, set custom backend', async ({ + dashboardPage, + settingsPage, + window: page, + }) => { + const defaultUnchecked: NetworkSymbol[] = [ + 'ltc', + 'eth', + 'etc', + 'xrp', + 'bch', + 'btg', + 'dash', + 'dgb', + 'doge', + 'nmc', + 'vtc', + 'zec', + 'ada', + 'sol', + 'test', + 'tsep', + 'thol', + 'txrp', + 'tada', + 'dsol', + ]; + + await expect(settingsPage.coinNetworkButton('btc')).toBeEnabledCoin(); + for (const network of defaultUnchecked) { + await expect(settingsPage.coinNetworkButton(network)).toBeDisabledCoin(); + } + + await settingsPage.disableCoin('btc'); + + // check dashboard with all coins disabled + await dashboardPage.navigateTo(); + expect(page.getByTestId('@exception/discovery-empty')).toContainText( + 'All coins are disabled in Settings.', + ); + + await settingsPage.navigateTo(); + await settingsPage.coinsTabButton.click(); + // just do some clicking on switches and check result + for (const network of ['btc', ...defaultUnchecked] as NetworkSymbol[]) { + await settingsPage.enableCoin(network); + } + + //TODO: #15811 this is just not useful validation. To be refactored + // const settingsCoinsEvent = findAnalyticsEventByType< + // ExtractByEventType + // >(requests, EventType.SettingsCoins); + // expect(settingsCoinsEvent.symbol).to.be.oneOf(['btc', ...defaultUnchecked]); + // expect(settingsCoinsEvent.value).to.be.oneOf(['true', 'false']); + + // custom eth backend + await page.getByTestId('@settings/wallet/network/eth/advance').click(); + await page.getByTestId('@settings/advance/select-type/input').click(); + await page.getByTestId('@settings/advance/select-type/option/blockbook').click(); + // sometimes select stays open after click, no idea why, experimenting with wait + await page.getByTestId('@settings/advance/url').fill('https://eth.marek.pl/'); + await page.getByTestId('@settings/advance/button/save').click(); + + //TODO: #15811 this is just not useful validation. To be refactored + // const settingsCoinsBackendEvent = findAnalyticsEventByType>(requests, EventType.SettingsCoinsBackend) + // expect(settingsCoinsBackendEvent.type).to.equal('blockbook'); + // expect(settingsCoinsBackendEvent.totalRegular).to.equal('1'); + // expect(settingsCoinsBackendEvent.totalOnion).to.equal('0'); + }); +}); diff --git a/packages/suite-desktop-core/e2e/tests/settings/custom-firmware.test.ts b/packages/suite-desktop-core/e2e/tests/settings/custom-firmware.test.ts new file mode 100644 index 00000000000..c96e241d453 --- /dev/null +++ b/packages/suite-desktop-core/e2e/tests/settings/custom-firmware.test.ts @@ -0,0 +1,35 @@ +import path from 'node:path'; + +import { test, expect } from '../../support/fixtures'; + +const firmwarePath = path.join(__dirname, '../../fixtures/trezor-2.5.1.bin'); + +test.describe('Custom firmware', { tag: ['@group=settings'] }, () => { + test.use({ emulatorStartConf: { wipe: true } }); + test.beforeEach(async ({ onboardingPage, settingsPage }) => { + await onboardingPage.completeOnboarding(); + await settingsPage.navigateTo(); + await settingsPage.deviceTabButton.click(); + }); + + test('Custom firmware installation', async ({ window: page }) => { + await test.step('Start `Install firmware` flow', async () => { + await page.getByTestId('@settings/device/custom-firmware-modal-button').click(); + await expect(page.getByTestId('@firmware-modal/install-button')).toBeDisabled(); + }); + + await test.step('Select the custom firmware', async () => { + const fileChooserPromise = page.waitForEvent('filechooser'); + await page.getByTestId('@firmware-modal/input-area').click(); + const fileChooser = await fileChooserPromise; + await fileChooser.setFiles(firmwarePath); + }); + + await test.step('Complete the FW installation on the device', async () => { + await page.getByTestId('@firmware-modal/install-button').click(); + await page.getByTestId('@firmware/confirm-seed-checkbox').click(); + await page.getByTestId('@firmware/confirm-seed-button').click(); + await expect(page.getByTestId('@firmware/reconnect-device')).toBeVisible(); + }); + }); +}); diff --git a/packages/suite-desktop-core/e2e/tests/settings/t2b1-device-settings.test.ts b/packages/suite-desktop-core/e2e/tests/settings/t2b1-device-settings.test.ts index 5d623bd5741..69d911a2189 100644 --- a/packages/suite-desktop-core/e2e/tests/settings/t2b1-device-settings.test.ts +++ b/packages/suite-desktop-core/e2e/tests/settings/t2b1-device-settings.test.ts @@ -28,7 +28,7 @@ test.describe.serial('T2B1 - Device settings', { tag: ['@group=settings'] }, () test('change all possible device settings', async ({ trezorUserEnvLink, window: page, - baseURL, + apiURL, }) => { const newDeviceName = 'TREVOR!'; @@ -49,7 +49,7 @@ test.describe.serial('T2B1 - Device settings', { tag: ['@group=settings'] }, () // change background // On Web the there is instability, Playwright keeps clicking the button too soon. const buttonImageLoad = page.waitForResponse( - `${baseURL}static/images/homescreens/BW_64x128/circleweb.png`, + `${apiURL}static/images/homescreens/BW_64x128/circleweb.png`, ); await page.getByTestId('@settings/device/homescreen-gallery').click(); await buttonImageLoad; diff --git a/packages/suite-web/e2e/tests/settings/coins.test.ts b/packages/suite-web/e2e/tests/settings/coins.test.ts deleted file mode 100644 index 84827cc992a..00000000000 --- a/packages/suite-web/e2e/tests/settings/coins.test.ts +++ /dev/null @@ -1,133 +0,0 @@ -// @group_settings -// @retry=2 - -import { EventType } from '@trezor/suite-analytics'; - -import { ExtractByEventType, Requests } from '../../support/types'; -import { onNavBar } from '../../support/pageObjects/topBarObject'; - -let requests: Requests; - -describe('Coin Settings', () => { - beforeEach(() => { - cy.task('startEmu', { wipe: true }); - cy.task('setupEmu'); - cy.task('startBridge'); - cy.viewport('macbook-13').resetDb(); - cy.prefixedVisit('/'); - cy.passThroughInitialRun(); - - requests = []; - cy.interceptDataTrezorIo(requests); - }); - - it('go to wallet settings page, check BTC, activate all coins, deactivate all coins, set custom backend', () => { - const defaultUnchecked = [ - 'ltc', - 'eth', - 'etc', - 'xrp', - 'bch', - 'btg', - 'dash', - 'dgb', - 'doge', - 'nmc', - 'vtc', - 'zec', - 'ada', - // 'sol', FIXME: disabled till available in trezor-user-env - 'test', - 'tsep', - 'thol', - 'txrp', - 'tada', - // 'dsol', FIXME: disabled till available in trezor-user-env - ]; - - onNavBar.openSettings(); - cy.getTestElement('@settings/menu/wallet').click(); - - // only btc is selected by default; - cy.getTestElement('@settings/wallet/network/btc').should( - 'have.attr', - 'data-active', - 'true', - ); - - // other coins are not selected - defaultUnchecked.forEach(network => { - cy.getTestElement(`@settings/wallet/network/${network}`).should( - 'have.attr', - 'data-active', - 'false', - ); - }); - - // // this helps with unstable click to btc - cy.contains('span', 'Got it!').should('be.visible').click({ scrollBehavior: 'bottom' }); - cy.wait(500); - // disable Bitcoin - cy.getTestElement('@settings/wallet/network/btc').click(); - cy.getTestElement('@settings/wallet/network/btc').should( - 'have.attr', - 'data-active', - 'false', - ); - // check dashboard with all coins disabled - cy.getTestElement('@suite/menu/suite-index').click(); - - // check that there is no assets grid - cy.get('[class^="AssetsView__Grid"] > [class^="Card"]').should('not.exist'); - - onNavBar.openSettings(); - cy.getTestElement('@settings/menu/wallet').click(); - // just do some clicking on switches and check result - ['btc', ...defaultUnchecked].forEach(network => { - cy.getTestElement(`@settings/wallet/network/${network}`).should( - 'have.attr', - 'data-active', - 'false', - ); - }); - - ['btc', ...defaultUnchecked].forEach(network => { - cy.getTestElement(`@settings/wallet/network/${network}`).click({ force: true }); - }); - - ['btc', ...defaultUnchecked].forEach(network => { - cy.getTestElement(`@settings/wallet/network/${network}`).should( - 'have.attr', - 'data-active', - 'true', - ); - }); - - cy.findAnalyticsEventByType>( - requests, - EventType.SettingsCoins, - ).then(settingsCoinsEvent => { - expect(settingsCoinsEvent.symbol).to.be.oneOf(['btc', ...defaultUnchecked]); - expect(settingsCoinsEvent.value).to.be.oneOf(['true', 'false']); - }); - - // custom eth backend - cy.getTestElement('@settings/wallet/network/eth/advance').click(); - cy.getTestElement('@settings/advance/select-type/input').click(); - cy.getTestElement('@settings/advance/select-type/option/blockbook').click(); - // sometimes select stays open after click, no idea why, experimenting with wait - cy.wait(100); - cy.getTestElement('@settings/advance/url').type('https://eth.marek.pl/'); - cy.getTestElement('@settings/advance/button/save').click(); - - cy.findAnalyticsEventByType>( - requests, - EventType.SettingsCoinsBackend, - ).then(settingsCoinsBackendEvent => { - expect(settingsCoinsBackendEvent.symbol).to.equal('eth'); - expect(settingsCoinsBackendEvent.type).to.equal('blockbook'); - expect(settingsCoinsBackendEvent.totalRegular).to.equal('1'); - expect(settingsCoinsBackendEvent.totalOnion).to.equal('0'); - }); - }); -}); diff --git a/packages/suite-web/e2e/tests/settings/custom-firmware.test.ts b/packages/suite-web/e2e/tests/settings/custom-firmware.test.ts deleted file mode 100644 index b4cb42ab939..00000000000 --- a/packages/suite-web/e2e/tests/settings/custom-firmware.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -// @group_settings - -import { onNavBar } from '../../support/pageObjects/topBarObject'; - -// @retry=2 -describe('Install custom firmware', () => { - beforeEach(() => { - cy.task('startEmu', { wipe: true }); - cy.task('setupEmu'); - cy.task('startBridge'); - cy.viewport(1920, 1080).resetDb(); - cy.prefixedVisit('/'); - cy.passThroughInitialRun(); - cy.discoveryShouldFinish(); - }); - - /* - * 1. Navigate to `Settings/Device` - * 2. Click on `Install firmware` - * 3. Select the custom firmware - * 4. Complete the FW instalation on the device - */ - //TODO: skipped due to #13926 - it('go to device settings and check if custom FW modal appears', () => { - // - // Test preparation - // - const testBinFile = 'trezor-2.5.1.bin'; - - onNavBar.openSettings(); - cy.getTestElement('@settings/menu/device').click(); - cy.getTestElement('@settings/device/check-seed-button').should('be.visible'); - - cy.getTestElement('@settings/device/custom-firmware-modal-button') - .should('be.enabled') - .click({ - force: true, - }); - // - // Test execution - // - cy.getTestElement('@firmware-modal').then(fileUploadModal => { - cy.wrap(fileUploadModal) - .find('input[type=file]') - .attachFile( - { filePath: testBinFile, encoding: 'binary' }, - { subjectType: 'drag-n-drop' }, - ); - }); - cy.getTestElement('@firmware-modal').then(installFWbutton => { - cy.wrap(installFWbutton) - .find('[class*="Button"]') - .should('not.be.disabled') - .contains('Install firmware') - .click(); - }); - cy.getTestElement('@firmware/confirm-seed-checkbox').click(); - cy.getTestElement('@firmware/confirm-seed-button').click(); - // - // Assert - // - cy.getTestElement('@firmware/reconnect-device').should('be.visible'); - }); -}); diff --git a/packages/suite/src/components/firmware/SelectCustomFirmware.tsx b/packages/suite/src/components/firmware/SelectCustomFirmware.tsx index 38bc670263e..b56ee2c692b 100644 --- a/packages/suite/src/components/firmware/SelectCustomFirmware.tsx +++ b/packages/suite/src/components/firmware/SelectCustomFirmware.tsx @@ -84,10 +84,17 @@ export const SelectCustomFirmware = ({ number="2" title={} > - + + + - +