@Desktop • UI e2e • Test App triggered by gbecerra-ledger on ref develop #1310
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: "[Desktop] - E2E Test - Scheduled" | |
run-name: "@Desktop • UI e2e • Test App triggered by ${{ inputs.login || github.actor }} ${{ format('on ref {0}', github.ref_name) }}" | |
on: | |
schedule: | |
- cron: "0 5 * * 1-5" | |
workflow_dispatch: | |
inputs: | |
ref: | |
description: the branch which triggered this workflow | |
required: false | |
login: | |
description: The GitHub username that triggered the workflow | |
required: false | |
base_ref: | |
description: The base branch to merge the head into when checking out the code | |
required: false | |
test_filter: | |
description: Filter test pattern to execute only tests suites named according to pattern(s) separated by '|' (e.g. to execute accounts and settings describe blocks "Accounts @smoke" or "Accounts @smoke|Settings") | |
required: false | |
invert_filter: | |
description: Ignore test having name pattern (entered in the previous field) | |
type: boolean | |
default: false | |
slack_notif: | |
description: "Send notification to Slack?" | |
required: false | |
type: boolean | |
default: false | |
export_to_xray: | |
description: Send tests results to Xray | |
required: false | |
type: boolean | |
default: false | |
test_execution: | |
description: "Test Execution ticket ID" | |
required: false | |
type: string | |
default: "B2CQA-2461" | |
enable_broadcast: | |
description: "Enable transaction broadcast" | |
required: false | |
type: boolean | |
default: false | |
build_type: | |
description: "Firebase env to target (pick js for release testing)" | |
required: false | |
type: choice | |
options: | |
- js | |
- staging | |
- testing | |
default: testing | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref_name != 'develop' && github.ref || github.run_id }} | |
cancel-in-progress: true | |
permissions: | |
id-token: write | |
contents: read | |
jobs: | |
e2e-tests-linux: | |
name: "Ubuntu E2E" | |
env: | |
NODE_OPTIONS: "--max-old-space-size=7168" | |
INSTRUMENT_BUILD: true | |
FORCE_COLOR: 3 | |
CI_OS: "ubuntu-latest" | |
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 | |
SPECULOS_IMAGE_TAG: ghcr.io/ledgerhq/speculos:master | |
runs-on: [ledger-live-4xlarge-e2e] | |
strategy: | |
fail-fast: false | |
matrix: | |
shardIndex: [1, 2, 3, 4] | |
shardTotal: [4] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{ inputs.ref || github.sha }} | |
- name: Setup caches | |
id: caches | |
uses: LedgerHQ/ledger-live/tools/actions/composites/setup-caches@develop | |
with: | |
skip-turbo-cache: "false" | |
accountId: ${{ secrets.AWS_ACCOUNT_ID_PROD }} | |
roleName: ${{ secrets.AWS_CACHE_ROLE_NAME }} | |
region: ${{ secrets.AWS_CACHE_REGION }} | |
turbo-server-token: ${{ secrets.TURBOREPO_SERVER_TOKEN }} | |
- uses: LedgerHQ/ledger-live/tools/actions/composites/setup-e2e-test-desktop@develop | |
id: setup-test-desktop | |
with: | |
build_type: ${{ inputs.build_type || 'testing' }} | |
turborepo-server-port: ${{ steps.caches.outputs.port }} | |
- name: Generate token | |
id: generate-token | |
uses: tibdex/github-app-token@v1 | |
with: | |
app_id: ${{ secrets.GH_BOT_APP_ID }} | |
private_key: ${{ secrets.GH_BOT_PRIVATE_KEY }} | |
- name: Retrieving coin apps | |
uses: actions/checkout@v4 | |
with: | |
ref: master | |
repository: LedgerHQ/coin-apps | |
token: ${{ steps.generate-token.outputs.token }} | |
path: coin-apps | |
- name: Pull docker image | |
run: docker pull ${{ env.SPECULOS_IMAGE_TAG }} | |
shell: bash | |
- name: Set test environment variables | |
uses: LedgerHQ/ledger-live/tools/actions/composites/setup-e2e-env@develop | |
with: | |
enable_broadcast: ${{ inputs.enable_broadcast }} | |
build_type: ${{ inputs.build_type }} | |
- name: Run playwright tests [Linux => xvfb-run] | |
id: tests | |
run: | | |
export SPECULOS_IMAGE_TAG=${{ env.SPECULOS_IMAGE_TAG }} | |
export COINAPPS=$PWD/coin-apps | |
export MOCK=0 | |
if [ "${{ inputs.invert_filter }}" = true ]; then invert_filter="-invert"; fi | |
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- pnpm e2e:desktop test:playwright --max-failures 50 ${INPUTS_TEST_FILTER:+--grep$invert_filter} "${{ inputs.test_filter }}" --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} | |
env: | |
INPUTS_TEST_FILTER: ${{ inputs.test_filter }} | |
SEED: ${{ secrets.SEED_QAA_B2C }} | |
XRAY: ${{ inputs.export_to_xray }} | |
TEST_EXECUTION: ${{ inputs.test_execution }} | |
PROJECT_KEY: B2CQA | |
- name: Upload Allure Results | |
if: ${{ !cancelled() }} | |
uses: actions/[email protected] | |
with: | |
name: allure-results-${{ matrix.shardIndex }} | |
path: "e2e/desktop/allure-results" | |
- name: Upload Xray Results | |
if: ${{ !cancelled() && inputs.export_to_xray }} | |
uses: actions/[email protected] | |
with: | |
name: xray-reports-${{ matrix.shardIndex }} | |
path: e2e/desktop/tests/artifacts/xray/xray-report.json | |
report-to-allure: | |
name: "Create Allure Report and upload it" | |
runs-on: [ledger-live-medium] | |
needs: e2e-tests-linux | |
outputs: | |
test_result: ${{ steps.summary.outputs.test_result }} | |
status_color: ${{ steps.summary.outputs.status_color }} | |
status_emoji: ${{ steps.summary.outputs.status_emoji }} | |
report-url: ${{ steps.allure-server.outputs.report-url }} | |
if: ${{ !cancelled() }} | |
env: | |
ALLURE_RESULTS: "allure-results" | |
steps: | |
- name: Download Allure Report | |
uses: actions/download-artifact@v4 | |
with: | |
path: ${{ env.ALLURE_RESULTS }} | |
pattern: ${{ env.ALLURE_RESULTS }}* | |
merge-multiple: true | |
- name: Publish report on Allure Server | |
id: allure-server | |
if: ${{ !cancelled() }} | |
uses: LedgerHQ/ledger-live/tools/actions/composites/upload-allure-report@develop | |
with: | |
platform: linux-speculos | |
login: ${{ vars.ALLURE_USERNAME }} | |
password: ${{ secrets.ALLURE_LEDGER_LIVE_PASSWORD }} | |
path: ${{ env.ALLURE_RESULTS }} | |
- name: Get summary | |
if: ${{ !cancelled() && (inputs.slack_notif || github.event_name == 'schedule' )}} | |
id: summary | |
uses: LedgerHQ/ledger-live/tools/actions/composites/get-allure-summary@develop | |
with: | |
allure-results-path: ${{ env.ALLURE_RESULTS }} | |
platform: linux | |
upload-to-xray: | |
name: "Upload to Xray" | |
runs-on: [ledger-live-medium] | |
env: | |
XRAY_CLIENT_ID: ${{ secrets.XRAY_CLIENT_ID }} | |
XRAY_CLIENT_SECRET: ${{ secrets.XRAY_CLIENT_SECRET }} | |
XRAY_API_URL: https://xray.cloud.getxray.app/api/v2 | |
JIRA_URL: https://ledgerhq.atlassian.net/browse | |
needs: e2e-tests-linux | |
if: ${{ !cancelled() && inputs.export_to_xray }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{ inputs.ref || github.sha }} | |
- name: Download Xray Results | |
uses: actions/[email protected] | |
with: | |
path: "e2e/desktop/artifacts/xray" | |
pattern: xray-reports-* | |
merge-multiple: false | |
- name: Extract and Aggregate Xray results | |
run: e2e/desktop/aggregate-xray-reports.sh e2e/desktop/artifacts/xray | |
- name: Upload aggregated xray results | |
uses: actions/[email protected] | |
with: | |
name: aggregated-xray-reports | |
path: "e2e/desktop/artifacts/xray/aggregated-xray-reports.json" | |
- name: Authenticate to Xray | |
id: authenticate | |
run: | | |
response=$(curl -H "Content-Type: application/json" -X POST --data '{"client_id": "${{ secrets.XRAY_CLIENT_ID }}", "client_secret": "${{ secrets.XRAY_CLIENT_SECRET }}"}' ${{ env.XRAY_API_URL }}/authenticate) | |
echo "xray_token=$response" >> $GITHUB_OUTPUT | |
- name: Publish merged report on Xray | |
id: publish-xray | |
run: | | |
response=$(curl -H "Content-Type: application/json" \ | |
-H "Authorization: Bearer ${{ steps.authenticate.outputs.xray_token }}" \ | |
-X POST \ | |
--data @e2e/desktop/artifacts/xray/aggregated-xray-reports.json \ | |
${{ env.XRAY_API_URL }}/import/execution) | |
key=$(echo $response | jq -r '.key') | |
echo "xray_key=$key" >> $GITHUB_OUTPUT | |
- name: Write Xray report in summary | |
shell: bash | |
run: echo "::notice title=Xray report URL::${{ env.JIRA_URL }}/${{ steps.publish-xray.outputs.xray_key }}" | |
notify-to-slack: | |
name: "Notify to slack" | |
runs-on: [ledger-live-medium] | |
needs: report-to-allure | |
if: ${{ !cancelled() && (inputs.slack_notif || github.event_name == 'schedule' )}} | |
steps: | |
- uses: actions/github-script@v7 | |
name: prepare status | |
id: status | |
env: | |
STATUS_EMOJI: ${{ needs.report-to-allure.outputs.status_emoji }} | |
EXPORT_TO_XRAY: ${{ inputs.export_to_xray }} | |
TEST_EXECUTION: ${{ github.event.inputs.test_execution }} | |
with: | |
script: | | |
const fs = require("fs"); | |
const path = require("path"); | |
const [ owner, repo ] = "${{ github.repository }}".split("/"); | |
const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRunAttempt, { | |
owner, | |
repo, | |
run_id: "${{ github.run_id }}", | |
attempt_number: "${{ github.run_attempt }}", | |
}); | |
const findJobUrl = os => | |
jobs.find(job => job.name == `Live Desktop Tests (${os})`)?.html_url; | |
const keys = { | |
linux: { | |
symbol: "🐧", | |
name: "Linux", | |
jobUrl: findJobUrl("Linux") | |
}, | |
}; | |
const report = { | |
linux: { | |
pass: ${{ needs.e2e-tests-linux.outputs.status == 'success' }}, | |
status: "${{ needs.e2e-tests-linux.outputs.status }}", | |
} | |
}; | |
const statusEmoji = process.env.STATUS_EMOJI; | |
let summary = `### Playwright Tests | |
` | |
summary += `|` | |
const reportKeys = Object.keys(report); | |
const playwrightSuccess = Object.entries(report).every(([os, values]) => !!values.pass); | |
reportKeys.forEach((k) => { | |
summary += ` [${keys[k].symbol} ${keys[k].name}](${keys[k].jobUrl}) |`; | |
}); | |
summary += ` | |
|`; | |
for (let i = 0; i < reportKeys.length; i++) { | |
summary += ` :--: |`; | |
} | |
summary += ` | |
|`; | |
Object.entries(report).forEach(([os, values]) => { | |
summary += ` ${values.pass ? statusEmoji : "❌"} (${values.status}) |`; | |
}); | |
summary += ` | |
${{ steps.comment.outputs.body }} | |
` | |
const output = { | |
summary, | |
actions: [{ | |
// 20 chars max | |
label: "Regen. Screenshots", | |
// 20 chars max | |
identifier: "regen_screenshots", | |
// 40 chars max | |
description: "Will regenerate playwright screenshots", | |
}, { | |
// 20 chars max | |
label: "Run full LLD suite", | |
// 20 chars max | |
identifier: "lld_full_suite", | |
// 40 chars max | |
description: "Run the full e2e test suite for LLD", | |
}], | |
}; | |
const slackPayload = { | |
"attachments": [ | |
{ | |
"color": "${{ needs.report-to-allure.outputs.status_color }}", | |
"blocks": [ | |
{ | |
"type": "header", | |
"text": { | |
"type": "plain_text", | |
"text": ":ledger-logo: Ledger Live Desktop E2E tests results on ${{ github.ref_name }}", | |
"emoji": true | |
} | |
}, | |
{ | |
"type": "divider" | |
}, | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": `- 🐧 linux: ${statusEmoji} ${{ needs.report-to-allure.outputs.test_result || 'No test results' }}` | |
} | |
}, | |
{ | |
"type": "divider" | |
}, | |
{ | |
"type": "section", | |
"fields": [ | |
{ | |
"type": "mrkdwn", | |
"text": "*Allure Report*\n<${{ needs.report-to-allure.outputs.report-url }}|allure-results-linux>" | |
}, | |
{ | |
"type": "mrkdwn", | |
"text": "*Workflow*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Workflow Run>" | |
} | |
] | |
} | |
] | |
} | |
] | |
}; | |
if (process.env.EXPORT_TO_XRAY === 'true') { | |
slackPayload.attachments[0].blocks.push({ | |
"type": "section", | |
"fields": [ | |
{ | |
"type": "mrkdwn", | |
"text": `*Xray Link*\n<https://ledgerhq.atlassian.net/browse/${process.env.TEST_EXECUTION}|Test Execution>` | |
} | |
] | |
}); | |
} | |
fs.writeFileSync("payload-slack-content.json", JSON.stringify(slackPayload), "utf-8"); | |
- name: Print Slack Payload Content | |
run: cat ${{ github.workspace }}/payload-slack-content.json | |
- name: Post to a Slack channel | |
id: slack | |
uses: slackapi/[email protected] | |
with: | |
channel-id: "C05FKJ7DFAP" | |
payload-file-path: ${{ github.workspace }}/payload-slack-content.json | |
env: | |
SLACK_BOT_TOKEN: ${{ secrets.SLACK_LIVE_CI_BOT_TOKEN }} | |
STATUS_COLOR: ${{ needs.report-to-allure.outputs.status_color }} |