@Desktop • UI e2e • Test App triggered by Sheng-Long on ref develop #87
This file contains 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 • UI e2e • Test App" | |
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 | |
report_path: | |
description: Path where you want to store this execution's results | |
required: false | |
default: "allure-results-linux" | |
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_send_test: | |
description: Enable broadcast | |
required: false | |
type: boolean | |
default: false | |
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: "Desktop Tests E2E (Ubuntu)" | |
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:0.9.5 | |
ENABLE_BROADCAST_TEST: ${{ inputs.enable_send_test }} | |
runs-on: [ledger-live-4xlarge] | |
strategy: | |
fail-fast: false | |
matrix: | |
shardIndex: [1, 2, 3] | |
shardTotal: [3] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{ inputs.ref || github.sha }} | |
- name: Setup broadcast environment variables | |
id: set-env | |
run: | | |
day=$(date +%u) | |
if [ $day -eq 1 ] || "$ENABLE_BROADCAST_TEST" = "1" ; then | |
echo "ENABLE_TRANSACTION_BROADCAST=1" >> $GITHUB_ENV | |
else | |
echo "DISABLE_TRANSACTION_BROADCAST=1" >> $GITHUB_ENV | |
fi | |
- 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-test-desktop@develop | |
id: setup-test-desktop | |
with: | |
skip_ruby: true | |
install_playwright: true | |
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: 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 desktop test:playwright:speculos ${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/upload-artifact@v4.3.0 | |
with: | |
retention-days: 1 | |
name: allure-results-${{ matrix.shardIndex }} | |
path: "apps/ledger-live-desktop/allure-results" | |
- name: Upload Xray Results | |
if: ${{ !cancelled() && inputs.export_to_xray }} | |
uses: actions/upload-artifact@v4.3.0 | |
with: | |
retention-days: 1 | |
name: xray-reports-${{ matrix.shardIndex }} | |
path: apps/ledger-live-desktop/tests/artifacts/xray/xray-report.json | |
report-and-notify: | |
name: "Report and Notify" | |
runs-on: [ledger-live-medium] | |
needs: e2e-tests-linux | |
if: always() | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{ inputs.ref || github.sha }} | |
- name: Download Allure Results | |
uses: actions/download-artifact@v4.1.1 | |
with: | |
path: "apps/ledger-live-desktop/allure-results" | |
pattern: allure-results-* | |
merge-multiple: true | |
- name: Publish report on Allure Server | |
id: allure-server | |
if: ${{ !cancelled() }} | |
uses: LedgerHQ/send-to-allure-server-action@2.1.2 | |
with: | |
allure-server-url: "https://ledger-live.allure.green.ledgerlabs.net" | |
build-name: ${{ github.workflow }} | |
build-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
username: ${{ vars.ALLURE_USERNAME }} | |
password: ${{ secrets.ALLURE_LEDGER_LIVE_PASSWORD }} | |
path: ${{ github.ref_name }}/linux | |
allure-results: "apps/ledger-live-desktop/allure-results" | |
- name: Write Allure report in summary | |
if: ${{ !cancelled() }} | |
shell: bash | |
run: echo "::notice title=Allure report URL::${{ steps.allure-server.outputs.report-url }}" | |
- name: Get summary | |
if: ${{ !cancelled() }} | |
id: summary | |
shell: bash | |
run: | | |
cd apps/ledger-live-desktop | |
allure generate | |
cd allure-report/widgets | |
passedTests=$(jq '.statistic.passed' summary.json) | |
failedTests=$(jq '.statistic.failed' summary.json) | |
brokenTests=$(jq '.statistic.broken' summary.json) | |
skippedTests=$(jq '.statistic.skipped' summary.json) | |
totalTests=$(jq '.statistic.total' summary.json) | |
echo "TEST_RESULT=$passedTests passed, $failedTests failed, $brokenTests broken, $skippedTests skipped, $totalTests total" >> $GITHUB_ENV | |
if [ "$failedTests" -gt 0 ] || [ "$brokenTests" -gt 0 ]; then | |
echo "STATUS_COLOR=#FF333C" >> $GITHUB_ENV; | |
echo "STATUS_EMOJI=❌" >> $GITHUB_ENV; | |
else | |
echo "STATUS_COLOR=#33FF39" >> $GITHUB_ENV; | |
echo "STATUS_EMOJI=✅" >> $GITHUB_ENV; | |
fi | |
- uses: actions/github-script@v6 | |
if: ${{ !cancelled() }} | |
name: prepare status | |
id: status | |
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", | |
}], | |
}; | |
if (${{ !inputs.slack_notif && github.event_name == 'workflow_dispatch' }}) return; | |
const slackPayload = { | |
"attachments": [ | |
{ | |
"color": "${{ env.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} ${process.env.TEST_RESULT || 'No test results'}` | |
} | |
}, | |
{ | |
"type": "divider" | |
}, | |
{ | |
"type": "section", | |
"fields": [ | |
{ | |
"type": "mrkdwn", | |
"text": "*Allure Report*\n<${{ steps.allure-server.outputs.report-url }}|allure-results-linux>" | |
}, | |
{ | |
"type": "mrkdwn", | |
"text": "*Workflow*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Workflow Run>" | |
} | |
] | |
} | |
] | |
} | |
] | |
}; | |
fs.writeFileSync("payload-slack-content.json", JSON.stringify(slackPayload), "utf-8"); | |
- name: Print Slack Payload Content | |
if: ${{ !cancelled() && (inputs.slack_notif || github.event_name == 'schedule' )}} | |
run: cat ${{ github.workspace }}/payload-slack-content.json | |
- name: post to a Slack channel | |
id: slack | |
uses: slackapi/slack-github-action@v1.23.0 | |
if: ${{ !cancelled() && (inputs.slack_notif || github.event_name == 'schedule' )}} | |
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: ${{ env.STATUS_COLOR }} | |
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/download-artifact@v4.1.1 | |
with: | |
path: "apps/ledger-live-desktop/artifacts/xray" | |
pattern: xray-reports-* | |
merge-multiple: false | |
- name: Extract and Aggregate Xray results | |
run: | |
./aggregate-xray-reports.sh | |
- name: Upload aggregated xray results | |
uses: actions/upload-artifact@v4.3.0 | |
with: | |
name: aggregated-xray-reports | |
path: "apps/ledger-live-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 @apps/ledger-live-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 }}" |