Consolidate Build & Test CI (#32929)
* Consolidate Build & Test CI * Add missing workflow dependency * Fix artifact name clash * Fix playwright config * Fix playwright_ew job * Fix ed tests * Fix playwright tags * Iterate * Fix file reads * Fix sample-files paths * Fix PW_TAG * Fix blob report paths * Delint * Fix build-and-test.yaml * Iterate * Fix consentHomeserver.ts * Simplify * Iterate * Delint * Iterate * Iterate * Iterate * Specify shell * Simplify * Delete apps/web/playwright/sample-files/index.ts * Discard changes to apps/web/playwright/sample-files/index.ts * Exclude playwright-common from coverage gate * Attempt to speed up arm64 desktop test * Revert "Attempt to speed up arm64 desktop test" This reverts commit 8fa8ff0c785da6dad05bda938c8af24fa6af0451. * Iterate * Fix cache key * Accept python or python3 as per node-gyp * Accept python or python3 as per node-gypd * Exclude apps/desktop/hak from coverage gate
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@ on:
|
|||||||
# Privilege escalation necessary to publish to Netlify
|
# Privilege escalation necessary to publish to Netlify
|
||||||
# 🚨 We must not execute any checked out code here.
|
# 🚨 We must not execute any checked out code here.
|
||||||
workflow_run: # zizmor: ignore[dangerous-triggers]
|
workflow_run: # zizmor: ignore[dangerous-triggers]
|
||||||
workflows: ["End to End Tests"]
|
workflows: ["Build & Test"]
|
||||||
types:
|
types:
|
||||||
- completed
|
- completed
|
||||||
|
|
||||||
@@ -1,7 +1,13 @@
|
|||||||
# Produce a build of element-web with this version of react-sdk
|
# builds Element Web
|
||||||
# and any matching branches of element-web and js-sdk, output it
|
# runs Playwright tests against the built Element Web
|
||||||
# as an artifact and run end-to-end tests.
|
# builds Element Desktop using the built Element Web
|
||||||
name: End to End Tests
|
#
|
||||||
|
# Tries to use a matching js-sdk branch for the build.
|
||||||
|
#
|
||||||
|
# Produces a `webapp` artifact
|
||||||
|
# Produces multiple Desktop artifacts
|
||||||
|
# Produces multiple Playwright report artifacts
|
||||||
|
name: Build & Test
|
||||||
on:
|
on:
|
||||||
# CRON to run all Projects at 6am UTC
|
# CRON to run all Projects at 6am UTC
|
||||||
schedule:
|
schedule:
|
||||||
@@ -10,7 +16,8 @@ on:
|
|||||||
merge_group:
|
merge_group:
|
||||||
types: [checks_requested]
|
types: [checks_requested]
|
||||||
push:
|
push:
|
||||||
branches: [develop, master]
|
# We do not build on push to develop as the merge_group check handles that
|
||||||
|
branches: [staging, master]
|
||||||
repository_dispatch:
|
repository_dispatch:
|
||||||
types: [element-web-notify]
|
types: [element-web-notify]
|
||||||
|
|
||||||
@@ -35,15 +42,15 @@ concurrency:
|
|||||||
env:
|
env:
|
||||||
# fetchdep.sh needs to know our PR number
|
# fetchdep.sh needs to know our PR number
|
||||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
# Use 6 runners in the default case, but 4 when running on a schedule where we run all 5 projects (20 runners total)
|
# Use 4 runners in the default case, but only 1 when running on a schedule where we run all 5 projects
|
||||||
NUM_RUNNERS: ${{ github.event_name == 'schedule' && 4 || 6 }}
|
NUM_RUNNERS: ${{ github.event_name == 'schedule' && 1 || 4 }}
|
||||||
NX_DEFAULT_OUTPUT_STYLE: stream-without-prefixes
|
NX_DEFAULT_OUTPUT_STYLE: stream-without-prefixes
|
||||||
|
|
||||||
permissions: {} # No permissions required
|
permissions: {} # No permissions required
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build_ew:
|
||||||
name: "Build Element-Web"
|
name: "Build Element Web"
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
if: inputs.skip != true
|
if: inputs.skip != true
|
||||||
outputs:
|
outputs:
|
||||||
@@ -94,9 +101,9 @@ jobs:
|
|||||||
const matrix = Array.from({ length: numRunners }, (_, i) => i + 1);
|
const matrix = Array.from({ length: numRunners }, (_, i) => i + 1);
|
||||||
core.setOutput("matrix", JSON.stringify(matrix));
|
core.setOutput("matrix", JSON.stringify(matrix));
|
||||||
|
|
||||||
playwright:
|
playwright_ew:
|
||||||
name: "Run Tests [${{ matrix.project }}] ${{ matrix.runner }}/${{ needs.build.outputs.num-runners }}"
|
name: "Run Tests [${{ matrix.project }}] ${{ matrix.runner }}/${{ needs.build_ew.outputs.num-runners }}"
|
||||||
needs: build
|
needs: build_ew
|
||||||
if: inputs.skip != true
|
if: inputs.skip != true
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
permissions:
|
permissions:
|
||||||
@@ -107,7 +114,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
# Run multiple instances in parallel to speed up the tests
|
# Run multiple instances in parallel to speed up the tests
|
||||||
runner: ${{ fromJSON(needs.build.outputs.runners-matrix) }}
|
runner: ${{ fromJSON(needs.build_ew.outputs.runners-matrix) }}
|
||||||
project:
|
project:
|
||||||
- Chrome
|
- Chrome
|
||||||
- Firefox
|
- Firefox
|
||||||
@@ -179,29 +186,85 @@ jobs:
|
|||||||
--project="${{ matrix.project }}" \
|
--project="${{ matrix.project }}" \
|
||||||
${{ (github.event_name == 'pull_request' && matrix.runAllTests == false ) && '--grep-invert @mergequeue' || '' }}
|
${{ (github.event_name == 'pull_request' && matrix.runAllTests == false ) && '--grep-invert @mergequeue' || '' }}
|
||||||
env:
|
env:
|
||||||
SHARD: ${{ format('{0}/{1}', matrix.runner, needs.build.outputs.num-runners) }}
|
SHARD: ${{ format('{0}/{1}', matrix.runner, needs.build_ew.outputs.num-runners) }}
|
||||||
|
|
||||||
- name: Upload blob report to GitHub Actions Artifacts
|
- name: Upload blob report to GitHub Actions Artifacts
|
||||||
if: always()
|
if: always()
|
||||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
|
||||||
with:
|
with:
|
||||||
name: all-blob-reports-${{ matrix.project }}-${{ matrix.runner }}
|
name: blob-report-${{ matrix.project }}-${{ matrix.runner }}
|
||||||
path: apps/web/blob-report
|
path: apps/web/blob-report
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
downstream-modules:
|
downstream-modules:
|
||||||
name: Downstream Playwright tests [element-modules]
|
name: Downstream Playwright tests [element-modules]
|
||||||
needs: build
|
needs: build_ew
|
||||||
if: inputs.skip != true && github.event_name == 'merge_group'
|
if: inputs.skip != true && github.event_name == 'merge_group'
|
||||||
uses: element-hq/element-modules/.github/workflows/reusable-playwright-tests.yml@main # zizmor: ignore[unpinned-uses]
|
uses: element-hq/element-modules/.github/workflows/reusable-playwright-tests.yml@main # zizmor: ignore[unpinned-uses]
|
||||||
with:
|
with:
|
||||||
webapp-artifact: webapp
|
webapp-artifact: webapp
|
||||||
|
|
||||||
|
prepare_ed:
|
||||||
|
name: "Prepare Element Desktop"
|
||||||
|
uses: ./.github/workflows/build_desktop_prepare.yaml
|
||||||
|
needs: build_ew
|
||||||
|
if: inputs.skip != true
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
with:
|
||||||
|
config: ${{ (github.event.pull_request.base.ref || github.ref_name) == 'develop' && 'element.io/nightly' || 'element.io/release' }}
|
||||||
|
version: ${{ (github.event.pull_request.base.ref || github.ref_name) == 'develop' && 'develop' || '' }}
|
||||||
|
webapp-artifact: webapp
|
||||||
|
|
||||||
|
build_ed_windows:
|
||||||
|
needs: prepare_ed
|
||||||
|
name: "Desktop Windows"
|
||||||
|
uses: ./.github/workflows/build_desktop_windows.yaml
|
||||||
|
if: inputs.skip != true
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
arch: [x64, ia32, arm64]
|
||||||
|
with:
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
|
blob_report: true
|
||||||
|
|
||||||
|
build_ed_linux:
|
||||||
|
needs: prepare_ed
|
||||||
|
name: "Desktop Linux"
|
||||||
|
uses: ./.github/workflows/build_desktop_linux.yaml
|
||||||
|
if: inputs.skip != true
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
sqlcipher: [system, static]
|
||||||
|
arch: [amd64, arm64]
|
||||||
|
runAllTests:
|
||||||
|
- ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'X-Run-All-Tests') }}
|
||||||
|
# We ship static sqlcipher builds, so delegate testing the system builds to the merge queue
|
||||||
|
exclude:
|
||||||
|
- runAllTests: false
|
||||||
|
sqlcipher: system
|
||||||
|
with:
|
||||||
|
sqlcipher: ${{ matrix.sqlcipher }}
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
|
blob_report: true
|
||||||
|
|
||||||
|
build_ed_macos:
|
||||||
|
needs: prepare_ed
|
||||||
|
name: "Desktop macOS"
|
||||||
|
uses: ./.github/workflows/build_desktop_macos.yaml
|
||||||
|
if: inputs.skip != true
|
||||||
|
with:
|
||||||
|
blob_report: true
|
||||||
|
|
||||||
complete:
|
complete:
|
||||||
name: end-to-end-tests
|
name: end-to-end-tests
|
||||||
needs:
|
needs:
|
||||||
- playwright
|
- playwright_ew
|
||||||
- downstream-modules
|
- downstream-modules
|
||||||
|
- build_ed_windows
|
||||||
|
- build_ed_linux
|
||||||
|
- build_ed_macos
|
||||||
if: always()
|
if: always()
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
@@ -227,18 +290,20 @@ jobs:
|
|||||||
if: inputs.skip != true
|
if: inputs.skip != true
|
||||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||||
with:
|
with:
|
||||||
pattern: all-blob-reports-*
|
pattern: blob-report-*
|
||||||
path: apps/web/all-blob-reports
|
path: all-blob-reports
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Merge into HTML Report
|
- name: Merge into HTML Report
|
||||||
if: inputs.skip != true
|
if: inputs.skip != true
|
||||||
working-directory: apps/web
|
run: |
|
||||||
run: pnpm playwright merge-reports --reporter=html,./playwright/flaky-reporter.ts,@element-hq/element-web-playwright-common/lib/stale-screenshot-reporter.js ./all-blob-reports
|
pnpm playwright merge-reports \
|
||||||
|
--config=playwright-merge.config.ts \
|
||||||
|
./all-blob-reports
|
||||||
env:
|
env:
|
||||||
# Only pass creds to the flaky-reporter on main branch runs
|
# Only pass creds to the flaky-reporter on main branch runs
|
||||||
GITHUB_TOKEN: ${{ github.ref_name == 'develop' && secrets.ELEMENT_BOT_TOKEN || '' }}
|
GITHUB_TOKEN: ${{ github.ref_name == 'develop' && secrets.ELEMENT_BOT_TOKEN || '' }}
|
||||||
PLAYWRIGHT_HTML_TITLE: ${{ case(github.event_name == 'pull_request', format('EW Playwright Report PR-{0}', env.PR_NUMBER), 'EW Playwright Report') }}
|
PLAYWRIGHT_HTML_TITLE: ${{ case(github.event_name == 'pull_request', format('Playwright Report PR-{0}', env.PR_NUMBER), 'Playwright Report') }}
|
||||||
|
|
||||||
# Upload the HTML report even if one of our reporters fails, this can happen when stale screenshots are detected
|
# Upload the HTML report even if one of our reporters fails, this can happen when stale screenshots are detected
|
||||||
- name: Upload HTML report
|
- name: Upload HTML report
|
||||||
@@ -246,7 +311,7 @@ jobs:
|
|||||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
|
||||||
with:
|
with:
|
||||||
name: html-report
|
name: html-report
|
||||||
path: apps/web/playwright-report
|
path: playwright-report
|
||||||
retention-days: 14
|
retention-days: 14
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
name: Build and Test
|
|
||||||
on:
|
|
||||||
pull_request: {}
|
|
||||||
push:
|
|
||||||
branches: [develop, staging, master]
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
permissions: {} # No permissions required
|
|
||||||
jobs:
|
|
||||||
fetch:
|
|
||||||
uses: ./.github/workflows/build_desktop_prepare.yaml
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
with:
|
|
||||||
config: ${{ (github.event.pull_request.base.ref || github.ref_name) == 'develop' && 'element.io/nightly' || 'element.io/release' }}
|
|
||||||
version: ${{ (github.event.pull_request.base.ref || github.ref_name) == 'develop' && 'develop' || '' }}
|
|
||||||
branch-matching: true
|
|
||||||
|
|
||||||
windows:
|
|
||||||
needs: fetch
|
|
||||||
name: Windows
|
|
||||||
uses: ./.github/workflows/build_desktop_windows.yaml
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
arch: [x64, ia32, arm64]
|
|
||||||
with:
|
|
||||||
arch: ${{ matrix.arch }}
|
|
||||||
blob_report: true
|
|
||||||
|
|
||||||
linux:
|
|
||||||
needs: fetch
|
|
||||||
name: "Linux (${{ matrix.arch }}) (sqlcipher: ${{ matrix.sqlcipher }})"
|
|
||||||
uses: ./.github/workflows/build_desktop_linux.yaml
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
sqlcipher: [system, static]
|
|
||||||
arch: [amd64, arm64]
|
|
||||||
with:
|
|
||||||
sqlcipher: ${{ matrix.sqlcipher }}
|
|
||||||
arch: ${{ matrix.arch }}
|
|
||||||
blob_report: true
|
|
||||||
|
|
||||||
macos:
|
|
||||||
needs: fetch
|
|
||||||
name: macOS
|
|
||||||
uses: ./.github/workflows/build_desktop_macos.yaml
|
|
||||||
with:
|
|
||||||
blob_report: true
|
|
||||||
|
|
||||||
tests-done:
|
|
||||||
needs: [windows, linux, macos]
|
|
||||||
runs-on: ubuntu-24.04
|
|
||||||
if: ${{ !cancelled() }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
|
|
||||||
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
|
|
||||||
with:
|
|
||||||
cache: "pnpm"
|
|
||||||
node-version: "lts/*"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
- name: Download blob reports from GitHub Actions Artifacts
|
|
||||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
|
||||||
with:
|
|
||||||
pattern: blob-report-*
|
|
||||||
path: apps/desktop/all-blob-reports
|
|
||||||
merge-multiple: true
|
|
||||||
|
|
||||||
- name: Merge into HTML Report
|
|
||||||
working-directory: apps/desktop
|
|
||||||
run: pnpm playwright merge-reports -c ./playwright.config.ts --reporter=html ./all-blob-reports
|
|
||||||
|
|
||||||
- name: Upload HTML report
|
|
||||||
if: always()
|
|
||||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
|
|
||||||
with:
|
|
||||||
name: html-report
|
|
||||||
path: apps/desktop/playwright-report
|
|
||||||
retention-days: 14
|
|
||||||
|
|
||||||
- if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
|
|
||||||
run: exit 1
|
|
||||||
@@ -28,7 +28,7 @@ on:
|
|||||||
type: string
|
type: string
|
||||||
required: false
|
required: false
|
||||||
description: |
|
description: |
|
||||||
The name of the prepare artifact to use, defaults to 'webapp'.
|
The name of the prepare artifact to use, defaults to 'desktop-prepare'.
|
||||||
The artifact must contain the following:
|
The artifact must contain the following:
|
||||||
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
|
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
|
||||||
+ electronVersion - the version of electron to use for cache keying
|
+ electronVersion - the version of electron to use for cache keying
|
||||||
@@ -38,7 +38,7 @@ on:
|
|||||||
|
|
||||||
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
||||||
for example icons in the `build/` directory to override the app icons.
|
for example icons in the `build/` directory to override the app icons.
|
||||||
default: "webapp"
|
default: "desktop-prepare"
|
||||||
test:
|
test:
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
@@ -73,20 +73,8 @@ jobs:
|
|||||||
# https://github.com/matrix-org/seshat/issues/135
|
# https://github.com/matrix-org/seshat/issues/135
|
||||||
runs-on: ${{ inputs.runs-on || (inputs.arch == 'arm64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04') }}
|
runs-on: ${{ inputs.runs-on || (inputs.arch == 'arm64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04') }}
|
||||||
env:
|
env:
|
||||||
HAK_DOCKER_IMAGE: ghcr.io/element-hq/element-web/desktop-build-env
|
HAK_DOCKER_IMAGE: ghcr.io/element-hq/element-web/desktop-build-env:${{ case(github.event_name == 'push', inputs.ref || github.ref_name, github.event_name == 'release', 'staging', 'develop') }}
|
||||||
steps:
|
steps:
|
||||||
- name: Resolve docker image tag for push
|
|
||||||
if: github.event_name == 'push'
|
|
||||||
run: echo "HAK_DOCKER_IMAGE=$HAK_DOCKER_IMAGE:$REF" >> $GITHUB_ENV
|
|
||||||
env:
|
|
||||||
REF: ${{ inputs.ref || github.ref_name }}
|
|
||||||
- name: Resolve docker image tag for release
|
|
||||||
if: github.event_name == 'release'
|
|
||||||
run: echo "HAK_DOCKER_IMAGE=$HAK_DOCKER_IMAGE:staging" >> $GITHUB_ENV
|
|
||||||
- name: Resolve docker image tag for other triggers
|
|
||||||
if: github.event_name != 'push' && github.event_name != 'release'
|
|
||||||
run: echo "HAK_DOCKER_IMAGE=$HAK_DOCKER_IMAGE:develop" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- uses: nbucic/variable-mapper@0673f6891a0619ba7c002ecfed0f9f4f39017b6f
|
- uses: nbucic/variable-mapper@0673f6891a0619ba7c002ecfed0f9f4f39017b6f
|
||||||
id: config
|
id: config
|
||||||
with:
|
with:
|
||||||
@@ -95,11 +83,9 @@ jobs:
|
|||||||
map: |
|
map: |
|
||||||
{
|
{
|
||||||
"amd64": {
|
"amd64": {
|
||||||
"target": "x86_64-unknown-linux-gnu",
|
|
||||||
"arch": "x86-64"
|
"arch": "x86-64"
|
||||||
},
|
},
|
||||||
"arm64": {
|
"arm64": {
|
||||||
"target": "aarch64-unknown-linux-gnu",
|
|
||||||
"arch": "aarch64",
|
"arch": "aarch64",
|
||||||
"build-args": "--arm64"
|
"build-args": "--arm64"
|
||||||
}
|
}
|
||||||
@@ -120,7 +106,7 @@ jobs:
|
|||||||
id: cache
|
id: cache
|
||||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
|
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
|
||||||
with:
|
with:
|
||||||
key: ${{ runner.os }}-${{ github.ref_name }}-${{ inputs.sqlcipher }}-${{ inputs.arch }}-${{ hashFiles('hakHash', 'electronVersion', 'dockerbuild/*') }}
|
key: ${{ runner.os }}-${{ github.ref_name }}-${{ inputs.sqlcipher }}-${{ inputs.arch }}-${{ hashFiles('apps/desktop/hakHash', 'apps/desktop/electronVersion', 'apps/desktop/dockerbuild/*') }}
|
||||||
path: |
|
path: |
|
||||||
apps/desktop/.hak
|
apps/desktop/.hak
|
||||||
|
|
||||||
@@ -135,7 +121,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Deps
|
- name: Install Deps
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
run: pnpm install --frozen-lockfile
|
run: "pnpm install --frozen-lockfile --filter element-desktop"
|
||||||
|
|
||||||
- name: "Get modified files"
|
- name: "Get modified files"
|
||||||
id: changed_files
|
id: changed_files
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ on:
|
|||||||
type: string
|
type: string
|
||||||
required: false
|
required: false
|
||||||
description: |
|
description: |
|
||||||
The name of the prepare artifact to use, defaults to 'webapp'.
|
The name of the prepare artifact to use, defaults to 'desktop-prepare'.
|
||||||
The artifact must contain the following:
|
The artifact must contain the following:
|
||||||
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
|
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
|
||||||
+ electronVersion - the version of electron to use for cache keying
|
+ electronVersion - the version of electron to use for cache keying
|
||||||
@@ -46,7 +46,7 @@ on:
|
|||||||
|
|
||||||
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
||||||
for example icons in the `build/` directory to override the app icons.
|
for example icons in the `build/` directory to override the app icons.
|
||||||
default: "webapp"
|
default: "desktop-prepare"
|
||||||
test:
|
test:
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
@@ -92,7 +92,7 @@ jobs:
|
|||||||
id: cache
|
id: cache
|
||||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
|
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
|
||||||
with:
|
with:
|
||||||
key: ${{ runner.os }}-${{ hashFiles('hakHash', 'electronVersion') }}
|
key: ${{ runner.os }}-${{ hashFiles('apps/desktop/hakHash', 'apps/desktop/electronVersion') }}
|
||||||
path: |
|
path: |
|
||||||
apps/desktop/.hak
|
apps/desktop/.hak
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Deps
|
- name: Install Deps
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
run: "pnpm install --frozen-lockfile"
|
run: "pnpm install --frozen-lockfile --filter element-desktop"
|
||||||
|
|
||||||
- name: Build Natives
|
- name: Build Natives
|
||||||
if: steps.cache.outputs.cache-hit != 'true'
|
if: steps.cache.outputs.cache-hit != 'true'
|
||||||
|
|||||||
@@ -20,11 +20,10 @@ on:
|
|||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
description: "Whether the build should be deployed to production"
|
description: "Whether the build should be deployed to production"
|
||||||
branch-matching:
|
webapp-artifact:
|
||||||
type: boolean
|
type: string
|
||||||
required: false
|
required: false
|
||||||
default: false
|
description: "Name of the webapp artifact that should be used, will fetch a relevant build if omitted"
|
||||||
description: "Whether the branch name should be matched to find the element-web commit"
|
|
||||||
secrets:
|
secrets:
|
||||||
# Required if `nightly` is set
|
# Required if `nightly` is set
|
||||||
CF_R2_ACCESS_KEY_ID:
|
CF_R2_ACCESS_KEY_ID:
|
||||||
@@ -66,28 +65,26 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Deps
|
- name: Install Deps
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
run: "pnpm install --frozen-lockfile"
|
run: "pnpm install --frozen-lockfile --filter element-desktop"
|
||||||
|
|
||||||
- name: Fetch Element Web (matching branch)
|
- name: Fetch Element Web (from artifact)
|
||||||
id: branch-matching
|
if: inputs.webapp-artifact != ''
|
||||||
if: inputs.branch-matching
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||||
|
with:
|
||||||
|
name: ${{ inputs.webapp-artifact }}
|
||||||
|
path: apps/desktop/webapp
|
||||||
|
|
||||||
|
- name: Build webapp.asar (from artifact)
|
||||||
|
if: inputs.webapp-artifact != ''
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
continue-on-error: true
|
|
||||||
run: |
|
run: |
|
||||||
scripts/branch-match.sh
|
cp -f "$CONFIG_DIR/config.json" webapp/config.json
|
||||||
cp "$CONFIG_DIR/config.json" element-web/
|
|
||||||
pnpm --cwd element-web install --frozen-lockfile
|
|
||||||
pnpm --cwd element-web run build
|
|
||||||
mv element-web/webapp .
|
|
||||||
pnpm run asar-webapp
|
pnpm run asar-webapp
|
||||||
env:
|
env:
|
||||||
# These must be set for branch-match.sh to get the right branch
|
|
||||||
REPOSITORY: ${{ github.repository }}
|
|
||||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
||||||
CONFIG_DIR: ${{ inputs.config }}
|
CONFIG_DIR: ${{ inputs.config }}
|
||||||
|
|
||||||
- name: Fetch Element Web (${{ inputs.version }})
|
- name: Fetch Element Web (${{ inputs.version }})
|
||||||
if: steps.branch-matching.outcome == 'failure' || steps.branch-matching.outcome == 'skipped'
|
if: inputs.webapp-artifact == ''
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
run: pnpm run fetch --noverify -d ${CONFIG} ${VERSION}
|
run: pnpm run fetch --noverify -d ${CONFIG} ${VERSION}
|
||||||
env:
|
env:
|
||||||
@@ -189,7 +186,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
|
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
|
||||||
with:
|
with:
|
||||||
name: webapp
|
name: desktop-prepare
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
path: |
|
path: |
|
||||||
apps/desktop/webapp.asar
|
apps/desktop/webapp.asar
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ jobs:
|
|||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install Deps
|
- name: Install Deps
|
||||||
working-directory: apps/desktop
|
run: "pnpm install --frozen-lockfile --filter element-desktop"
|
||||||
run: "pnpm install --frozen-lockfile"
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||||
with:
|
with:
|
||||||
@@ -85,12 +84,19 @@ jobs:
|
|||||||
EXECUTABLE: ${{ steps.executable.outputs.path }}
|
EXECUTABLE: ${{ steps.executable.outputs.path }}
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
uses: coactions/setup-xvfb@6b00cf1889f4e1d5a48635647013c0508128ee1a
|
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
with:
|
shell: bash
|
||||||
run: pnpm -C apps/desktop test --project=${{ inputs.project }} ${{ runner.os != 'Linux' && '--ignore-snapshots' || '' }} ${{ inputs.blob_report == false && '--reporter=html' || '' }} ${{ inputs.args }}
|
working-directory: apps/desktop
|
||||||
|
run: |
|
||||||
|
$PREFIX pnpm playwright test \
|
||||||
|
${{ runner.os != 'Linux' && '--ignore-snapshots' || '' }} \
|
||||||
|
${{ inputs.blob_report == false && '--reporter=html' || '' }} \
|
||||||
|
$ARGS
|
||||||
env:
|
env:
|
||||||
|
PREFIX: ${{ runner.os == 'Linux' && 'xvfb-run' || '' }}
|
||||||
|
PW_TAG: ${{ inputs.project }}
|
||||||
ELEMENT_DESKTOP_EXECUTABLE: ${{ steps.executable.outputs.path }}
|
ELEMENT_DESKTOP_EXECUTABLE: ${{ steps.executable.outputs.path }}
|
||||||
|
ARGS: ${{ inputs.args }}
|
||||||
|
|
||||||
- name: Upload blob report
|
- name: Upload blob report
|
||||||
if: always() && inputs.blob_report
|
if: always() && inputs.blob_report
|
||||||
@@ -99,6 +105,7 @@ jobs:
|
|||||||
name: blob-report-${{ inputs.artifact }}
|
name: blob-report-${{ inputs.artifact }}
|
||||||
path: apps/desktop/blob-report
|
path: apps/desktop/blob-report
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload HTML report
|
- name: Upload HTML report
|
||||||
if: always() && inputs.blob_report == false
|
if: always() && inputs.blob_report == false
|
||||||
@@ -107,3 +114,4 @@ jobs:
|
|||||||
name: ${{ inputs.artifact }}-test
|
name: ${{ inputs.artifact }}-test
|
||||||
path: apps/desktop/playwright-report
|
path: apps/desktop/playwright-report
|
||||||
retention-days: 14
|
retention-days: 14
|
||||||
|
if-no-files-found: error
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ on:
|
|||||||
type: string
|
type: string
|
||||||
required: false
|
required: false
|
||||||
description: |
|
description: |
|
||||||
The name of the prepare artifact to use, defaults to 'webapp'.
|
The name of the prepare artifact to use, defaults to 'desktop-prepare'.
|
||||||
The artifact must contain the following:
|
The artifact must contain the following:
|
||||||
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
|
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
|
||||||
+ electronVersion - the version of electron to use for cache keying
|
+ electronVersion - the version of electron to use for cache keying
|
||||||
@@ -52,7 +52,7 @@ on:
|
|||||||
|
|
||||||
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
||||||
for example icons in the `build/` directory to override the app icons.
|
for example icons in the `build/` directory to override the app icons.
|
||||||
default: "webapp"
|
default: "desktop-prepare"
|
||||||
test:
|
test:
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
@@ -123,7 +123,7 @@ jobs:
|
|||||||
id: cache
|
id: cache
|
||||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
|
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
|
||||||
with:
|
with:
|
||||||
key: ${{ runner.os }}-${{ inputs.arch }}-${{ hashFiles('hakHash', 'electronVersion') }}
|
key: ${{ runner.os }}-${{ inputs.arch }}-${{ hashFiles('apps/desktop/hakHash', 'apps/desktop/electronVersion') }}
|
||||||
path: |
|
path: |
|
||||||
apps/desktop/.hak
|
apps/desktop/.hak
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Deps
|
- name: Install Deps
|
||||||
working-directory: apps/desktop
|
working-directory: apps/desktop
|
||||||
run: "pnpm install --frozen-lockfile"
|
run: "pnpm install --frozen-lockfile --filter element-desktop"
|
||||||
|
|
||||||
- name: Insert config snippet
|
- name: Insert config snippet
|
||||||
if: steps.config.outputs.extra_config != ''
|
if: steps.config.outputs.extra_config != ''
|
||||||
|
|||||||
@@ -14,10 +14,7 @@ import type { Tool } from "../../scripts/hak/hakEnv.ts";
|
|||||||
import type { DependencyInfo } from "../../scripts/hak/dep.ts";
|
import type { DependencyInfo } from "../../scripts/hak/dep.ts";
|
||||||
|
|
||||||
export default async function (hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> {
|
export default async function (hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> {
|
||||||
const tools: Tool[] = [
|
const tools: Tool[] = [["rustc", "--version"]];
|
||||||
["rustc", "--version"],
|
|
||||||
["python", "--version"], // node-gyp uses python for reasons beyond comprehension
|
|
||||||
];
|
|
||||||
if (hakEnv.isWin()) {
|
if (hakEnv.isWin()) {
|
||||||
tools.push(["perl", "--version"]); // for openssl configure
|
tools.push(["perl", "--version"]); // for openssl configure
|
||||||
tools.push(["nasm", "-v"]); // for openssl building
|
tools.push(["nasm", "-v"]); // for openssl building
|
||||||
@@ -28,6 +25,14 @@ export default async function (hakEnv: HakEnv, moduleInfo: DependencyInfo): Prom
|
|||||||
}
|
}
|
||||||
await hakEnv.checkTools(tools);
|
await hakEnv.checkTools(tools);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// node-gyp uses python for reasons beyond comprehension
|
||||||
|
await hakEnv.checkTools([["python", "--version"]]);
|
||||||
|
} catch {
|
||||||
|
// try python3 too
|
||||||
|
await hakEnv.checkTools([["python3", "--version"]]);
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure Rust target exists (nb. we avoid depending on rustup)
|
// Ensure Rust target exists (nb. we avoid depending on rustup)
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
const rustc = childProcess.execFile(
|
const rustc = childProcess.execFile(
|
||||||
|
|||||||
@@ -8,25 +8,9 @@ Please see LICENSE files in the repository root for full details.
|
|||||||
|
|
||||||
import { defineConfig } from "@playwright/test";
|
import { defineConfig } from "@playwright/test";
|
||||||
|
|
||||||
const projects = [
|
|
||||||
"macos",
|
|
||||||
"win-x64",
|
|
||||||
"win-ia32",
|
|
||||||
"win-arm64",
|
|
||||||
"linux-amd64-sqlcipher-system",
|
|
||||||
"linux-amd64-sqlcipher-static",
|
|
||||||
"linux-arm64-sqlcipher-system",
|
|
||||||
"linux-arm64-sqlcipher-static",
|
|
||||||
];
|
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// Allows the GitHub action to specify a project name (OS + arch) for the combined report to make sense
|
projects: [{ name: "Desktop" }],
|
||||||
// workaround for https://github.com/microsoft/playwright/issues/33521
|
tag: process.env.PW_TAG ? `@${process.env.PW_TAG}` : undefined,
|
||||||
projects: process.env.CI
|
|
||||||
? projects.map((name) => ({
|
|
||||||
name,
|
|
||||||
}))
|
|
||||||
: undefined,
|
|
||||||
use: {
|
use: {
|
||||||
viewport: { width: 1280, height: 720 },
|
viewport: { width: 1280, height: 720 },
|
||||||
video: "retain-on-failure",
|
video: "retain-on-failure",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||||
"projectType": "app",
|
"projectType": "application",
|
||||||
|
"implicitDependencies": ["element-web"],
|
||||||
"root": "apps/desktop",
|
"root": "apps/desktop",
|
||||||
"targets": {
|
"targets": {
|
||||||
"docker:build": {
|
"docker:build": {
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Script for downloading a branch of element-web matching the branch a PR is contributed from
|
|
||||||
|
|
||||||
set -x
|
|
||||||
|
|
||||||
deforg="element-hq"
|
|
||||||
defrepo="element-web"
|
|
||||||
|
|
||||||
# The PR_NUMBER variable must be set explicitly.
|
|
||||||
default_org_repo=${GITHUB_REPOSITORY:-"$deforg/$defrepo"}
|
|
||||||
PR_ORG=${PR_ORG:-${default_org_repo%%/*}}
|
|
||||||
PR_REPO=${PR_REPO:-${default_org_repo##*/}}
|
|
||||||
|
|
||||||
# A function that clones a branch of a repo based on the org, repo and branch
|
|
||||||
clone() {
|
|
||||||
org=$1
|
|
||||||
repo=$2
|
|
||||||
branch=$3
|
|
||||||
if [ -n "$branch" ]
|
|
||||||
then
|
|
||||||
echo "Trying to use $org/$repo#$branch"
|
|
||||||
# Disable auth prompts: https://serverfault.com/a/665959
|
|
||||||
GIT_TERMINAL_PROMPT=0 git clone https://github.com/$org/$repo.git $repo --branch "$branch" --depth 1 && exit 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "Getting info about a PR with number $PR_NUMBER"
|
|
||||||
apiEndpoint="https://api.github.com/repos/$PR_ORG/$PR_REPO/pulls/$PR_NUMBER"
|
|
||||||
head=$(curl "$apiEndpoint" | jq -r '.head.label')
|
|
||||||
|
|
||||||
# for forks, $head will be in the format "fork:branch", so we split it by ":"
|
|
||||||
# into an array. On non-forks, this has the effect of splitting into a single
|
|
||||||
# element array given ":" shouldn't appear in the head - it'll just be the
|
|
||||||
# branch name. Based on the results, we clone.
|
|
||||||
BRANCH_ARRAY=(${head//:/ })
|
|
||||||
TRY_ORG=$deforg
|
|
||||||
TRY_BRANCH=${BRANCH_ARRAY[0]}
|
|
||||||
if [[ "$head" == *":"* ]]; then
|
|
||||||
# ... but only match that fork if it's a real fork
|
|
||||||
if [ "${BRANCH_ARRAY[0]}" != "$PR_ORG" ]; then
|
|
||||||
TRY_ORG=${BRANCH_ARRAY[0]}
|
|
||||||
fi
|
|
||||||
TRY_BRANCH=${BRANCH_ARRAY[1]}
|
|
||||||
fi
|
|
||||||
clone "$TRY_ORG" "$defrepo" "$TRY_BRANCH"
|
|
||||||
|
|
||||||
exit 1
|
|
||||||
@@ -75,5 +75,8 @@ export default {
|
|||||||
nx: {
|
nx: {
|
||||||
config: ["{nx,package,project}.json", "{apps,packages,modules}/**/{package,project}.json"],
|
config: ["{nx,package,project}.json", "{apps,packages,modules}/**/{package,project}.json"],
|
||||||
},
|
},
|
||||||
|
playwright: {
|
||||||
|
config: ["playwright.config.ts", "playwright-merge.config.ts"],
|
||||||
|
},
|
||||||
tags: ["-knipignore"],
|
tags: ["-knipignore"],
|
||||||
} satisfies KnipConfig;
|
} satisfies KnipConfig;
|
||||||
|
|||||||
@@ -27,9 +27,11 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@action-validator/cli": "^0.6.0",
|
"@action-validator/cli": "^0.6.0",
|
||||||
"@action-validator/core": "^0.6.0",
|
"@action-validator/core": "^0.6.0",
|
||||||
|
"@element-hq/element-web-playwright-common": "catalog:",
|
||||||
"@nx-tools/nx-container": "^7.2.1",
|
"@nx-tools/nx-container": "^7.2.1",
|
||||||
"@nx/jest": "^22.5.0",
|
"@nx/jest": "^22.5.0",
|
||||||
"@types/node": "22",
|
"@types/node": "22",
|
||||||
|
"@playwright/test": "catalog:",
|
||||||
"cronstrue": "^3.0.0",
|
"cronstrue": "^3.0.0",
|
||||||
"eslint-plugin-matrix-org": "^3.0.0",
|
"eslint-plugin-matrix-org": "^3.0.0",
|
||||||
"husky": "^9.0.0",
|
"husky": "^9.0.0",
|
||||||
|
|||||||
+8
-8
@@ -26,7 +26,7 @@ type PaginationLinks = {
|
|||||||
|
|
||||||
// We see quite a few test flakes which are caused by the app exploding
|
// We see quite a few test flakes which are caused by the app exploding
|
||||||
// so we have some magic strings we check the logs for to better track the flake with its cause
|
// so we have some magic strings we check the logs for to better track the flake with its cause
|
||||||
const SPECIAL_CASES = {
|
const SPECIAL_CASES: Record<string, string> = {
|
||||||
"ChunkLoadError": "ChunkLoadError",
|
"ChunkLoadError": "ChunkLoadError",
|
||||||
"Unreachable code should not be executed": "Rust crypto panic",
|
"Unreachable code should not be executed": "Rust crypto panic",
|
||||||
"Out of bounds memory access": "Rust crypto memory error",
|
"Out of bounds memory access": "Rust crypto memory error",
|
||||||
@@ -37,7 +37,7 @@ class FlakyReporter implements Reporter {
|
|||||||
|
|
||||||
public onTestEnd(test: TestCase): void {
|
public onTestEnd(test: TestCase): void {
|
||||||
// Ignores flakes on Dendrite and Pinecone as they have their own flakes we do not track
|
// Ignores flakes on Dendrite and Pinecone as they have their own flakes we do not track
|
||||||
if (["Dendrite", "Pinecone"].includes(test.parent.project()?.name)) return;
|
if (["Dendrite", "Pinecone"].includes(test.parent.project()!.name!)) return;
|
||||||
let failures = [`${test.location.file.split("playwright/e2e/")[1]}: ${test.title}`];
|
let failures = [`${test.location.file.split("playwright/e2e/")[1]}: ${test.title}`];
|
||||||
if (test.outcome() === "flaky") {
|
if (test.outcome() === "flaky") {
|
||||||
const timedOutRuns = test.results.filter((result) => result.status === "timedOut");
|
const timedOutRuns = test.results.filter((result) => result.status === "timedOut");
|
||||||
@@ -46,7 +46,7 @@ class FlakyReporter implements Reporter {
|
|||||||
);
|
);
|
||||||
// If a test failed due to a systemic fault then the test is not flaky, the app is, record it as such.
|
// If a test failed due to a systemic fault then the test is not flaky, the app is, record it as such.
|
||||||
const specialCases = Object.keys(SPECIAL_CASES).filter((log) =>
|
const specialCases = Object.keys(SPECIAL_CASES).filter((log) =>
|
||||||
pageLogs.some((attachment) => attachment.name.startsWith("page-") && attachment.body.includes(log)),
|
pageLogs.some((attachment) => attachment.name.startsWith("page-") && attachment.body?.includes(log)),
|
||||||
);
|
);
|
||||||
if (specialCases.length > 0) {
|
if (specialCases.length > 0) {
|
||||||
failures = specialCases.map((specialCase) => SPECIAL_CASES[specialCase]);
|
failures = specialCases.map((specialCase) => SPECIAL_CASES[specialCase]);
|
||||||
@@ -56,7 +56,7 @@ class FlakyReporter implements Reporter {
|
|||||||
if (!this.flakes.has(title)) {
|
if (!this.flakes.has(title)) {
|
||||||
this.flakes.set(title, []);
|
this.flakes.set(title, []);
|
||||||
}
|
}
|
||||||
this.flakes.get(title).push(test);
|
this.flakes.get(title)!.push(test);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,8 +76,8 @@ class FlakyReporter implements Reporter {
|
|||||||
if (!link) return map;
|
if (!link) return map;
|
||||||
const matches = link.matchAll(/(<(?<link>.+?)>; rel="(?<type>.+?)")/g);
|
const matches = link.matchAll(/(<(?<link>.+?)>; rel="(?<type>.+?)")/g);
|
||||||
for (const match of matches) {
|
for (const match of matches) {
|
||||||
const { link, type } = match.groups;
|
const { link, type } = match.groups!;
|
||||||
map[type] = link;
|
map[type as keyof PaginationLinks] = link;
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
@@ -102,9 +102,9 @@ class FlakyReporter implements Reporter {
|
|||||||
issues.push(...fetchedIssues);
|
issues.push(...fetchedIssues);
|
||||||
|
|
||||||
// Get the next link for fetching more results
|
// Get the next link for fetching more results
|
||||||
const linkHeader = issuesResponse.headers.get("Link");
|
const linkHeader = issuesResponse.headers.get("Link")!;
|
||||||
const parsed = this.parseLinkHeader(linkHeader);
|
const parsed = this.parseLinkHeader(linkHeader);
|
||||||
url = parsed.next;
|
url = parsed.next!;
|
||||||
}
|
}
|
||||||
return issues;
|
return issues;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2026 Element Creations Ltd.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||||
|
Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { defineConfig } from "@playwright/test";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
// Playwright only supports merging using a single testDir, specifying web here
|
||||||
|
// means that some parts of the report for Desktop will be incorrect, but this is minor.
|
||||||
|
// https://github.com/microsoft/playwright/issues/39855
|
||||||
|
testDir: "apps/web/playwright/e2e",
|
||||||
|
reporter: [
|
||||||
|
["html", { open: "never" }],
|
||||||
|
["./packages/playwright-common/flaky-reporter.ts"],
|
||||||
|
["@element-hq/element-web-playwright-common/lib/stale-screenshot-reporter.js"],
|
||||||
|
],
|
||||||
|
});
|
||||||
Generated
+23
-10
@@ -135,12 +135,18 @@ importers:
|
|||||||
'@action-validator/core':
|
'@action-validator/core':
|
||||||
specifier: ^0.6.0
|
specifier: ^0.6.0
|
||||||
version: 0.6.0
|
version: 0.6.0
|
||||||
|
'@element-hq/element-web-playwright-common':
|
||||||
|
specifier: 'catalog:'
|
||||||
|
version: 2.2.7(@element-hq/element-web-module-api@1.12.0(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4))(@playwright/test@1.58.2)(playwright-core@1.58.2)
|
||||||
'@nx-tools/nx-container':
|
'@nx-tools/nx-container':
|
||||||
specifier: ^7.2.1
|
specifier: ^7.2.1
|
||||||
version: 7.2.1(@nx/devkit@22.5.3(nx@22.5.4))(@nx/js@22.5.3(@babel/traverse@7.29.0)(nx@22.5.4))(dotenv@17.3.1)(nx@22.5.4)(tslib@2.8.1)
|
version: 7.2.1(@nx/devkit@22.5.3(nx@22.5.4))(@nx/js@22.5.3(@babel/traverse@7.29.0)(nx@22.5.4))(dotenv@17.3.1)(nx@22.5.4)(tslib@2.8.1)
|
||||||
'@nx/jest':
|
'@nx/jest':
|
||||||
specifier: ^22.5.0
|
specifier: ^22.5.0
|
||||||
version: 22.5.3(@babel/traverse@7.29.0)(@types/node@18.19.130)(babel-plugin-macros@3.1.0)(nx@22.5.4)(typescript@5.9.3)
|
version: 22.5.3(@babel/traverse@7.29.0)(@types/node@18.19.130)(babel-plugin-macros@3.1.0)(nx@22.5.4)(typescript@5.9.3)
|
||||||
|
'@playwright/test':
|
||||||
|
specifier: 'catalog:'
|
||||||
|
version: 1.58.2
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: 18.19.130
|
specifier: 18.19.130
|
||||||
version: 18.19.130
|
version: 18.19.130
|
||||||
@@ -179,10 +185,10 @@ importers:
|
|||||||
version: 5.9.3
|
version: 5.9.3
|
||||||
vitepress:
|
vitepress:
|
||||||
specifier: ^1.6.4
|
specifier: ^1.6.4
|
||||||
version: 1.6.4(@algolia/client-search@5.50.0)(@types/node@18.19.130)(@types/react@19.2.10)(axios@1.13.5)(jwt-decode@4.0.0)(lightningcss@1.32.0)(postcss@8.5.8)(qrcode@1.5.4)(search-insights@2.17.3)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(typescript@5.9.3)
|
version: 1.6.4(@algolia/client-search@5.50.0)(@types/node@18.19.130)(@types/react@19.2.10)(axios@1.13.5)(jwt-decode@4.0.0)(lightningcss@1.32.0)(postcss@8.5.8)(qrcode@1.5.4)(react@19.2.4)(search-insights@2.17.3)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(typescript@5.9.3)
|
||||||
vitepress-plugin-mermaid:
|
vitepress-plugin-mermaid:
|
||||||
specifier: ^2.0.17
|
specifier: ^2.0.17
|
||||||
version: 2.0.17(mermaid@11.13.0)(vitepress@1.6.4(@algolia/client-search@5.50.0)(@types/node@18.19.130)(@types/react@19.2.10)(axios@1.13.5)(jwt-decode@4.0.0)(lightningcss@1.32.0)(postcss@8.5.8)(qrcode@1.5.4)(search-insights@2.17.3)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(typescript@5.9.3))
|
version: 2.0.17(mermaid@11.13.0)(vitepress@1.6.4(@algolia/client-search@5.50.0)(@types/node@18.19.130)(@types/react@19.2.10)(axios@1.13.5)(jwt-decode@4.0.0)(lightningcss@1.32.0)(postcss@8.5.8)(qrcode@1.5.4)(react@19.2.4)(search-insights@2.17.3)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(typescript@5.9.3))
|
||||||
yaml:
|
yaml:
|
||||||
specifier: 2.8.3
|
specifier: 2.8.3
|
||||||
version: 2.8.3
|
version: 2.8.3
|
||||||
@@ -11457,6 +11463,10 @@ packages:
|
|||||||
sanitize-html@2.17.1:
|
sanitize-html@2.17.1:
|
||||||
resolution: {integrity: sha512-ehFCW+q1a4CSOWRAdX97BX/6/PDEkCqw7/0JXZAGQV57FQB3YOkTa/rrzHPeJ+Aghy4vZAFfWMYyfxIiB7F/gw==}
|
resolution: {integrity: sha512-ehFCW+q1a4CSOWRAdX97BX/6/PDEkCqw7/0JXZAGQV57FQB3YOkTa/rrzHPeJ+Aghy4vZAFfWMYyfxIiB7F/gw==}
|
||||||
|
|
||||||
|
sax@1.4.4:
|
||||||
|
resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==}
|
||||||
|
engines: {node: '>=11.0.0'}
|
||||||
|
|
||||||
sax@1.6.0:
|
sax@1.6.0:
|
||||||
resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==}
|
resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==}
|
||||||
engines: {node: '>=11.0.0'}
|
engines: {node: '>=11.0.0'}
|
||||||
@@ -14541,9 +14551,9 @@ snapshots:
|
|||||||
|
|
||||||
'@docsearch/css@3.8.2': {}
|
'@docsearch/css@3.8.2': {}
|
||||||
|
|
||||||
'@docsearch/js@3.8.2(@algolia/client-search@5.50.0)(@types/react@19.2.10)(search-insights@2.17.3)':
|
'@docsearch/js@3.8.2(@algolia/client-search@5.50.0)(@types/react@19.2.10)(react@19.2.4)(search-insights@2.17.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@docsearch/react': 3.8.2(@algolia/client-search@5.50.0)(@types/react@19.2.10)(search-insights@2.17.3)
|
'@docsearch/react': 3.8.2(@algolia/client-search@5.50.0)(@types/react@19.2.10)(react@19.2.4)(search-insights@2.17.3)
|
||||||
preact: 10.28.3
|
preact: 10.28.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@algolia/client-search'
|
- '@algolia/client-search'
|
||||||
@@ -14552,7 +14562,7 @@ snapshots:
|
|||||||
- react-dom
|
- react-dom
|
||||||
- search-insights
|
- search-insights
|
||||||
|
|
||||||
'@docsearch/react@3.8.2(@algolia/client-search@5.50.0)(@types/react@19.2.10)(search-insights@2.17.3)':
|
'@docsearch/react@3.8.2(@algolia/client-search@5.50.0)(@types/react@19.2.10)(react@19.2.4)(search-insights@2.17.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0)(search-insights@2.17.3)
|
'@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0)(search-insights@2.17.3)
|
||||||
'@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0)
|
'@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.50.0)(algoliasearch@5.50.0)
|
||||||
@@ -14560,6 +14570,7 @@ snapshots:
|
|||||||
algoliasearch: 5.50.0
|
algoliasearch: 5.50.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 19.2.10
|
'@types/react': 19.2.10
|
||||||
|
react: 19.2.4
|
||||||
search-insights: 2.17.3
|
search-insights: 2.17.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@algolia/client-search'
|
- '@algolia/client-search'
|
||||||
@@ -19317,7 +19328,7 @@ snapshots:
|
|||||||
builder-util-runtime@9.5.1:
|
builder-util-runtime@9.5.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
sax: 1.6.0
|
sax: 1.4.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@@ -25261,6 +25272,8 @@ snapshots:
|
|||||||
parse-srcset: 1.0.2
|
parse-srcset: 1.0.2
|
||||||
postcss: 8.5.8
|
postcss: 8.5.8
|
||||||
|
|
||||||
|
sax@1.4.4: {}
|
||||||
|
|
||||||
sax@1.6.0: {}
|
sax@1.6.0: {}
|
||||||
|
|
||||||
saxes@6.0.0:
|
saxes@6.0.0:
|
||||||
@@ -26687,17 +26700,17 @@ snapshots:
|
|||||||
tsx: 4.21.0
|
tsx: 4.21.0
|
||||||
yaml: 2.8.3
|
yaml: 2.8.3
|
||||||
|
|
||||||
vitepress-plugin-mermaid@2.0.17(mermaid@11.13.0)(vitepress@1.6.4(@algolia/client-search@5.50.0)(@types/node@18.19.130)(@types/react@19.2.10)(axios@1.13.5)(jwt-decode@4.0.0)(lightningcss@1.32.0)(postcss@8.5.8)(qrcode@1.5.4)(search-insights@2.17.3)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(typescript@5.9.3)):
|
vitepress-plugin-mermaid@2.0.17(mermaid@11.13.0)(vitepress@1.6.4(@algolia/client-search@5.50.0)(@types/node@18.19.130)(@types/react@19.2.10)(axios@1.13.5)(jwt-decode@4.0.0)(lightningcss@1.32.0)(postcss@8.5.8)(qrcode@1.5.4)(react@19.2.4)(search-insights@2.17.3)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(typescript@5.9.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
mermaid: 11.13.0
|
mermaid: 11.13.0
|
||||||
vitepress: 1.6.4(@algolia/client-search@5.50.0)(@types/node@18.19.130)(@types/react@19.2.10)(axios@1.13.5)(jwt-decode@4.0.0)(lightningcss@1.32.0)(postcss@8.5.8)(qrcode@1.5.4)(search-insights@2.17.3)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(typescript@5.9.3)
|
vitepress: 1.6.4(@algolia/client-search@5.50.0)(@types/node@18.19.130)(@types/react@19.2.10)(axios@1.13.5)(jwt-decode@4.0.0)(lightningcss@1.32.0)(postcss@8.5.8)(qrcode@1.5.4)(react@19.2.4)(search-insights@2.17.3)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(typescript@5.9.3)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@mermaid-js/mermaid-mindmap': 9.3.0
|
'@mermaid-js/mermaid-mindmap': 9.3.0
|
||||||
|
|
||||||
vitepress@1.6.4(@algolia/client-search@5.50.0)(@types/node@18.19.130)(@types/react@19.2.10)(axios@1.13.5)(jwt-decode@4.0.0)(lightningcss@1.32.0)(postcss@8.5.8)(qrcode@1.5.4)(search-insights@2.17.3)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(typescript@5.9.3):
|
vitepress@1.6.4(@algolia/client-search@5.50.0)(@types/node@18.19.130)(@types/react@19.2.10)(axios@1.13.5)(jwt-decode@4.0.0)(lightningcss@1.32.0)(postcss@8.5.8)(qrcode@1.5.4)(react@19.2.4)(search-insights@2.17.3)(sugarss@5.0.1(postcss@8.5.8))(terser@5.46.0)(typescript@5.9.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@docsearch/css': 3.8.2
|
'@docsearch/css': 3.8.2
|
||||||
'@docsearch/js': 3.8.2(@algolia/client-search@5.50.0)(@types/react@19.2.10)(search-insights@2.17.3)
|
'@docsearch/js': 3.8.2(@algolia/client-search@5.50.0)(@types/react@19.2.10)(react@19.2.4)(search-insights@2.17.3)
|
||||||
'@iconify-json/simple-icons': 1.2.75
|
'@iconify-json/simple-icons': 1.2.75
|
||||||
'@shikijs/core': 2.5.0
|
'@shikijs/core': 2.5.0
|
||||||
'@shikijs/transformers': 2.5.0
|
'@shikijs/transformers': 2.5.0
|
||||||
|
|||||||
@@ -18,11 +18,13 @@ sonar.coverage.exclusions=\
|
|||||||
apps/web/scripts/**/*,\
|
apps/web/scripts/**/*,\
|
||||||
apps/desktop/scripts/**/*,\
|
apps/desktop/scripts/**/*,\
|
||||||
apps/desktop/playwright/**/*,\
|
apps/desktop/playwright/**/*,\
|
||||||
|
apps/desktop/hak/**/*,\
|
||||||
scripts/**/*,\
|
scripts/**/*,\
|
||||||
apps/web/src/components/views/dialogs/devtools/**/*,\
|
apps/web/src/components/views/dialogs/devtools/**/*,\
|
||||||
apps/web/src/utils/SessionLock.ts,\
|
apps/web/src/utils/SessionLock.ts,\
|
||||||
apps/web/src/**/*.d.ts,\
|
apps/web/src/**/*.d.ts,\
|
||||||
apps/web/src/vector/mobile_guide/**/*,\
|
apps/web/src/vector/mobile_guide/**/*,\
|
||||||
packages/shared-components/src/test/**/*,\
|
packages/shared-components/src/test/**/*,\
|
||||||
packages/shared-components/src/**/*.stories.tsx
|
packages/shared-components/src/**/*.stories.tsx,\
|
||||||
|
packages/playwright-common/**/*
|
||||||
sonar.testExecutionReportPaths=apps/web/coverage/jest-sonar-report.xml
|
sonar.testExecutionReportPaths=apps/web/coverage/jest-sonar-report.xml
|
||||||
|
|||||||
Reference in New Issue
Block a user