Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert suite settings (coins, custom-firmware) + refactors desktop pipeline #15869

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 45 additions & 36 deletions .github/workflows/test-suite-desktop-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,78 +27,87 @@ 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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our web pipeline uses different checkout:

      - name: Checkout
        uses: actions/checkout@v4
        with:
          ref: ${{github.event.after}}
          fetch-depth: 2

Any preferences?

uses: actions/checkout@v4
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
27 changes: 11 additions & 16 deletions .github/workflows/test-suite-web-e2e-pw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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 }}"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unify how vars are passed to bash and adds safety net --forbid-only. Playwright docs: Whether to disallow test.only. Useful on CI.

yarn workspace @trezor/suite-desktop-core test:e2e:web --forbid-only --grep=${{ matrix.TEST_GROUP }}

- name: Extract Trezor-user-env logs
if: ${{ ! cancelled() }}
Expand All @@ -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() }}
Expand Down
6 changes: 4 additions & 2 deletions packages/suite-desktop-core/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ export enum PlaywrightProjects {
Web = 'web',
Desktop = 'desktop',
}
const timeoutCIRun = 1000 * 60;
const timeoutLocalRun = 1000 * 30;

const config: PlaywrightTestConfig = {
projects: [
{
name: PlaywrightProjects.Web,
use: {
browserName: 'chromium',
baseURL: process.env.BASE_URL || 'http://localhost:8000',
baseURL: process.env.BASE_URL || 'http://localhost:8000/',
},
grepInvert: /@desktopOnly/,
},
Expand All @@ -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,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want locally tests to fail fast during troubleshooting.

outputDir: path.join(__dirname, 'test-results'),
};

Expand Down
15 changes: 14 additions & 1 deletion packages/suite-desktop-core/e2e/support/common.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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;
};
Comment on lines +106 to +115
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might need update once i see first ci run

26 changes: 26 additions & 0 deletions packages/suite-desktop-core/e2e/support/customMatchers.ts
Original file line number Diff line number Diff line change
@@ -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}'`,
};
},
});
9 changes: 6 additions & 3 deletions packages/suite-desktop-core/e2e/support/fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable react-hooks/rules-of-hooks */

import { test as base, ElectronApplication, Page } from '@playwright/test';

import {
Expand All @@ -10,14 +9,15 @@ 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';
import { OnboardingActions } from './pageActions/onboardingActions';
import { PlaywrightProjects } from '../playwright.config';

type Fixtures = {
apiURL: string;
startEmulator: boolean;
emulatorStartConf: StartEmu;
emulatorSetupConf: SetupEmu;
Expand All @@ -35,6 +35,9 @@ const test = base.extend<Fixtures>({
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);
Expand Down Expand Up @@ -115,4 +118,4 @@ const test = base.extend<Fixtures>({
});

export { test };
export { expect } from '@playwright/test';
export { expect } from './customMatchers';
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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() {
Expand All @@ -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) {
Expand Down
Loading
Loading