Compare commits

...

577 Commits

Author SHA1 Message Date
rbondesson bb4a7e9613 Move RovingTabIndex to shared component and use it in ActionBarView (#33263)
Build / Build on ubuntu-24.04 (push) Failing after 42s
Build and Deploy develop / Build & Deploy develop.element.io (push) Has been skipped
Deploy documentation / GitHub Pages (push) Failing after 35s
Deploy documentation / deploy (push) Has been skipped
Publish shared component storybook / Build storybook (push) Failing after 3m4s
Publish shared component storybook / Publish storybook (push) Has been skipped
Shared Component Visual Tests / Run Visual Tests (push) Failing after 49s
Static Analysis / Docs (push) Failing after 38s
Static Analysis / ESLint (push) Failing after 28s
Static Analysis / Analyse Dead Code (push) Failing after 44s
Static Analysis / Prettier (push) Failing after 36s
Static Analysis / Style Lint (push) Failing after 38s
Static Analysis / Typescript Syntax Check (push) Failing after 38s
Static Analysis / Workflow Lint (push) Failing after 42s
Static Analysis / Rethemendex Check (push) Failing after 41s
Static Analysis / Zizmor Github Actions lint (push) Failing after 37s
Static Analysis / i18n Check (Element Desktop) (push) Failing after 0s
Static Analysis / i18n Check (Shared Components) (push) Failing after 0s
Static Analysis / i18n Check (Element Web) (push) Failing after 0s
Static Analysis / Static Analysis (push) Successful in 1s
Build / Build on macos-14 (push) Has been cancelled
Build / Build on windows-2022 (push) Has been cancelled
* Create a new shared component and a wrapper in app/web

* Move unit tests and add new for better coverage

* Refactor ActionBarView to use the RovingTabIndexProvider

* Clean up the interface and adjust callers

* Added documentation and renamed type for better readabililty

* Reverting the clean up of IContext

* Fix Sonar issues

* More Sonar issus fixed
2026-04-23 09:33:32 +00:00
Michael Telatynski 1a6b0e22a1 Add CI to detect stale vis screenshots (#33274)
* Add CI to detect stale vis screenshots

* Remove already installed `tree` command

* Remove workaround for vis silently adding missing screenshots in CI

* Fix stale screenshot detection

* Test that CI doesn't silently create new screenshots

* Discard changes to packages/shared-components/src/room/composer/Banner/Banner.stories.tsx

* Delete stale snapshots
2026-04-23 09:24:31 +00:00
Michael Telatynski 8f9953f419 Fix flaky test src/room/composer/Banner/Banner.stories.tsx > With Avatar Image (#33275)
* Fix flaky test `src/room/composer/Banner/Banner.stories.tsx > With Avatar Image`

it was previously loading an external (slow) image which was random (!) by design

Fixes https://github.com/element-hq/element-web/issues/33273

* Fix styling

* Iterate

* Update snapshot
2026-04-23 08:26:48 +00:00
Michael Telatynski 12df09bd4b Move playwright-common wait-on from devDependencies to dependencies (#33272)
as it is needed by the `playwright-screenshots.sh` script which is exposed to dependants
2026-04-23 07:51:39 +00:00
Richard van der Hoff cd515444a8 Confirm before inviting unknown users to a DM/room (#33171)
* InviteDialog: factor out startDmOrSendInvites

Factor out the logic of calling `startDm` or `inviteUsers` to a helper
function. We're going to need to call this from a second location soon, so this
is useful groundwork.

* Add `UnknownIdentityUsersWarningDialog`

* Add unit tests

* Update playwright tests

* Convert if/else to switch statement

* Convert helper functions to React components

* Factor out "onRemove" callback

* Add clarifying comment
2026-04-22 20:05:31 +00:00
Florian Duros f4c62abbcd Room list: assign room to custom section (#33238)
* feat(sc): add new toast type for room list

* feat(sc): add section entries in room list item menu

* feat(rls): expose util functions

* feat: allows to tag room with custom sections

* feat(vm): add new Chat moved toast to room list vm

* feat(vm): add section selection to room list item vm

* feat(e2e): add tests for adding room in a custom section

* test(e2e): update existing screenshots

* chore: fix lint after merge

* chore: remove outline in test
2026-04-22 19:50:54 +00:00
Richard van der Hoff 73e1b87075 Sonar: exclude tests from duplication check (#33271)
* Sonar: exclude tests from duplication check

* cleanup

* more cleanup
2026-04-22 15:54:41 +00:00
Michael Telatynski 4b4289e211 Implement new design for Welcome page (#33211)
* Convert welcome.html to React component

In advance of changes to use Compound

* Fix types

* Fix tests

* Update styling to match Figma

* Fix random capitalisation

* Tweak styling

* Regenerate i18n

* Update tests

* Make linter happy

* Iterate
2026-04-22 15:32:05 +00:00
renovate[bot] 7b89d84acb Update npm non-major dependencies (#33246)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 13:44:05 +00:00
Will Hunt 9df7182c0c Redesign link previews (#33061)
* Commit design update

* Add figma links

* Check in other changes

* revert accidental change

* Iterative update

* linting n test fiddles

* linting

* Cleanup

* update snaps

* Move URL previews to new home

* Fix paths

* compress img

* Add back all the stories

* Improved rendering

* Fixup

* Update previews again

* lint

* update stories

* Update snaps again

* More screenshots

* Also these

* Update snaps

* include site name

* Update snaps again

* Use a scale so the images don't go blur

* update snaps again

* Update snaps

* remove mistaken playwright cfg

* update pw snaps

* update snap

* update previews

* Update with new designs

* Update screenshots
2026-04-22 13:23:24 +00:00
renovate[bot] 2d16498fe6 Update dependency typescript to v6 (#32927)
* Update dependency typescript to v6

* Switch to unplugin-vts

Workaround for https://github.com/qmhc/unplugin-dts/issues/467

And tweak tsconfigs

* tweak tsconfig

* Make tsc happy

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-22 12:28:54 +00:00
renovate[bot] 021e222719 Update nginxinc/nginx-unprivileged:alpine-slim Docker digest to 360465d (#33231)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 12:26:26 +00:00
Florian Duros 9df9fb9428 Room list: scroll to newly creation section (#33210)
* feat(rls): emit tag when section is created

* feat(vm): scroll to newly section tag

* feat(view): scroll to new section
2026-04-22 12:21:41 +00:00
Michael Telatynski 29411f0ded Speed up PR CI (#33239)
* Speed up PR CI

By skipping some desktop tests in pull requests and instead only running them in the Merge Queue

* Fix comment
2026-04-22 10:55:29 +00:00
Michael Telatynski 5fc98d0a36 Add stopUpdatingLabel to Renovate configuration (#33237) 2026-04-22 10:15:42 +00:00
renovate[bot] a08c34142f Update dependency vite to v8 (#33252)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 08:48:19 +00:00
renovate[bot] 44a2c9936d Update react (#33247)
* Update react

* Pin back react-resizeable-panels as it overwrites onFocus/onBlur

* Roll back react-resizable panels fully

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-22 08:44:21 +00:00
Michael Telatynski f0eb95495e Renovate group resolutions/overrides separately (#33260)
* Renovate group resolutions/overrides separately

* Update pnpm resolutions to pnpm overrides

* Update pnpm overrides group configuration

* Update Renovate configuration for pnpm overrides

* Update renovate.json

* Update renovate.json

* Update renovate.json

* Fix formatting in renovate.json for groupSlug

* Update renovate.json
2026-04-22 09:01:43 +00:00
renovate[bot] 4437dadef6 Update dependency storybook-addon-vis to v4 (#33251)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 08:30:27 +00:00
ElementRobot 193cdff562 [create-pull-request] automated change (#33262)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2026-04-22 08:24:30 +00:00
renovate[bot] d01f40bf27 Update dependency html-react-parser to v6 (#33250)
* Update dependency html-react-parser to v6

* Fix renderer utils

* Fix CodeBlock similarly

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-21 22:20:09 +00:00
renovate[bot] 1a87865134 Update vite (#33258)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-21 22:13:01 +00:00
renovate[bot] 764892bd41 Update tj-actions/changed-files action to v47 (#33259)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 21:49:44 +00:00
Michael Telatynski fb263ee511 Fix Module API versioning (#33233)
* Fix Module API versioning

* Attempt #2
2026-04-21 21:47:07 +00:00
renovate[bot] 8fa7b5ca2c Update dependency babel-loader to v10.1.1 (#33235)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 20:31:17 +00:00
renovate[bot] e568ed8aac Update dependency caniuse-lite to v1.0.30001788 (#33245)
* Update dependency caniuse-lite to v1.0.30001788

* Update tests

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-21 20:27:27 +00:00
renovate[bot] abb014553b Update peter-evans/create-pull-request digest to 5f6978f (#33256)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 20:09:23 +00:00
renovate[bot] ae8769e12d Update dependency uuid to v14 (#33229)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 19:49:00 +00:00
renovate[bot] fd86405338 Update sigstore/cosign-installer action to v4 (#33253)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 19:42:42 +00:00
renovate[bot] a0195fc4d6 Update dependency @vector-im/compound-web to v9 (#33249)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 19:40:28 +00:00
renovate[bot] ced3c25785 Update Node.js to d2059a9 (#33243)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 19:39:41 +00:00
renovate[bot] 370d2ec7d2 Update Node.js to d1b3b4d (#33242)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 19:39:27 +00:00
renovate[bot] 14917f9df5 Update robinraju/release-downloader digest to 28fc21f (#33244)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 19:38:30 +00:00
renovate[bot] 6423f2d8c0 Update dependency electron to v41.2.2 (#33254)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 19:34:49 +00:00
renovate[bot] feae8ed8b5 Update eslint-plugins (#33248)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 19:32:26 +00:00
renovate[bot] 549bdb8cb7 Update ghcr.io/element-hq/synapse:develop Docker digest to b2fec2c (#33241)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 19:31:26 +00:00
renovate[bot] e1b62c3370 Update css (#33234)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 19:28:54 +00:00
Michael Telatynski 354a05d89f Remove dependency on uuid (#33230)
* Remove dependency on `uuid`

* Delint
2026-04-21 16:36:27 +00:00
renovate[bot] 86ea6bd6b9 Update rust:bullseye Docker digest to 949b090 (#33232)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 15:22:24 +00:00
renovate[bot] a054e785ea Update docker.io/docker/dockerfile Docker tag to v1.23 (#33236)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 15:22:08 +00:00
renovate[bot] 42009ce6ec Update vite (#33224)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 14:47:42 +00:00
renovate[bot] 356119da79 Update dependency @axe-core/playwright to v4.11.2 (#33223)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 14:32:50 +00:00
renovate[bot] d823d633e3 Update dependency sanitize-filename to v1.6.4 (#33227)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 14:19:54 +00:00
Richard van der Hoff 1f6d1dbc0d Avoid nx jest executor for running unit tests (#33220)
* Avoid nx jest executor for running unit tests

The jest executor mangles the "summary of failing tests" from jest.

* Remove unneded dep on nx/jest
2026-04-21 14:07:54 +00:00
renovate[bot] 12a3abc0d5 Update dependency @element-hq/element-call-embedded to v0.19.1 (#33225)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 14:03:32 +00:00
renovate[bot] e90bc4a2f3 Update electron-builder to v26.9.0 (#33222)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 14:00:02 +00:00
renovate[bot] 0d9f205505 Update webpack (#33228)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 13:10:20 +00:00
renovate[bot] ac9ef6c2a2 Update Node.js to v24.15.0 (#33226)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 12:55:05 +00:00
renovate[bot] 4c474f5639 Update electron (#33221)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 12:48:56 +00:00
Richard van der Hoff 3f3ed93b8a nx test:playwright:screenshots: only do snapshots for Chrome (#33216)
* nx test:playwright:screenshots: only do snapshots for Chrome

`nx` eats the `--project` option unless we prefix with `--`.

* Apply suggestion from @richvdh
2026-04-21 11:34:22 +00:00
Michael Telatynski 133a56da65 Playwright docker improvements (#33213)
* Clean up playwright-common Dockerfile

* Speed up element-web docker build

* Wire up element-desktop playwright tests via nx

* Better debug logs for Element Desktop playwright in CI

* Iterate

* Iterate

* Fix element-desktop screenshot docker

* @electron/fuses

* Partial revert
2026-04-21 09:58:16 +00:00
mxandreas b06422d848 Updates to contribution guide for new features. (#33187)
* Updates to contribution guide for new features.

* Update CONTRIBUTING.md

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>

* Some final touches.

* Linter/prettier fixes.

---------

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-21 09:40:34 +00:00
renovate[bot] 2c58f82298 Update dependency @nx/jest to v22.6.5 (#33206)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 08:46:49 +00:00
renovate[bot] 384adea5a2 Update dependency @casualbot/jest-sonar-reporter to v2.6.0 (#33205)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 09:38:03 +00:00
renovate[bot] cb6c48a493 Update actions/setup-node digest to 48b55a0 (#33201)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 09:27:13 +00:00
renovate[bot] 73b8b51ea5 Update ghcr.io/element-hq/element-web:latest Docker digest to c7fa40b (#33202)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 08:31:47 +00:00
renovate[bot] e8db72d81a Update storybook (#33207)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 08:27:57 +00:00
renovate[bot] 106b0e09ae Update dependency typedoc to v0.28.19 (#33204)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 08:25:42 +00:00
renovate[bot] 8253d64021 Update testcontainers docker digests (#33203)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 08:22:48 +00:00
ElementRobot 9428c10284 [create-pull-request] automated change (#33200)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2026-04-20 07:48:45 +00:00
Richard van der Hoff e58e803368 Update to compound 9.2.0 (#33173)
* Upgrade to compound 9.2.0

... to pick up the export of PageHeader

* update snapshots

* update shared-components snapshots

* More snapshot updates

* update snapshot

* GHA: Show disk usage on failure
2026-04-17 15:51:43 +00:00
Richard van der Hoff aeaa73adf6 Fix flaky OIDC "verifiy dialog" test (#33188)
This test was flaking. The problem appears to have been that we were clicking
"Continue" twice in succession; the intention was that we click on two
*different* "Continue" buttons, but sometimes we ended up clicking in the same
one twice.

Fix it by waiting for the content to change after the first click.

Fixes: #31316
2026-04-17 13:37:20 +00:00
Michael Telatynski 8834438a20 Add apps/desktop/deploy to Prettier ignore (#33185) 2026-04-17 12:23:24 +00:00
Florian Duros 6b67b24254 Room list: add custom section creation (#33155)
* feat: add creation section dialog

* feat: add in skip list a method to change filters

* feat: add helper to creation section

* feat: add custom sections data to Settings

* feat: add custom section to room list store v3

* feat: update header and room list item vms

* feat: add toast to room list vm

* feat: add new translation

* chore: move util functions of room list specs

* test: add custom section playwright tests

* chore: call loadCustomSections in RoomListStoreV3 ctor
2026-04-17 12:02:42 +00:00
adis veletanlic 73d4b63ada Fix crashes in when opening Bridges in room settings (#33137)
* use SDKContext for room settings dialog to avoid crash #33107

* format with prettier

* add SDKContext to RoomSettingsDialog test
2026-04-17 11:36:40 +00:00
adis veletanlic 1044a95687 fix(call): leave call along with room (#33162)
* make sure to disconnect from possibly active calls for a room when leaving the room

* log error on log call

* Update apps/web/src/utils/leave-behaviour.ts

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>

* fix wrong logger import

* hang up calls properly on empty rooms for both legacy and element calls (listen for room event and leave call if only one member left). add tests for both legacy and element calls.

* format Call-test.ts

* revert async on function def

* revert Call.ts and Call-test.ts. Wrap legacy call hangup in try

---------

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-17 10:58:15 +00:00
Andy Balaam abae870b83 Improve the toasts fixture of the playwright-common tools (#33158)
* Improve the toasts fixture of the playwright-common tools

* Increase @element-hq/element-web-playwright-common version to 3.2.0

* Default to 2 second wait for IfExists variants

* Set playwright-common version to 4.0.0 due to breaking change

* Move handleToast into a free function

* Rename handleToast to clickToastButton

* Document new param on clickToastButton
2026-04-17 09:15:22 +00:00
Michael Telatynski 4afba408c0 Satisfy pnpm audit (#33142) 2026-04-17 09:01:27 +00:00
ElementRobot c3e82cf33b [create-pull-request] automated change (#33182)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2026-04-17 07:08:28 +00:00
renovate[bot] 3b1b39f822 Update dependency sanitize-html to v2.17.3 [SECURITY] (#33180)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 21:59:40 +00:00
Richard van der Hoff cf4b8744ab Configuration for nx output under playwright (#33177)
When playwright starts the development web server, have it tell nx to use the
`stream` output style, which is somewhat clearer than the
default. (Specifically, it distinguishes between output from different tasks,
so you can see where any errors are coming from.)
2026-04-16 16:29:32 +00:00
Richard van der Hoff aadf760e3c Factor DMRoomTile out to its own file (#33170)
I'm going to use this from a new component
2026-04-16 16:19:52 +00:00
Richard van der Hoff 733755abb2 Annotate output from playwright-screenshots scripts (#33176)
... to make it easier to see where it is coming from

Also, add a blank line before starting playwright itself
2026-04-16 15:26:04 +00:00
Richard van der Hoff 9c09a1b731 Add analytics config to nx (#33175)
* Add `analytics` config to nx

There doesn't seem to be any way to stop nx wanting to add this config setting,
so I think we just have to add it.

* Update nx.json
2026-04-16 15:25:52 +00:00
Michael Telatynski 30f442208a Fix React hydration issues (#32958)
* Add more playwright axe tests to settings dialogs

* Add utility to jest setupTests to detect React hydration errors

* Iterate jest utility

* Fix axe issue heading-order

* Fix div-in-p issues

* Fix setupTests.ts

* Fix heading order

* Make types happier

* Fix hydration issues of thead containing text nodes

* Update tests

* Fix form-in-form React hydration issues

* Fix li-in-li React hydration issues

* Fix checked in form without onChange React hydration issue

* Fix styling bleeding from _common.pcss

* Update snapshots

* Fix more remaining issues

* Remove _common.pcss h2 rule altogether

* Fix test

* Update snapshots

* Iterate

* Iterate

* Update snapshots

* Simplify diff

* Test

* Update screenshots

* Update screenshot
2026-04-16 13:35:40 +00:00
Florian Duros d7f5546294 Room list: add custom section creation in SC (#33138)
* feat: add way to create custom section in SC

* feat: disable custom section in vms

* chore: include design tokens icons in vitest config

* test: update screenshot

* chore: use one react import
2026-04-16 13:14:10 +00:00
Michael Telatynski 64d3802efe Fall back to OIDC response_mode query if fragment unsupported (#33169)
* Fall back to OIDC response_mode query if fragment unsupported

* Tidy comments

* Fix test
2026-04-16 11:07:39 +00:00
Richard van der Hoff 583eae63f7 Simplifications in InviteDialog (#33156)
* InviteDialog: simplify users section for CallTransferDialog

The majority of `renderMainTab` is enpty for the call transfer dialog, so we
may as well inkine the bits that aren't.

* Simplify `renderMainTab`

Now that this is unused for CallTransfer, we can simplify

* Remove redundant eslint-disable

eslint seems happy without this, and we shouldn't be disabling lints for a
whole file anyway
2026-04-16 09:03:26 +00:00
Zack d4aea25600 Phase 1 Refactor MImageBody to shared component (#33093)
* Phase 1 Refactor MImageBody to shared component

* blurhash package added into shared components

* Added image snapshots

* Correct the GIF label css design

* Update snapshot for GIF

* crop image correctly

* Update snapshot to reflect updates

* typo fix

* update css to compund variables

* Added tsdoc to function

* Fix inaccurate css and text values in stories

* use const enum instead

* Add i18n to shared components + added string

* Correct css comment information

* Update lockfile
2026-04-16 08:59:32 +00:00
renovate[bot] aa0abdb43a Update dependency matrix-seshat to v4.2.0 (#33168)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 08:50:54 +00:00
renovate[bot] 3e63216822 Update cloudflare/wrangler-action digest to 9acf94a (#33167)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 08:41:26 +00:00
Michael Telatynski 475b89ec46 Update check-regexp to exclude 'Report results'
As this runs on workflow_run so gets clobbered by non-develop runs
2026-04-16 09:55:27 +01:00
Michael Telatynski b495628e6f Fix element-web start not building module-api (#33161) 2026-04-16 07:58:43 +00:00
Richard van der Hoff ef5fad8d6a BaseDialog: fix comment (#33159)
This comment was a half-truth
2026-04-15 15:57:40 +00:00
renovate[bot] 93ab87c4a1 Migrate Renovate config (#33160)
* Migrate config .github/renovate.json

* Prettier

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-15 15:53:22 +00:00
Michael Telatynski e8b4b9b6ed Teach renovate about hakDependencies (#33147)
* Teach renovate about hakDependencies

* Update testcontainers-docker slug
2026-04-15 14:56:49 +00:00
renovate[bot] 421fbe4a52 Update storybook (#33125)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-15 10:33:42 +00:00
renovate[bot] 35b9b12eae Update nx to v22.6.5 (#33124)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-15 09:36:09 +00:00
Michael Telatynski de4a1e6d35 Switch OIDC to response_mode=fragment (#33100)
* Refactor: kill off `parseQs` in favour of URLSearchParams

* Consolidate app-load url parameter handling

* Switch to responseMode=fragment
2026-04-15 09:35:02 +00:00
Michael Telatynski 5475edbbc5 Fix layered.sh linking js-sdk incorrectly (#33143)
* Simplify layered.sh

pnpm link already installs dependencies, this was causing the prepare script to run twice

* Improve logging in fetchdep and make linter happier

* Fix incorrectly linking js-sdk
2026-04-15 08:59:27 +00:00
renovate[bot] dfdd438ae6 Update eslint-plugins (#33123)
* Update eslint-plugins

* Hold back esbuild to unbreak vitepress

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-15 08:48:15 +00:00
ElementRobot c106abd721 [create-pull-request] automated change (#33092)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2026-04-15 08:35:12 +00:00
Michael Telatynski 181b06b3c8 Fix static analysis CI gate not working (#33146)
* Debug CI

* Debug CI

* Fix ci final job

* Revert test change
2026-04-14 20:14:28 +00:00
renovate[bot] b63c3646bd Update docker (#33145)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-14 15:40:35 +00:00
Michael Telatynski 201f5dfd90 Fix build-and-test.yaml skip behaviour for downstream runs 2026-04-14 16:22:48 +01:00
Zack 80cf9e5b4a Shared Components Restructure, Cherry Picked | Room Shell Structure (#32917)
* refactor(shared-components): move composer and right-panel tree

* refactor: cleanup remaining structure leftovers

* test(shared-components): add room shell visual baselines

* Correct Path
2026-04-14 13:20:15 +00:00
Michael Telatynski cc9549da0a Skip bulk of CI in pull_request renovate runs (#33141)
* Skip bulk of CI in pull_request renovate runs

Relying instead on running the full suite in the merge queue to lower the impact of Renovate on the github actions concurrency limits in the org

* Iterate
2026-04-14 13:17:32 +00:00
Michael Telatynski 9151640d40 Exclude binary files from Sonar analysis (#33144)
* Exclude png files from Sonar analysis

They just cause errors

`11:39:29.466 WARN  Invalid character encountered in file /home/runner/work/element-web/element-web/apps/web/res/vector-icons/152.png at line 1 for encoding UTF-8. Please fix file content or configure the encoding to be used using property 'sonar.sourceEncoding'.`

* Modify sonar-project.properties for exclusions

Updated sonar.exclusions to include additional file types.
2026-04-14 13:15:36 +00:00
Zack f615968835 Refactoring readMarkerForEvent into ReadMarkerView in shared-components (#32777)
* Refactoring readMarkerForEvent  into ReadMarketView in shared-components

* Use shared ReadMarkerView in MessagePanel

* Rename ReadMarkerView to ReadMarker

* Fix Prettier

* Update snapshots screenshots

* Use plain props for ReadMarker

* Fix Prettier

* Move ReadMarker into room timeline

* Replace ReadMarker nested ternary

* Update snapshot
2026-04-14 11:56:52 +00:00
Andy Balaam 9a8ffbe0bd playwright-common utilities for handling toasts (#33119)
* playwright-common utilities for handling toasts

* Set element-web-playwright-common version to 3.1.0

* Add comments to explain the linear hierarchy of fixtures
2026-04-14 11:49:27 +00:00
renovate[bot] 733c685d5e Update actions/upload-pages-artifact action to v5 (#33140)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-14 10:52:30 +00:00
renovate[bot] abefefc981 Update zizmorcore/zizmor-action action to v0.5.3 (#33139)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-14 10:50:38 +00:00
renovate[bot] 91e9a0058c Update typescript (#33133)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-14 10:29:34 +00:00
renovate[bot] e2197307b4 Update dependency @casualbot/jest-sonar-reporter to v2.5.1 (#33122)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-14 10:14:48 +00:00
renovate[bot] c982a4c89b Update testcontainers to v11.14.0 (#33126)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-14 09:58:40 +00:00
Zack 1670015ef7 Fix missing Storybook autodocs descriptions for shared components (#33135) 2026-04-14 09:53:29 +00:00
renovate[bot] 5d2c0de9e2 Update actions/upload-artifact digest to 043fb46 (#33130)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-14 09:14:29 +00:00
renovate[bot] 65c744f16c Update actions/github-script action to v9 (#33127)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-14 09:10:26 +00:00
Zack a7cd6eac31 Shared Components Restructure, Cherry Picked | Restructure Room-List Tree (#32915)
* refactor(shared-components): restructure room-list tree

* refactor(web): rename room-list parent viewmodel

* test(shared-components): add room-list visual baselines

* fix(room-list): address review feedback

* Fix Prettier

* Move AvatarWithDetails from avatar folder to core

* Update stories title to reflect correct path

* Fix AvatarWithDetails barrel export path

* Remove stale DateSeparatorView barrel export

* Move AvatarWithDetails visual baseline

* Shorten shared-components visual snapshot paths

* Revert "Shorten shared-components visual snapshot paths"

This reverts commit 91880ff5fb10408aa0091175b53ce3c86c6975a9.

* Move room list notification decoration files up a level
2026-04-14 08:51:36 +00:00
renovate[bot] d46cfe154b Update actions/cache digest to 27d5ce7 (#33129)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-14 08:35:52 +00:00
renovate[bot] 8c5ccfe0e1 Update aws-actions/configure-aws-credentials digest to ec61189 (#33131)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-14 08:32:53 +00:00
renovate[bot] 936c75ff1c Update testcontainers docker digests (#33132)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-14 08:32:39 +00:00
Michael Telatynski 2204493094 Merge pull request #33112 from element-hq/t3chguy/monorepo-module-api
Absorb element-modules/packages/element-web-module-api into monorepo
2026-04-14 07:05:26 +00:00
Florian Duros 23b11aaf86 Update compound web and compound design tokens (#33120)
* chore: update compound web and compound design tokens

* test: update SC snapshots

* test: update EW snapshots

* test: update EW screenshots
2026-04-13 15:40:24 +00:00
Michael Telatynski dc42c2518e Pin matrix-seshat version to 4.0.1 (#33121)
As 4.1.0 seems broken https://github.com/matrix-org/matrix-js-sdk/actions/runs/24346991243/job/71091033109
2026-04-13 15:39:40 +00:00
Zack 9e47271afe Fix CSS module name collisions in shared-components Vitest (#33116) 2026-04-13 13:34:23 +00:00
Andy Balaam 273a891b7b Update Exclude Insecure Devices date to October 2026 (#33117) 2026-04-13 13:03:53 +00:00
Richard van der Hoff eef8cad229 Update to compound-web 9.0.1 (#33095)
* Update to compound-web 9.0.1

There are a couple of breaking changes in v9, leading to the changes in
`BugReportDialog` and `EncryptionCard`.

Most of these updates, however, are snapshot updates, due to changes in the CSS
class names in compound web (which happens due to updates in the CSS content in
those classes; `postcss-modules` generates class names based on the hash of the
CSS).

* update playwright screenshots
2026-04-13 10:16:34 +00:00
Michael Telatynski 7010f2091c Absorb element-modules/packages/element-web-module-api into monorepo 2026-04-13 11:10:11 +01:00
Will Hunt 17efc81f0b remove disabled on retry room status bar (#33113) 2026-04-13 09:51:55 +00:00
Michael Telatynski ad2e6d37bc mv element-web-module-api module-api 2026-04-13 09:18:23 +01:00
rbondesson e30adf4eb3 Fix date separator trigger ref forwarding for jump-to-date menu (#33102)
* Fix date separator trigger ref forwarding for jump-to-date menu

* Normal forwarded ref is sufficient for the menu-button setup in Compound

* Better comment
2026-04-10 18:28:39 +00:00
Michael Telatynski a210d3c29e Merge pull request #33088 from element-hq/t3chguy/monorepo-playwright-common
Absorb remainder of playwright-common from element-modules
2026-04-10 17:38:27 +00:00
Michael Telatynski 1096ca2066 Iterate 2026-04-10 17:39:46 +01:00
Richard van der Hoff 4186b8e8e8 Convert TextualBody-test to out-of-line snapshots (#33104)
Sonar complains about duplication in the inline snapshots
2026-04-10 15:52:59 +00:00
Jefta 7b9e586c3a Hide spoilers from desktop notifications (#31699)
* Hide spoilers from desktop notifications

* Replace unicode blocks with spoiler tag

* Run prettier

* Add comments
2026-04-10 15:45:25 +00:00
Michael Telatynski ec924deaa0 Merge branch 'develop' of ssh://github.com/element-hq/element-web into t3chguy/monorepo-playwright-common
# Conflicts:
#	pnpm-lock.yaml
2026-04-10 16:41:45 +01:00
Michael Telatynski b97a0be0fd Generalise npm publishing workflow to work for more than just shared-components (#33086)
* Generalise npm publishing workflow to work for more than just shared-components

* Update doc
2026-04-10 14:37:45 +00:00
Richard van der Hoff a132b9167d Fix playwright-server docker image not exiting (#33099)
* Fix playwright-server docker image not exiting

... by wrapping with tini

* Remove redundant `npm exec`

* Update packages/playwright-common/Dockerfile

* missing comma
2026-04-10 12:31:03 +00:00
Richard van der Hoff b860a3864d Improve output of playwright-screenshots script (#33098)
* Improve output of playwright-screenshots script

* Address review feedback
2026-04-10 11:50:12 +00:00
Richard van der Hoff 4c4bfcde7e Inline inviteMultipleToRoom (#33027)
This two-line method serves mostly to obfuscate, imho. Let's get rid of it.
2026-04-09 22:11:12 +00:00
Richard van der Hoff ca6943cb43 Fix 'test' lines in codeowners (#33083)
* Fix 'test' lines in codeowners

Some of the unit tests are meant to be owned by the crypto team, but the paths
were wrong, so this didn't work.

This seems to have been broken since b084ff2313,
which moved all the tests around.

* another fix
2026-04-09 21:41:03 +00:00
Andy Balaam 70f26f9142 Separate cases in DeviceListener (#32973)
* Separate cases in DeviceListener

According to the comment in `else` there were two ways to end up there. Split
these into separate cases and provide a different log message in each case.
If we somehow get there another way, throw an error.

* Replace a throw with an error log
2026-04-09 15:25:42 +00:00
Florian Duros 3fd5718fcd Add tags support to SC I18nApi (#32984)
* chore: update ew module to 1.13.0

* feat: implement tag support in I18nApi#translate

* fix: correct return type for translate

* test: translate World! in i18nApi test

* fix: again return type

* chore: update pnpm lock
2026-04-09 15:01:20 +00:00
Michael Telatynski 917237fc3c Pass args thru nx 2026-04-09 15:50:51 +01:00
Michael Telatynski b6b0b0009c Fix some flaky playwright tests (#33085)
* Tweak flaky test reporter to identify setup failures

* Fix some flaky playwright tests

* Iterate
2026-04-09 14:34:48 +00:00
Michael Telatynski 561dbd32be Iterate 2026-04-09 15:31:34 +01:00
Michael Telatynski 540e620f40 Adjust consumers of playwright-common 2026-04-09 15:22:56 +01:00
Michael Telatynski 03e12cbd22 Absorb element-modules/packages/element-web-playwright-common into monorepo 2026-04-09 15:17:15 +01:00
Michael Telatynski 5e80431399 Shorten path for playwright-commmon 2026-04-09 14:35:32 +01:00
Florian Duros a5e09ebb53 feat: expand sections when filter is toggled (#33077) 2026-04-09 13:14:41 +00:00
Michael Telatynski 60a7a22c7b Consolidate element-modules playwright run into the main html report (#33082) 2026-04-09 13:13:35 +00:00
Michael Telatynski 04dff2d2b6 Update doc 2026-04-09 14:12:28 +01:00
Michael Telatynski 16f17d9127 Generalise npm publishing workflow to work for more than just shared-components 2026-04-09 14:07:24 +01:00
Michael Telatynski f5ec194937 Tweaks to CI (#33014)
* Tweak github actions to make Sonar & zizmor happier

* Apply filters on some pnpm install calls

* Remove stale setup-python step

* Add missing needs in complete job

* Remove repository_dispatch for everything bar develop CD

js-sdk now runs the tests downstream so this was unnecessary

* Fix prepare desktop for tests in merge queue

* Iterate

* Iterate

* Iterate

* Discard changes to .github/workflows/build_desktop_linux.yaml

* Discard changes to .github/workflows/build_desktop_macos.yaml
2026-04-09 12:34:52 +00:00
Will Hunt b4d0c21abf Update URL Preview settings (#32992)
* Remove ability for url previews to be set per-room

* Add ability to enable E2EE URL Previews globally

* Remove old migration

* Cleanup

* Remove room account handler

* update snap

* screenshot updated

* Add a test
2026-04-09 12:32:50 +00:00
Robin 253dcb44dd Show a 'grab' cursor on picture-in-picture view (#33079)
* Remove unused 'draggable' prop from PictureInPictureDragger

* Show a 'grab' cursor on picture-in-picture view

To give it a proper affordance for dragging.
2026-04-09 12:25:14 +00:00
Zack 70e40009a3 Fix issues with /me emote two liner (#33081)
* Fix issues with me emote liner

* Fix Prettier
2026-04-09 12:13:02 +00:00
Zack 1721b69017 Move TextualBody to shared components (#32868)
* Init, refactoring and movement of TextualBody to shared components, adding stories, test and view

* migrate TextualBody to shared view + app viewmodel

* Update snapshots + prettier fix

* Fix Prettier

* added new tests to make coverage happy

* add comment to attachbodyRef function

* Fix: Remove event onkeydown and remove hardcoded mx css

* Update enums to const enums

* added comment on css to explain 9px

* Update comment

* Correcting comment, pushed too fast..

* Update Css To Fix (edited)

* Update snapshot to reflect css changes

* Fix emote into one liner

* Update snapshot
2026-04-09 11:36:24 +00:00
Valere Fedronic 6486a6b5ff Add user friendly capability text for msc4039.download_file (#32983)
* Add user friendly capability test for `msc4039.download_file`

* review: remove un-needed experimental copy
2026-04-09 11:08:08 +00:00
Joao Pedro Antunes Borie 5ba09a5f90 Fix #32727: Ensure VoiceRecording uses the selected microphone (#32887)
Voice messages were being recorded using the system default microphone
instead of the device selected in Element settings.

This was fixed by ensuring the preferred deviceId is correctly passed
to the MediaStream constraints in VoiceRecording.ts.

Added unit tests in VoiceRecording-test.ts to verify that the
application correctly requests the user-selected device.

Co-authored-by: Will Hunt <2072976+Half-Shot@users.noreply.github.com>
2026-04-09 11:07:32 +00:00
Michael Telatynski 52061d624b Fix build_desktop_test for downstream runs 2026-04-09 11:35:09 +01:00
Michael Telatynski f4bd466b02 Fix build_desktop_test for downstream runs 2026-04-09 11:08:43 +01:00
Michael Telatynski d5602ebea8 Fix build_desktop_test for downstream runs 2026-04-09 10:50:30 +01:00
Michael Telatynski ec8b7bf109 Merge pull request #212 from element-hq/t3chguy/wat/382 2026-04-09 08:56:05 +01:00
Michael Telatynski 134ffe3de2 Merge pull request #212 from element-hq/t3chguy/wat/382 2026-04-09 08:56:05 +01:00
Michael Telatynski 7261b3eef1 Fix build-and-test workflow for downstream runs (#33035)
e.g. from matrix-js-sdk
2026-04-09 07:49:38 +00:00
renovate[bot] bbe4280c2c Update testcontainers docker digests (#33075)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-08 14:39:14 +00:00
Florian Duros 121c2d18e9 Room list: fix expanded/collapse state of sections (#33074)
* fix: section being empty in flat list mode

When switching space (or removing a section later), if the Chat section
is collpased and the room list is in flat list mode in the other space,
the room list is empty.

The fix forces the section to be in expanded state if in flat list mode

* fix: store section expanded state by space
2026-04-08 13:44:52 +00:00
Michael Telatynski ce498ef983 Tweak playwright caching (#33065)
* Install chromium-headless-shell instead of full Chromium

* Install chromium-headless-shell instead of full Chromium

* Standardise playwright caching

* Consolidate into a composite action

* Iterate

* Remove spurious step
2026-04-08 13:01:50 +00:00
Marley Alford 725b191ace fix: Left hand sidebar text selectable (#33029)
* fix: Add `user-select none` styles to header and room list filters

* chore: remove extra prefixed user-select variants

---------

Co-authored-by: Marley Alford <marleycalford@gmail.com>
2026-04-08 12:01:33 +00:00
Michael Telatynski ee404f098b Merge pull request #248 from element-hq/t3chguy/missing-return 2026-04-08 12:56:47 +01:00
renovate[bot] b1745318fb Update dependency path-to-regexp@0.1.12 to v1 [SECURITY] (#33070)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-08 10:43:57 +00:00
Michael Telatynski 8cae8df17f Actually skip stale screenshot reporter on errors 2026-04-08 11:43:50 +01:00
dependabot[bot] 4cc51a6756 Bump lodash from 4.17.23 to 4.18.1 (#33071)
* Bump lodash from 4.17.23 to 4.18.1

Bumps [lodash](https://github.com/lodash/lodash) from 4.17.23 to 4.18.1.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.23...4.18.1)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.18.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* -es

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-08 10:10:03 +00:00
Zack d197fb4e30 Refactor and Move TileErrorBoundary to Shared Components (#32793)
* creation of stories and view in shared-components

* migrate EventTile error fallback to shared TileErrorView MVVM

* Fix lint errors and unused import

* Update tests because of the refactoring

* Update snapshots + stories

* removal of mxEvent since it never changes in timeline

* Update packages/shared-components/src/message-body/TileErrorView/TileErrorView.stories.tsx

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>

* Update apps/web/src/viewmodels/message-body/TileErrorViewModel.ts

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>

* Update apps/web/src/viewmodels/message-body/TileErrorViewModel.ts

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>

* docs: add TileErrorView tsdoc

* docs: add TileErrorViewModel tsdoc

* docs: add view source label tsdoc

* refactor: move tile error layout into vm

* docs: add TileErrorView story view docs

* docs: move tile error story list wrapper

* refactor: remove unused tile error event setter

* Update packages/shared-components/src/message-body/TileErrorView/TileErrorView.stories.tsx

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>

* docs: add tsdoc for event tile error fallback props

* refactor: rely on snapshot merge no-op checks

* remove unessecery if statment

* test: restore EventTile mocks in afterEach

* test(shared-components): move TileErrorView baselines

---------

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>
2026-04-08 09:05:31 +00:00
renovate[bot] 6e9fc9b8fa Update npm non-major dependencies (#33001)
* Update npm non-major dependencies

* Update snapshot

* Patch plist for compatibility with updated @xmldom/xmldom

* Lockfile

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-08 07:40:43 +00:00
ElementRobot 4beaa52b28 [create-pull-request] automated change (#33068)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2026-04-08 07:09:57 +00:00
renovate[bot] 3abf74ef44 Migrate Renovate config (#33067)
* Migrate config .github/renovate.json

* Update renovate.json

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-08 07:05:54 +00:00
RiotRobot e0cddf8e4a Merge branch 'master' into develop 2026-04-08 07:52:55 +00:00
Michael Telatynski 08dbd78a7c Group docker digests renovate tasks (#33058)
* Group docker digests renovate tasks

* Change group name for testcontainers docker digests
2026-04-07 21:48:57 +00:00
Michael Telatynski dc06d36b9f Fix docs:build workflow run on a tag (#33064)
where js-sdk workflows are not available
2026-04-07 21:48:52 +00:00
Michael Telatynski 950b4cc23a Update develop CD check-regexp to exclude Netlify (#33059) 2026-04-07 21:48:48 +00:00
renovate[bot] 1dcc19b4b6 Update playwright (#33060)
* Update playwright

* Update snapshots

* Update types

* Update snapshot

* Update playwright-common

* Remove stale screenshots

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-07 16:16:57 +00:00
R Midhun Suresh edea3fffdf Collapsible Left Panel - Ensure that panels have non-fractional widths (#33052)
* Expand panel to full width

* Write tests

* Resize to nearest whole number if necessary

* Update screenshots

* Early return when resizing to whole width

* Update screenshot
2026-04-07 15:44:51 +00:00
Michael Telatynski 6c1dc7051f Accessibility improvements in settings (#32968)
* Add more playwright axe tests to settings dialogs

* Fix axe issue heading-order

* Fix heading order

* Iterate

* Update snapshots

* Iterate

* Update snapshots

* Iterate

* Update screenshot

* Iterate

* Iterate

* Update snapshot
2026-04-07 15:17:59 +00:00
Michael Telatynski 7fd837e723 Bump element-desktop version with element-web during release (#33062) 2026-04-07 15:11:33 +00:00
Michael Telatynski e74e146b4c Add workaround for cla-assistant being flaky wedging merge queue (#33033) 2026-04-07 16:59:50 +00:00
Michael Telatynski 1107ddf695 Bump version to 2.4.0 in playwright-common 2026-04-07 15:39:22 +01:00
Michael Telatynski 63dbc2a60b Merge pull request #200 from element-hq/t3chguy-patch-1 2026-04-07 15:38:42 +01:00
RiotRobot 592d7ca6b6 Reset matrix-js-sdk back to develop branch 2026-04-07 13:27:46 +00:00
RiotRobot 63aa8cad6a Merge branch 'master' into develop 2026-04-07 13:27:10 +00:00
Will Hunt 5de316b752 Move Low Bandwidth feature to devtools. (#32797)
* Move and rename low bandwidth mode.

* Still in use.

* remove string

* Add a test for low bandwidth mode

* Test requests too

* update snaps

* New year!
2026-04-07 12:16:35 +00:00
R Midhun Suresh 811670a08c Ignore specific directories (#33055)
Otherwise newly generated screenshots will be ignored.
2026-04-07 12:05:52 +00:00
R Midhun Suresh 6b00466a85 Collapsible Left Panel - Clicking on separator should expand to 100% when no width is available in settings (#33053)
* Expand panel to full width

* Write tests
2026-04-07 12:05:36 +00:00
renovate[bot] f12b23a87a Update webpack (#33011)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-07 12:03:40 +00:00
renovate[bot] 2bef316bed Update dependency caniuse-lite to v1.0.30001781 (#32996)
* Update dependency caniuse-lite to v1.0.30001781

* Update tests

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-07 10:02:33 +00:00
ElementRobot c05795c1bb Localazy Download (#33049)
* [create-pull-request] automated change

* Discard changes to apps/web/src/i18n/strings/en_EN.json

---------

Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-07 08:35:25 +00:00
renovate[bot] 2c89396a6f Update dependency vite to v8.0.5 [SECURITY] (#33054)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-07 08:00:15 +00:00
Michael Telatynski e0deef531c Merge pull request #245 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-c4bc6a0a9e 2026-04-07 08:58:48 +01:00
Will Hunt cffd8cfd70 Disallow links without protocol (e.g. starting with http(s)://) in LinkedText. (#32972)
* Disallow links without protocols in LinkedText.

* Update tests
2026-04-07 07:53:06 +00:00
Zack 11fd669c26 Move shared message body views into event-tile layout (#33015)
* Move shared message body views into event-tile layout

* Move shared message body visual baselines
2026-04-07 06:38:24 +00:00
dependabot[bot] 6d1cd514e4 build(deps-dev): bump vite in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 7.3.1 to 7.3.2
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.3.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.3.2
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 20:43:24 +00:00
Florian Duros 46bff1f9e6 Room list: add activity marker to sections (#33024)
* feat: add unread status to section view

* feat: add unread tracking in room list section

* feat: populate rooms into section header vm

* test: add units for unread in section view model

* test(e2e): add unread tests
2026-04-06 19:05:45 +00:00
renovate[bot] e53a148da2 Update vite (#33003)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-03 10:39:12 +00:00
renovate[bot] d5ec23f032 Update dependency lodash to v4.18.1 [SECURITY] (#33023)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-03 09:18:09 +00:00
ElementRobot b1ed35e9b8 [create-pull-request] automated change (#33038)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2026-04-03 06:55:51 +00:00
Richard van der Hoff 5e140768f0 InviteDialog: remove broken checks for unknown users (#33026)
* InviteDialog: remove broken checks for unknown users

Per https://github.com/element-hq/element-web/issues/33020, this doesn't
actually work, and if we were to bring it back, we'd design it differently.

* Remove now-unused `UserProfilesStore.getProfileLookupError`

This was only used in `InviteDialog.checkProfileAndStartDm`, which has now been
removed.
2026-04-02 15:31:29 +00:00
renovate[bot] d7a5659180 Update dependency domutils to v4 (#33007)
* Update dependency domutils to v4

* Tweak jest config

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-02 14:28:43 +00:00
renovate[bot] 063e0802f4 Update dependency knip to v6 (#33008)
* Update dependency knip to v6

* Make knip happy

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2026-04-02 13:38:58 +00:00
Michael Telatynski 2d3e2fcb70 Remove global h2 css rule in favour of heading styles/components (#32969)
* Remove global h2 css rule in favour of heading styles/components

* Use Compound Heading in shared-components

and forbid hX elements

* Use Compound Heading in settings

add back margin to some legacy headings

* Tweak some headings

* Update screenshots

* Update screenshots

* Update snapshots

* Tweak .gitignore

* Update snapshots

* Iterate

* Update screenshots

* Update screenshots

* Update screenshot
2026-04-02 16:13:17 +00:00
Michael Telatynski 7bbd86ca10 Only run Docker CD workflow if any images have changed (#32954) 2026-04-02 13:07:30 +00:00
renovate[bot] f18eb24144 Update Node.js to v24.14.1 (#33000)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-02 13:00:46 +00:00
ElementRobot f6461ed944 [create-pull-request] automated change (#33016)
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
2026-04-02 10:26:38 +00:00
Michael Telatynski b790019ecc Fix EventListSummary not unbinding event listeners (#33006) 2026-04-02 09:03:50 +00:00
Michael Telatynski 0a8ef85f2f Fix hak check for matrix-seshat (#33030) 2026-04-02 09:43:12 +00:00
rbondesson 4315038346 Refactor MessageActionBar using MVVM and move to shared-components (#32784)
* Refactor MessageActionBar into MVVM ActionBarView

* Adding tooltips for menu items and correct i18n strings

* Layout changes

* Renaming some properties

* Rename property

* Create a first version of the view model and refactor media visibility logic

* Refactor view to take options and rections menu as optional properties

* Cleaner interface between view and view model

* Refactor view properties and replace Menu and MenuItem

* Bugfixes and switching to ActionBarView instead of MessageActionBar in element-web

* Avoid creating view models and render toolbar until it is actually shown

* Added unit and playwright tests and documented the view

* Added view model unit tests and updated snapshots of dependant tests

* Remove unused components and unnecessary css

* Remove unused language tags

* Fix for handling join-rules correctly

* Prettier

* Add handling of stale view model in async calls

* Prettier

* Split the element-web css into two different. One for legacy components and one for the ActionBarView

* Missing variables used for linting

* Fix for showing ActionBarView when using keyboard for navigation

* Handle visibility on context menu closing

* ThreadPanel uses the ActionBarView so restore css rule

* Fix for visibility of the ActionBarView in Thread panel

* Fix for ActionBarVuew visibility when closing right-click context menu and not still hovering

* Add roving index to function as a toolbar

* Adjust the RoomView test to send hover to the EventTile instead of the message text

* Fix SonarCloud issues

* Fix for SonarCloud issue

* Merge fix

* Rename mx_LegacyActionBar to mx_ThreadActionBar

* Added documentation and simplified join rules

* Generalize the ActionBarView and move logic to view model

* Add the four new buttons to the ActionBarView

* Update view model and tests to use the updated ActionBarView

* Refactor element-web to use ActionBarView

* Clean up styling in element-web

* Clean up and updating snaps and screenshots

* Added unit-tests for better coverage

* Moving ActionBarView to the correct folder in shared components

* Update snaps in element-web

* Better documentation in stories

* Merge fixes

* Updates after review comments

* Review comment fixes

* Added documentation to view models and updated snaps

* Hide button had the wrong label

* Replace createRef with useRef
2026-04-01 12:27:03 +00:00
Zack 0391543bbc Refactor and move MVideoBody to shared components (#32849)
* init MVideoBody to shared components, including test, stories and view

* fix prettier and other warnings

* move video message body to shared view + app viewmodel

* Fix prettier warnings and masking spinner for tests

* stabilize VideoBodyView screenshots with local media asset

* Disable spinner from changing image all the time

* Added mask over video spinner to prevent issues with new generated images on playwright tests

* Update prettier fix

* Update snapshot

* Add tests to cover different states of Video

* Update code to prevent the previous component Hack fix regarding jumps on the timeline.

* Update snapshot

* Update code to improve code quality for Sonar + update snapshot

* adde documentation snippets

* refactor: move m.video rendering into body factory

* docs: add tsdoc for video body view model

* docs: add thumbnail tsdoc for video body view model

* docs: add content-url tsdoc for video body view model

* docs: add dimensions tsdoc for video body view model

* docs: add aspect-ratio tsdoc for video body view model

* docs: add tsdoc for video body view state

* refactor: replace video body view state enum

* refactor: remove duplicate video body state init

* refactor: drop unused video body view state attribute

* Fix Prettier

* Update snapshot screenshot

* test: restore video story screenshot mask

* chore: refresh PR head

* Add mask to screenshot to pass CI tests

* test: narrow video story mask hook

* Fix easy Sonar warnings in video body components

* Move shared message body views into event-tile layout

* Move shared message body visual baselines

* Revert unrelated shared message body moves
2026-04-01 09:48:22 +00:00
JephDiel 3e04b24d1e Allow Element Call to use MSC4039 (#32755)
* Allow Element Call to use MSC4039

Allow Element Call to use MSC4039 so it can
download avatars if it can't authenticate with the
server directly.

* Test Allowing Element Call to use MSC4039

---------

Co-authored-by: Valere Fedronic <bill.carson@valrsoft.com>
2026-04-01 08:14:16 +00:00
renovate[bot] e2ffaef7c3 Update sanitize (#33012)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-01 00:28:32 +00:00
renovate[bot] 93ca06d6b7 Update dependency mini-css-extract-plugin to v2.10.2 (#32997)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 22:44:27 +00:00
renovate[bot] f24003d217 Update dependency @vector-im/compound-design-tokens to v8 (#33013)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 22:08:58 +00:00
renovate[bot] 51e8573ddc Update dependency testcontainers to v11.13.0 (#33010)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 22:08:47 +00:00
renovate[bot] b79a34e9fc Update babel (#33009)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 22:08:23 +00:00
renovate[bot] e9dbddfc97 Update Node.js to 27e462f (#32994)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 22:07:46 +00:00
renovate[bot] 319044f2f9 Update nginxinc/nginx-unprivileged:alpine-slim Docker digest to b5831ee (#32993)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 22:07:05 +00:00
renovate[bot] bee4c1cdaf Update rust:bullseye Docker digest to bc19574 (#32995)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 22:07:00 +00:00
renovate[bot] 823d43bfce Update eslint-plugins (#32999)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 21:39:22 +00:00
renovate[bot] f1c0e556ab Update pnpm to v10.33.0 (#33004)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 20:54:22 +00:00
Florian Duros 0f515f581e Room list: add default sections (#32785)
* feat: add sections to RLSV3

* feat: add sections in vms

* feat: add room list section labs flag

* fix: wrong margin for room list item when in sections

* feat: hide favourites and low priority filters

* fix: crash when changing filter

* feat: support sticky room in sections

* test: update SC snapshot

* test: update SC screenshot

* test: update RLS tests

* test: add tests to RoomListSectionHeaderViewModel

* test: fix existing test in RoomListViewModel

* test: add sections tests for RoomListViewModel

* test: add e2e tests for sections

* fix: incorrect selected room when expanding/collasping a section

* fix: typo in `roomSkipList`

* feat: use one skip list with all filters instead of one list by tag

* chore: put back comment about `roomIndexInSection`

* chore: add missing `readonly`

* chore: add doc about possible undefined value for room item vm
2026-03-31 18:43:32 +00:00
renovate[bot] 1974b50213 Update typescript (#33002)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 15:22:30 +00:00
renovate[bot] 1e3dc4f9b9 Update storybook (#33005)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 15:10:24 +00:00
renovate[bot] 5b44a1cd16 Update electron (#32998)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 15:03:50 +00:00
Michael Telatynski 60c65e5649 Fix reusable build-and-test workflow 2026-03-31 15:52:11 +01:00
renovate[bot] 86d9e32d53 Update Node.js to 0174333 (#235)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-31 14:27:28 +00:00
Michael Telatynski 2b3720b4a2 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
2026-03-31 12:52:50 +00:00
Michael Telatynski 27f6129dab Merge branch 'main' of github.com:/element-hq/element-web-modules into t3chguy/wat/382
# Conflicts:
#	modules/restricted-guests/element-web/e2e/snapshots/restricted-guests.spec.ts/preview-bar-linux.png
2026-03-31 09:26:21 +01:00
Michael Telatynski 2b3425f0e8 Merge branch 'main' of github.com:/element-hq/element-web-modules into t3chguy/wat/382
# Conflicts:
#	modules/restricted-guests/element-web/e2e/snapshots/restricted-guests.spec.ts/preview-bar-linux.png
2026-03-31 09:26:21 +01:00
R Midhun Suresh a6f0d25525 Merge pull request #230 from element-hq/midhun/bump/playwright-common-2.3.0
Bump `@element-hq/element-web-playwright-common` package version
2026-03-30 20:06:54 +05:30
R Midhun Suresh 72de8745e9 Bump package version 2026-03-30 19:56:58 +05:30
Florian Duros 00a2e704ec chore: bump ew module api to 1.13.0 2026-03-30 16:25:59 +02:00
R Midhun Suresh 0079270fa5 Lock width when running most playwright tests 2026-03-30 18:16:44 +05:30
Florian Duros 4e72eb6dcc Merge pull request #227 from element-hq/florianduros/i18n-tags 2026-03-30 14:39:51 +02:00
Florian Duros 91d153aca3 doc: add for sub in SubstitutionValue 2026-03-27 09:29:13 +01:00
Florian Duros 520dfffc95 feat: add tags support to i18n api 2026-03-26 12:17:59 +01:00
Michael Telatynski f3aef2f1cc Merge branch 'main' of github.com:/element-hq/element-web-modules into t3chguy/wat/382
# Conflicts:
#	modules/restricted-guests/element-web/e2e/snapshots/restricted-guests.spec.ts/login-legacy-linux.png
#	modules/restricted-guests/element-web/e2e/snapshots/restricted-guests.spec.ts/login-mas-linux.png
#	playwright.config.ts
2026-03-20 16:41:53 +00:00
Michael Telatynski d42c816558 Merge branch 'main' of github.com:/element-hq/element-web-modules into t3chguy/wat/382
# Conflicts:
#	modules/restricted-guests/element-web/e2e/snapshots/restricted-guests.spec.ts/login-legacy-linux.png
#	modules/restricted-guests/element-web/e2e/snapshots/restricted-guests.spec.ts/login-mas-linux.png
#	playwright.config.ts
2026-03-20 16:41:53 +00:00
David Baker a2ca504fd6 Bump module API to 1.12.0 2026-03-13 12:52:08 +00:00
David Baker 7fc83fa30e Merge pull request #222 from element-hq/dbkr/vitest_default_output
Add default output for vitest & playwright tests
2026-03-12 16:57:53 +00:00
David Baker 196c8a082a Add default output for vitest
Otherwise it's just mysteriously silent.
2026-03-11 14:42:06 +00:00
David Baker 82398f7d50 Merge pull request #219 from element-hq/dbkr/widget-toggles-api
Add module APIs to enable widget toggle buttons
2026-03-09 18:25:36 +00:00
David Baker 90ab1534c9 change back to unix line endings 2026-03-09 18:19:05 +00:00
David Baker 3a21741737 Merge remote-tracking branch 'origin/main' into dbkr/widget-toggles-api 2026-03-09 15:58:35 +00:00
David Baker 4591a72d3a Change to add callback 2026-03-09 15:51:42 +00:00
David Baker a96327b691 Make matrix-widget-api a devDependency
as it's only for the type
2026-03-09 15:48:14 +00:00
Michael Telatynski 28e5008abf Merge pull request #221 from element-hq/t3chguy-patch-2 2026-03-09 10:14:16 +00:00
Michael Telatynski e322627d3e Bump Module API to 1.11.0 2026-03-06 16:16:52 +00:00
Michael Telatynski 9ad27f61f2 Merge pull request #210 from element-hq/t3chguy/wat/382.1 2026-03-06 16:04:39 +00:00
Michael Telatynski 267b63a10e Merge branches 't3chguy/wat/382.1' and 'main' of github.com:/element-hq/element-web-modules into t3chguy/wat/382.1
# Conflicts:
#	packages/element-web-module-api/element-web-module-api.api.md
2026-03-06 15:55:24 +00:00
David Baker bf69ddf2b4 Add module APIs to enable widget toggle buttons 2026-03-06 10:58:00 +00:00
Michael Telatynski 225fe7c406 Tidy up 2026-03-04 10:32:58 +00:00
Michael Telatynski 6d71191af9 Fix axe imports 2026-03-03 18:27:32 +00:00
Michael Telatynski fd4bb50a14 Tests galore 2026-03-03 18:25:22 +00:00
Michael Telatynski 4af0608995 Merge branch 't3chguy/wat/382.2' of github.com:/element-hq/element-web-modules into t3chguy/wat/382
# Conflicts:
#	packages/element-web-module-api/element-web-module-api.api.md
2026-03-02 21:43:48 +00:00
Michael Telatynski ccf3fcf4af Add API to replace Login component renderer 2026-03-02 16:54:23 +00:00
Michael Telatynski 1a9ce45038 Adopt shouldShowComponent customisations from legacy Module API 2026-03-02 16:25:50 +00:00
renovate[bot] 7206db8243 Update Node.js to 7fddd9d 2026-03-01 16:05:08 +00:00
Michael Telatynski d11c2e880b Merge pull request #205 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-b2936519f3 2026-02-28 21:23:58 +00:00
dependabot[bot] 2b688528e3 build(deps): bump rollup in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [rollup](https://github.com/rollup/rollup).


Updates `rollup` from 4.52.0 to 4.59.0
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.52.0...v4.59.0)

---
updated-dependencies:
- dependency-name: rollup
  dependency-version: 4.59.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-28 16:42:02 +00:00
David Langley c9d7142267 Merge pull request #204 from element-hq/langleyd/module-api-release-1.10.0
Release element-web-module-api 1.10.0
2026-02-25 15:19:19 +00:00
David Langley 3ac2b36657 bump to 1.10.0 2026-02-25 13:08:11 +00:00
David Langley 226824890a Merge pull request #198 from element-hq/langleyd/widget-lifecycle-module-api
Widget lifecycle module api
2026-02-25 12:58:43 +00:00
David Langley 83d752cfd7 Add MaybePromise 2026-02-25 09:33:48 +00:00
Michael Telatynski 73e2770246 Merge pull request #203 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-57e1ad1f90 2026-02-23 09:05:27 +00:00
dependabot[bot] a0d4df56c0 build(deps): bump bn.js in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [bn.js](https://github.com/indutny/bn.js).


Updates `bn.js` from 4.12.1 to 4.12.3
- [Release notes](https://github.com/indutny/bn.js/releases)
- [Changelog](https://github.com/indutny/bn.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/indutny/bn.js/commits/v4.12.3)

---
updated-dependencies:
- dependency-name: bn.js
  dependency-version: 4.12.3
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-22 14:06:56 +00:00
Michael Telatynski cd061ee9f5 Merge pull request #202 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-f1bf2b0a19 2026-02-22 14:05:47 +00:00
dependabot[bot] e30d825503 build(deps): bump ajv in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [ajv](https://github.com/ajv-validator/ajv).


Updates `ajv` from 6.12.6 to 6.14.0
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](https://github.com/ajv-validator/ajv/compare/v6.12.6...v6.14.0)

---
updated-dependencies:
- dependency-name: ajv
  dependency-version: 6.14.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-21 17:45:03 +00:00
Michael Telatynski e98b9978d7 Merge pull request #201 from element-hq/t3chguy-patch-2
Specify ThisType on i18nApi
2026-02-20 12:48:01 +00:00
Michael Telatynski 5a3559a9bb Bump version from 1.9.0 to 1.9.1 2026-02-20 12:43:06 +00:00
Michael Telatynski 30c27af170 Update API report for @element-hq/element-web-module-api 2026-02-20 09:33:28 +00:00
Michael Telatynski d51eb5dfd3 Specify ThisType on i18nApi 2026-02-20 09:32:58 +00:00
Michael Telatynski a9e76dbb8a Update stale screenshots playwright reporter
At some point it seems that playwright changed how reporters are passed flakes.

https://github.com/microsoft/playwright/pull/39145 needs to land to fully fix the reporter though
2026-02-19 16:04:42 +00:00
David Langley 4614d2f395 Remove WidgetKind and fix header 2026-02-18 18:43:26 +00:00
David Langley a5ec21bd06 Update element-web-module-api.api.md 2026-02-18 13:18:03 +00:00
David Langley 5bb1d3d461 Add widget permissions module api 2026-02-18 13:17:53 +00:00
Michael Telatynski 30cbbd48b3 Merge pull request #197 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-14dc0ebc5a
build(deps): bump qs from 6.14.1 to 6.14.2 in the npm_and_yarn group across 1 directory
2026-02-16 08:45:58 +00:00
dependabot[bot] dd71370223 build(deps): bump qs in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [qs](https://github.com/ljharb/qs).


Updates `qs` from 6.14.1 to 6.14.2
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.14.1...v6.14.2)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.14.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-14 12:59:13 +00:00
Michael Telatynski e16626519f Merge pull request #195 from element-hq/t3chguy/no-link-modules 2026-02-12 15:14:07 +00:00
Michael Telatynski a604153ece Bump playwright-common version 2026-02-12 14:55:30 +00:00
Michael Telatynski 2c73e09907 Expose PLAYWRIGHT_COMMON_DOCKER envvar in playwright screenshots docker image 2026-02-12 14:55:12 +00:00
Michael Telatynski f243b3dd54 Enable corepack in playwright screenshots docker image 2026-02-12 14:54:59 +00:00
Michael Telatynski 82f185700e Add --no-link-modules to playwright-screenshots.sh script 2026-02-12 14:54:33 +00:00
Michael Telatynski aadeb01f97 Merge pull request #193 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-66fcce4dc2 2026-02-10 10:38:54 +00:00
dependabot[bot] 9c1f3ba928 build(deps): bump axios in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [axios](https://github.com/axios/axios).


Updates `axios` from 1.13.2 to 1.13.5
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.13.2...v1.13.5)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.13.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-10 10:32:16 +00:00
Michael Telatynski 31d5d60b4c Bump playwright-common version to 2.2.6 2026-02-10 10:31:06 +00:00
Michael Telatynski 8169d1c21b Merge pull request #192 from element-hq/t3chguy/pnpm
Add support for pnpm in playwright-common screenshot script
2026-02-09 15:05:51 +00:00
Michael Telatynski 5f7b56a89f Add support for pnpm in playwright-common screenshot script 2026-02-09 09:34:54 +00:00
Richard van der Hoff cb27334d3d Fix entrypoint for element-web-playwright-common docker image (#190) 2026-02-02 22:18:35 +00:00
Richard van der Hoff ccadd73953 playwright-screenshots: fix incompatibility with podman (#189)
Podman doesn't recognise the `volume-nocopy` option on mounts. It doesn't seem
to be necessary so let's omit it.
2026-02-02 11:27:00 +00:00
Michael Telatynski c96f5adcef Merge pull request #187 from element-hq/t3chguy/fix-playwright-docker 2026-01-28 15:34:22 +00:00
Michael Telatynski c3966aea82 Fix playwright-screenshots utility for native dependencies
Without this, a developer would need to both specify --with-node-modules && --entrypoint and provide a custom entrypoint to do the `yarn install`.
2026-01-23 17:15:49 +00:00
Michael Telatynski fba0da2eaa Bump playwright-common version to 2.2.5 2026-01-23 16:57:21 +00:00
Michael Telatynski 582537a879 Merge pull request #185 from element-hq/t3chguy-patch-1 2026-01-23 16:56:29 +00:00
Michael Telatynski 33fbb47d93 Fix Playwright version checking
Updated method to fetch Playwright version using yarn list.

`yarn info` was just querying what the latest available package is
2026-01-23 16:39:23 +00:00
Michael Telatynski 7698c72bbf Merge pull request #183 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-ab4d8f00f8 2026-01-22 09:11:50 +00:00
dependabot[bot] 9233c0c0db build(deps): bump lodash-es in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [lodash-es](https://github.com/lodash/lodash).


Updates `lodash-es` from 4.17.22 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/commits/4.17.23)

---
updated-dependencies:
- dependency-name: lodash-es
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-22 02:02:39 +00:00
Michael Telatynski edfc66fa81 Bump version from 2.2.3 to 2.2.4 2026-01-16 15:35:24 +00:00
Robin 1bd24aeb27 Merge pull request #181 from element-hq/robin/axe-no-container
Avoid starting a homeserver when using just the axe fixture
2026-01-16 12:10:51 +01:00
Robin 48e262d8f1 Avoid starting a homeserver when using just the axe fixture
Since 4c928d2854 importing the axe fixture would cause your test to pull in the entire world of Synapse and Postgres services. For Compound Web tests, we want to be able to use axe in isolation without all the extra fixtures. Inverting the fixture hierarchy ought to do the trick.
2026-01-16 12:05:41 +01:00
Michael Telatynski 0561301d98 Bump version to 2.2.3 in package.json 2026-01-07 14:02:43 +00:00
Will Hunt 1ab1b54e7c Merge pull request #174 from element-hq/hs/fix-imports
Fix missing `.js` imports
2026-01-06 19:04:28 +00:00
Half-Shot 23565d2d36 Fix imports to import with .js 2026-01-06 17:15:04 +00:00
Half-Shot a303e13060 Change module resolution to check for correct imports. 2026-01-06 17:14:50 +00:00
Will Hunt 384ddb4eab Merge pull request #173 from element-hq/hs/bump-@element-hq/element-web-playwright-common-to-2.2.2
Bump @element-hq/element-web-playwright-common to 2.2.2
2026-01-06 16:04:26 +00:00
Half-Shot db11815589 Bump @element-hq/element-web-playwright-common to 2.2.2 2026-01-06 15:47:10 +00:00
Will Hunt a4b5142837 Merge pull request #172 from element-hq/hs/type-msc3814_enabled
Set experimental_features type to Record<string, boolean>
2026-01-06 15:42:20 +00:00
Half-Shot 184c8dc3b3 Just set as Record<string, boolean> 2026-01-06 15:32:36 +00:00
Half-Shot b048f5323c Switch to MSC3814 2026-01-06 15:27:06 +00:00
Half-Shot de205f9911 Add msc2697_enabled 2026-01-06 14:46:50 +00:00
Will Hunt 5f154c77f9 Merge pull request #171 from element-hq/packages/element-web-playwright-common/v2.2.0
Bump @element-hq/element-web-playwright-common to 2.2.1
2026-01-06 14:19:35 +00:00
Half-Shot ea6017a26c Bump @element-hq/element-web-playwright-common to 2.2.1 2026-01-06 14:14:35 +00:00
Half-Shot 1bf78ac7c4 use as 2026-01-06 14:14:21 +00:00
Half-Shot 839a757d94 Bump @element-hq/element-web-playwright-common to 2.2.0 2026-01-06 13:57:23 +00:00
Half-Shot a8523421da add docs 2026-01-06 13:42:22 +00:00
Half-Shot 894e684dab match other syntax 2026-01-06 13:33:08 +00:00
Half-Shot b12b59a932 Allow configuring MatrixRTC endpoints. 2026-01-06 13:31:30 +00:00
Michael Telatynski 174c35b874 Iterate 2025-12-11 11:26:13 +00:00
Michael Telatynski 1b28a823f3 Merge pull request #160 from element-hq/renovate/ghcr.io-element-hq-element-web-latest 2025-12-11 11:12:10 +00:00
renovate[bot] 9b570e5cea Update ghcr.io/element-hq/element-web:latest Docker digest to a84f294 2025-12-11 11:06:25 +00:00
Michael Telatynski fec7923af0 Update index.ts 2025-12-09 17:06:45 +00:00
renovate[bot] a7583dbdbc Update dependency glob to v13 2025-12-09 16:39:37 +00:00
Michael Telatynski 02e36fd5fb Merge pull request #151 from element-hq/renovate/node-lts-alpine 2025-12-09 16:39:16 +00:00
renovate[bot] 9ea40d14a5 Update Node.js to 682368d 2025-12-09 16:31:13 +00:00
Florian Duros ac12b9a79a Merge pull request #149 from element-hq/florianduros/ew-api/release-1.9.0 2025-12-05 10:40:42 +01:00
Florian Duros 7b4894d444 build(ew-api): update to 1.9.0 2025-12-05 09:45:48 +01:00
Florian Duros 40f7bf2b81 Merge pull request #144 from element-hq/florianduros/ew-api/read-receipt
EW api: add option to enable read receipt and marker to be cleared on user activity
2025-12-04 19:54:52 +01:00
Florian Duros 0126cded9e doc: update api md doc 2025-12-04 18:02:29 +01:00
Florian Duros 94aba63a1d feat(ew-api): add builtins#RoomViewProps#enableReadReceiptsAndMarkersOnActivity
For the multiroom module, we display several room views at the same
time. In order to avoid all the rooms to send read receipts and markers
automatically when we are interacting with the UI, we add
`enableReadReceiptsAndMarkersOnActivity` props.

When at false, the timeline doesn't listen to user activity to send
these receipts. Only when the room is focused, marker and read receipts
are updated.
2025-12-04 18:02:28 +01:00
David Langley 84123065a7 Merge pull request #148 from element-hq/langleyd/hideWidgets
EW module APi: add hideWidgets props to RoomViewProps
2025-12-04 16:40:59 +00:00
David Langley f35357d3b3 Add api to hide widgets 2025-12-03 09:54:33 +00:00
R Midhun Suresh 2d3b554649 Increment package version 2025-12-02 14:43:48 +05:30
R Midhun Suresh 44d8f89754 Merge pull request #146 from element-hq/midhun/multiroom/render-notification-decoration
Add API to render notification decoration from EW
2025-12-02 14:40:46 +05:30
R Midhun Suresh 64a63bdbb0 Update docs 2025-12-02 13:59:21 +05:30
R Midhun Suresh 8f40ea5c0a Add API to render notification decoration 2025-12-02 13:56:53 +05:30
David Baker 3d0ad97667 module API 1.7.0 2025-12-01 09:22:18 +00:00
David Baker 0d69056e7b Merge pull request #137 from element-hq/dbkr/human_eyes
Add humanizeTime to the module i18n API
2025-12-01 09:08:51 +00:00
David Baker 65edff067a Better doc 2025-11-28 15:20:51 +00:00
Richard van der Hoff 0d46bc924c Fix "Error: No request context set" in credentials fixture (#145)
Make sure that we've run the `context` fixture first, so that the request API
is configured
2025-11-27 19:40:29 +00:00
Richard van der Hoff 4c928d2854 Avoid mergeTests in test fixture declarations (#138)
Normally, one can find the documentation on a playwright test fixture by
finding its declaration (i.e., you can ctrl-click on the fixture name and find
its documentaion).

However, `mergeTests` re-declares the type, making it much harder to find the
documentation on a given fixture.

It's easy enough to avoid `mergeTests`: we just structure our `test.extend`
calls as a strict hieirarchy.
2025-11-27 17:13:22 +00:00
R Midhun Suresh 1b11b3d1c0 Merge pull request #143 from element-hq/midhun/playwright/bump-2.1.0
Bump `element-web-playwright-common` version to 2.1.0
2025-11-27 17:26:09 +05:30
R Midhun Suresh 3b31bbf4a9 Bump version to 2.1.0 2025-11-27 17:16:56 +05:30
R Midhun Suresh 0f3938bb54 Merge pull request #142 from element-hq/midhun/playwright/fix-script
Fix `playwright-screenshots.sh` not working when run with yarn berry
2025-11-27 13:39:50 +05:30
R Midhun Suresh 76b07d736c Make script compatible with yarn berry 2025-11-27 13:23:16 +05:30
David Baker 56662c53e9 Add humanizeTime to the module i18n API
So modules can access it simply with the right context etc
2025-11-26 16:47:58 +00:00
Florian Duros 8019035578 Merge pull request #136 from element-hq/florianduros/release-ew-1.6.0
EW module: bump to v1.6.0
2025-11-21 18:28:55 +01:00
Florian Duros ef180bf89d chore(EW module): bump to v1.6.0 2025-11-21 16:30:14 +01:00
Florian Duros c570936d33 Merge pull request #135 from element-hq/florianduros/rooms-hide-pinned-message-banner 2025-11-21 15:38:33 +01:00
Florian Duros 7518d1c068 Add ExtraApi#getVisibleRoomBySpaceKey (#134) 2025-11-21 15:31:17 +01:00
renovate[bot] 99ee1f95ad Pin dependencies (#63)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-19 20:09:05 +01:00
Michael Telatynski 9b0af6c3ab Merge pull request #132 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-d580270e1d 2025-11-18 09:38:38 +00:00
dependabot[bot] 0788c3a207 Bump glob in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [glob](https://github.com/isaacs/node-glob).


Updates `glob` from 11.0.1 to 11.1.0
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v11.0.1...v11.1.0)

---
updated-dependencies:
- dependency-name: glob
  dependency-version: 11.1.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-18 07:36:22 +00:00
Florian Duros 17066c03fd chore: update element-web-module-api.api.md 2025-11-17 15:57:28 +01:00
Florian Duros a66fd6e976 feat: add option to add the right panel of a room view 2025-11-17 15:13:40 +01:00
Michael Telatynski 44c3d767ce Merge pull request #126 from element-hq/renovate/major-eslint-plugins 2025-11-12 12:24:19 +00:00
Michael Telatynski c2f4535153 Delint 2025-11-12 12:16:31 +00:00
Michael Telatynski 6a4c529083 Delint 2025-11-12 12:16:31 +00:00
Michael Telatynski 2612dcd8e0 Merge branch 'main' into renovate/vitest-sonar-reporter-3.x 2025-11-12 12:01:06 +00:00
renovate[bot] e197f0ec4b Update vitest monorepo to v4 (#128)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-12 12:00:07 +00:00
renovate[bot] 4125ebea79 Update dependency vitest-sonar-reporter to v3 2025-11-12 11:46:24 +00:00
Richard van der Hoff e31efda9b4 Apply suggestion from @richvdh 2025-11-06 11:45:58 +00:00
Richard van der Hoff 49ad9c1d9c Start Ryuk ourselves 2025-11-05 16:23:16 +00:00
Richard van der Hoff 2af8e3c21f Warn about linked node modules under podman
Thanks to a podman bug, the symlink workaround doesn't work there. Let's emit a
noisy warning.
2025-11-04 23:49:31 +00:00
Richard van der Hoff 28384f1112 playwright-screenshots: clean up output and error handling
Somebody wrote those `pushd` and `popd` lines without testing
them. Redirections bind tighter than `||` so those lines were always spamming
the console.

Using `set -e` is more reliable than always checking exit codes anyway.
2025-11-04 23:47:09 +00:00
Richard van der Hoff 6502ffcbe0 Disable ryuk reaper in the playwright container
... thus making it possible to use `testcontainers` inside unprivileged
containers.
2025-11-04 23:46:13 +00:00
Richard van der Hoff 4cfa5b3265 Use DOCKER_HOST env var to find docker socket 2025-11-04 23:04:44 +00:00
Florian Duros 9b8c26ff22 Merge pull request #106 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-fd296dbd23 2025-10-30 13:30:35 +01:00
R Midhun Suresh 815b80e8f7 Merge pull request #116 from element-hq/midhun/bump/module-api-1.5.0
Increment verison in package.json
2025-10-29 20:43:20 +05:30
R Midhun Suresh a1cd21244f Reset patch version as well 2025-10-29 20:35:53 +05:30
R Midhun Suresh 3d4b42c44b Merge pull request #115 from element-hq/midhun/bump/module-api
Increment version of module api
2025-10-29 20:29:51 +05:30
R Midhun Suresh b7385d8936 Update package.json 2025-10-29 20:21:27 +05:30
Florian Duros 07ab08a6f9 Merge pull request #114 from element-hq/florianduros/ew-api-room-view-props 2025-10-29 10:42:34 +01:00
Florian Duros afa2984645 refactor(builtins): remove roomId from RoomViewProps 2025-10-29 10:36:55 +01:00
R Midhun Suresh ef9732c68f Merge pull request #113 from element-hq/midhun/multiroom/navigation
Add `openRoom` action to Navigation
2025-10-28 21:16:39 +05:30
Florian Duros ca6443e4a2 chore: update api.md 2025-10-28 16:18:10 +01:00
Florian Duros 81212a3c16 feat(builtins): add hideHeader and hideComposer props to RoomViewProps and renderRoomView 2025-10-28 16:06:28 +01:00
R Midhun Suresh 879c5c47f6 Update doc 2025-10-28 16:36:39 +05:30
R Midhun Suresh 74acfb84aa Add openRoom to Navigation 2025-10-28 16:36:01 +05:30
dependabot[bot] 10d73fa0ea Bump vite in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 7.1.6 to 7.1.11
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.1.11/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.1.11
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-28 10:10:32 +01:00
R Midhun Suresh 4698f68d8a Merge pull request #109 from element-hq/midhun/multiroom/client-api
Allow modules to access a part of `MatrixClient` functionality
2025-10-27 18:11:17 +05:30
R Midhun Suresh 0c0fc60f1c Merge pull request #110 from element-hq/midhun/multiroom/stores-api
Allow modules to access RLS from element-web
2025-10-27 18:00:14 +05:30
R Midhun Suresh 0f6ac0a841 Merge pull request #111 from element-hq/midhun/multiroom/builtins-api
Render more components through builtins api
2025-10-27 17:59:12 +05:30
R Midhun Suresh 4381032d63 Update API doc 2025-10-24 00:30:01 +05:30
R Midhun Suresh 4ee9b05608 Return a watchable 2025-10-24 00:29:18 +05:30
R Midhun Suresh af3d476a70 Convert to property 2025-10-24 00:28:54 +05:30
R Midhun Suresh 97e1462474 Updat api doc 2025-10-24 00:08:45 +05:30
R Midhun Suresh 200d52a162 Add Stores API 2025-10-24 00:08:43 +05:30
R Midhun Suresh 6b4f33bee1 Update API doc 2025-10-23 23:45:36 +05:30
R Midhun Suresh 04379cc089 Return watchable in account data api 2025-10-23 23:41:08 +05:30
R Midhun Suresh cd9a21ac93 Add onFirstWatch and onLastWatch to watchable
So that we can create custom watchable objects that can add/remove event
listeners as necessary.
2025-10-23 23:38:31 +05:30
R Midhun Suresh 17f1a54a1f Fix comment 2025-10-23 16:11:50 +05:30
R Midhun Suresh 7c40be9054 Change method to property 2025-10-23 16:07:07 +05:30
R Midhun Suresh 4930da1e97 Update api doc 2025-10-23 12:43:10 +05:30
R Midhun Suresh 051fd6e8fe Add method to render room avatar 2025-10-23 12:39:11 +05:30
R Midhun Suresh b9a90b2bfc Render RoomView instead of simply returning it 2025-10-23 12:38:36 +05:30
R Midhun Suresh d0923c7b76 Update api doc 2025-10-23 12:22:39 +05:30
R Midhun Suresh 00f9283262 Add client API 2025-10-23 12:21:22 +05:30
R Midhun Suresh 949e64c7b5 Make field protected so that Watchable can be extended
So that you can have custom watchables that have very specific
behaviour, think `class NameWatchable extends Watchable`. Useful to have
access to `listeners` when you do this.
2025-10-23 12:19:22 +05:30
R Midhun Suresh c24cfb6311 Introduce an abstraction for Room
All APIs that need to return a room will use this type.
2025-10-23 12:18:33 +05:30
David Baker 214f3e20a8 Merge pull request #79 from element-hq/dbkr/module_experiments
Add some module interfaces
2025-10-21 11:03:39 +01:00
David Baker 824f262ac9 Make onSelected non-optional 2025-10-20 17:44:15 +01:00
David Baker a41a7faa75 docs 2025-10-20 17:33:09 +01:00
David Baker 79344ffd31 Update docs 2025-10-20 16:36:48 +01:00
David Baker c938dbe519 Rename contextMenuTooltip to just tooltip
because it has nothing to do with context menus afaics
2025-10-20 16:34:58 +01:00
David Baker b5639c25a4 Fix public/alpha statuses 2025-10-17 12:14:20 +01:00
David Baker e1f7a798a2 More doc 2025-10-17 12:11:39 +01:00
David Baker b83b5f4ad6 Add more docs 2025-10-17 12:10:07 +01:00
David Baker 6d0a715ac0 Tweak doc 2025-10-17 11:56:48 +01:00
Richard van der Hoff 3e31c2387c Merge pull request #83 from element-hq/playwight-common-2.0.0
element-web-playwright-common: bump version to 2.0.0
2025-10-03 17:15:53 +01:00
Richard van der Hoff 31d6b73476 v2.0.0 2025-10-03 17:00:45 +01:00
Richard van der Hoff ecb939a68a Merge pull request #82 from element-hq/rav/new_context
Playwright: add a `createNewInstance` utility function
2025-10-03 16:57:19 +01:00
Richard van der Hoff 24df6be6ce Merge branch 'main' into rav/new_context 2025-10-03 16:24:10 +01:00
Richard van der Hoff b484916ea8 Merge pull request #81 from element-hq/rav/config_json_funcs
Playwright: factor out helpers for config.json
2025-10-03 16:22:37 +01:00
Richard van der Hoff 68de37a6cb Playwright: add a createNewInstance utility function
Sometimes it's useful to be able to use two separate Element-Web instances, in
isolated browsers. This patch adds a utility method which creates such an
instance.
2025-10-03 14:34:22 +01:00
Richard van der Hoff d0c3901a1a Merge remote-tracking branch 'origin/main' into rav/new_context 2025-10-03 14:32:47 +01:00
Richard van der Hoff 595141cf4b Playwright: factor out helpers for config.json
Factor out some helper functions for building `config.json` files,
and adding the relevant routes to browser contexts.
2025-10-03 14:28:35 +01:00
Richard van der Hoff 519bafd68f Merge pull request #80 from element-hq/rav/credentials_funcs
Playwright: add `populateLocalStorageWithCredentials` helper
2025-10-03 12:48:21 +01:00
Richard van der Hoff 92b9896deb Factor out a helper function populateLocalStorageWithCredentials
This just takes the innards of the `pageWithCredentials` fixture and makes it
reusable in contexts outside the fixture. (This can be useful if you want to
use Element with an account other than the default provided by the
`credentials` fixture.)
2025-10-03 12:42:57 +01:00
Richard van der Hoff 885e7c36d9 Add homeserverBaseUrl field to Credentials
`Credentials` is used to record the access token etc once we log in a or
register a user. An access token isn't much use to you unless you know where to
send it, so this patch addes a new field, `homeserverUrl`, which contains
the base public URL for the homeserver.
2025-10-03 12:25:21 +01:00
David Baker cf869c9454 Tweak api so it can be called multiple times
to update the space item's properties.
2025-09-25 17:33:53 +01:00
David Baker 446830776f New interface for adding space panel items 2025-09-25 11:57:13 +01:00
David Baker 9685775528 Maybe make api-extractor happy 2025-09-24 16:07:31 +01:00
David Baker 2cd86f7c3d Add some experimental module interfaces
...with somewhat placeholder names as they're the best I can think of right now:

 * 'Extras': To add new bits of UI to places (specifically the space panel)
 * 'Builtins': For modules to render components that are part of Element Web
 * 'Navigation': For modules to add paths to the URL router
2025-09-24 10:58:41 +01:00
renovate[bot] 85ae19a093 Update dependency vite to v7 2025-09-21 05:26:51 +00:00
dependabot[bot] ac81502c0a Bump the npm_and_yarn group across 1 directory with 2 updates
Bumps the npm_and_yarn group with 1 update in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 6.1.6 to 6.3.6
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.3.6/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.3.6/packages/vite)

Updates `esbuild` from 0.24.2 to 0.25.1
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG-2024.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.24.2...v0.25.1)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.3.6
  dependency-type: direct:development
  dependency-group: npm_and_yarn
- dependency-name: esbuild
  dependency-version: 0.25.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-10 01:49:15 +00:00
Quentin Gliech 44bb9ed71a Merge pull request #48 from element-hq/quenting/fix-mas-config 2025-08-05 12:19:28 +02:00
Quentin Gliech 636cee5dcb Fix the MAS config override ordering 2025-08-05 12:05:04 +02:00
Quentin Gliech d3e9d5bd92 Merge pull request #47 from element-hq/quenting/playwight-common-1.4.5
element-web-playwright-common: bump version to 1.4.5
2025-08-05 11:33:28 +02:00
Quentin Gliech 4a9559bb16 element-web-playwright-common: bump version to 1.4.5 2025-08-05 11:25:47 +02:00
Quentin Gliech f91670f6b5 Merge pull request #46 from element-hq/quenting/better-mas
Simplify the MAS config & allow overriding the Docker image
2025-08-05 11:18:05 +02:00
Quentin Gliech 6520352453 Re-export the MasConfig type again 2025-08-05 11:03:37 +02:00
Quentin Gliech 5360f309f1 Generate accurate MAS config type from its JSON schema 2025-08-05 10:53:24 +02:00
Quentin Gliech b4a59ce009 Re-export the Postgres testcontainer 2025-08-05 09:45:34 +02:00
Quentin Gliech 90a51d4487 Allow overriding the MAS docker image 2025-08-05 09:35:13 +02:00
Quentin Gliech c7f5d91504 Simplify the default MAS configuration 2025-08-05 09:34:16 +02:00
Michael Telatynski dd402c834c Add missing internal dev dependency 2025-07-31 10:15:14 +01:00
Michael Telatynski 7a24eecde8 Add rc_room_creation to Synapse config 2025-07-31 10:10:24 +01:00
Michael Telatynski f397f0bb7d Fix cjs export 2025-07-29 10:29:32 +01:00
Michael Telatynski a3c31d82d6 Bump module-api to v1.4.0 2025-07-28 15:58:30 +01:00
Michael Telatynski 2b1858c436 Merge pull request #38 from element-hq/t3chguy/restricted-guests-api 2025-07-28 10:14:28 +01:00
Michael Telatynski 9c2ca140bb Iterate 2025-07-24 16:27:09 +01:00
Michael Telatynski 41887c61a9 Iterate 2025-07-24 16:27:09 +01:00
David Baker 8fba68db78 1.4.3 2025-07-24 11:07:17 +01:00
David Baker d1d69fbc56 Probably better not to keep this given how spammy it is 2025-07-18 16:54:01 +01:00
David Baker 4df86c4d3f Add options to use playwright screenshot script for other things
In this case, storybook screenshots, but this keeps it so this script
doesnt know about storybook itself (we can move the actual storybook
specific code to here if we standardise on it more).
2025-07-18 15:18:37 +01:00
Michael Telatynski 9f14297827 Merge branch 'main' of github.com:/element-hq/element-web-modules into t3chguy/restricted-guests-api 2025-07-16 15:03:44 +01:00
Will Hunt 6752197562 Merge pull request #42 from element-hq/hs/module-api-v1.3.0
element-web-module-api 1.3.0
2025-07-07 07:43:58 +01:00
Half-Shot 0b82316dbe element-web-module-api 1.3.0 2025-07-04 15:58:54 +01:00
Will Hunt 65ced81a8f Merge pull request #41 from element-hq/hs/add-allow-download
Add message hint to prevent media from being downloaded.
2025-07-04 09:55:38 +01:00
Will Hunt 0b5681bf5b Update custom-components.ts 2025-07-03 14:08:10 +01:00
Half-Shot cfb8c685d4 update sig 2025-07-03 13:06:26 +01:00
Half-Shot 24cc2455f9 Add message hint to prevent media from being downloaded. 2025-07-03 12:35:55 +01:00
Michael Telatynski 20098f132b Iterate 2025-06-24 09:50:02 +01:00
Michael Telatynski 9763807c42 Extend the Module API in prep of restricted-guests module 2025-06-23 09:32:26 +01:00
Michael Telatynski 03c2f2cd5f Add missing glob dependency for playwright-common 2025-06-20 12:09:34 +01:00
Michael Telatynski 46912a6a67 Bump version playwright-common 2025-06-20 11:41:24 +01:00
Michael Telatynski a44fe85209 Fix types 2025-06-20 11:37:09 +01:00
Michael Telatynski 62b8d1b3ab Remove exports from playwright-common package 2025-06-20 11:33:25 +01:00
Michael Telatynski 3ad03e123b Bump element-web-playwright-common version 2025-06-20 11:18:15 +01:00
Michael Telatynski 9bb434a2aa Merge pull request #36 from element-hq/t3chguy/stale-screenshots-reporter 2025-06-20 11:14:17 +01:00
Michael Telatynski 1c8d368cfe Merge pull request #37 from element-hq/t3chguy/allow-extending-synapse-testcontainer 2025-06-20 11:07:19 +01:00
Michael Telatynski a440678ffd Remove console.log 2025-06-20 10:28:38 +01:00
Michael Telatynski 75cf1ee738 Reuse annotation var 2025-06-20 10:28:04 +01:00
Michael Telatynski 78bc53ef0a Iterate 2025-06-20 10:21:26 +01:00
Michael Telatynski a6f851bbdf Iterate 2025-06-20 10:14:18 +01:00
Michael Telatynski 02833dac5e Allow extending SynapseContainer testcontainer 2025-06-20 10:06:49 +01:00
Michael Telatynski 683dfaef69 Add entrypoint 2025-06-20 10:03:32 +01:00
Michael Telatynski 2af22fb54f Add stale-screenshot-reporter.ts 2025-06-20 09:59:28 +01:00
Will Hunt e481865aa6 Merge pull request #35 from element-hq/element-web-module-api-1.2.0
element-web-module-api 1.2.0
2025-06-17 15:37:03 +01:00
Half-Shot fbd7c21ecc element-web-module-api 1.2.0 2025-06-17 15:28:27 +01:00
Will Hunt 433e88670e Merge pull request #34 from element-hq/hs/modules-matrix-event
Replace matrix-js-sdk's MatrixEvent with our own representation
2025-06-17 14:21:08 +01:00
Half-Shot 0d4a45d447 Update custom components API to have @alpha stability. 2025-06-17 14:07:06 +01:00
Half-Shot e2a89888c2 Mark MatrixEvent as @alpha and document. 2025-06-17 14:02:41 +01:00
Half-Shot c49ac2677b copyright 2025-06-17 13:42:54 +01:00
Half-Shot b38f0f2dd2 Drop js-sdk 2025-06-17 13:33:41 +01:00
Half-Shot 56d0c5656a API update\ 2025-06-17 13:30:47 +01:00
Half-Shot 89102aa903 fixup types 2025-06-17 13:27:50 +01:00
Half-Shot ead847ec6a Use MatrixEvent provided by us. 2025-06-17 13:16:01 +01:00
Will Hunt 66f83a9663 Merge pull request #33 from element-hq/hs/module-api-v1.1.0
element-web-module-api 1.1.0
2025-06-16 14:13:50 +01:00
Half-Shot 4e8c99dfd1 1.1.0 2025-06-16 12:05:28 +01:00
Will Hunt e5bbf7b45d Merge pull request #32 from element-hq/hs/custom-component-api
Support custom components for messages
2025-06-12 14:23:36 +01:00
Half-Shot cea6abfca5 Update API docs 2025-06-12 10:58:45 +01:00
Half-Shot 240045f433 Add filter function / hints 2025-06-09 15:41:53 +01:00
Half-Shot 8cf426f0e7 tighten example 2025-06-05 16:57:48 +01:00
Half-Shot 60687b27a6 Add an example 2025-06-05 16:10:35 +01:00
Half-Shot c6a6123826 Remove unused props 2025-06-05 10:01:40 +01:00
Half-Shot e2ae6f2288 Specify options for the original component. 2025-06-05 09:58:51 +01:00
Michael Telatynski 3941f99e17 Bump playwright-common version 2025-06-04 16:29:41 +01:00
Michael Telatynski 0eba5281fa Merge pull request #30 from element-hq/t3chguy-patch-1 2025-06-04 16:23:46 +01:00
Michael Telatynski 3befdeb167 Update mas.ts 2025-06-04 14:02:42 +01:00
Half-Shot 546861811c fixup 2025-06-03 13:41:57 +01:00
Will Hunt 0a9dffb132 Merge branch 'main' into hs/custom-component-api 2025-05-30 15:27:34 +01:00
Half-Shot 930a5eb8b7 Update module API 2025-05-30 14:51:38 +01:00
Michael Telatynski 627355e24c Merge pull request #28 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-432704706d 2025-05-28 17:24:16 +01:00
dependabot[bot] b480633c15 Bump vite in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 6.0.11 to 6.1.6
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.1.6/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.1.6/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.1.6
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-28 15:43:59 +00:00
Michael Telatynski b9f200d349 Update testcontainers to v11 2025-05-28 16:41:43 +01:00
Michael Telatynski b75c7ee34d Merge pull request #22 from element-hq/t3chguy/banner 2025-05-22 09:26:14 +01:00
Half-Shot ba5ce17574 docs fix 2025-05-20 13:00:47 +01:00
Half-Shot 908771235f Tidyup 2025-05-20 12:14:20 +01:00
Half-Shot e972c05ccc Remove context menu 2025-05-20 12:11:07 +01:00
Half-Shot 50fc7bec66 lint 2025-05-19 11:56:53 +01:00
Half-Shot b5a7bd9eac Document and types' 2025-05-19 09:16:27 +01:00
Half-Shot c9ea5f8f4f Custom component concept piece 2025-05-16 15:49:07 +01:00
Michael Telatynski c94eb986d5 Merge branch 'main' of github.com:/element-hq/element-web-modules into t3chguy/banner
# Conflicts:
#	modules/opendesk/element-web/package.json
#	packages/element-web-module-api/package.json
#	yarn.lock
2025-05-14 09:25:00 +01:00
Michael Telatynski 079f3392bb Merge pull request #24 from element-hq/t3chguy/module-api-v1 2025-05-13 17:19:20 +01:00
Michael Telatynski eda354505d Merge branch 'main' into t3chguy/module-api-v1 2025-05-13 12:35:18 +01:00
Michael Telatynski 6d58d9090f Merge pull request #23 from element-hq/t3chguy/standard-scripts 2025-05-13 12:35:04 +01:00
Michael Telatynski d2c2437188 Remove stray files 2025-05-13 10:48:17 +01:00
Michael Telatynski 5927495c88 Remove stray files 2025-05-13 10:45:18 +01:00
Michael Telatynski d7736db1af Initial stable release of the Module API
Primarily to get away from semver treating every update as breaking in the 0.x.y series.
2025-05-13 10:40:26 +01:00
Michael Telatynski 7157587668 Bump element-web-playwright-common version 2025-05-09 17:09:03 +01:00
Michael Telatynski 29d1c61d82 Update mas version 2025-05-09 17:08:40 +01:00
Michael Telatynski 4b56b98d20 Merge branch 't3chguy/standard-scripts' of github.com:/element-hq/element-web-modules into t3chguy/banner 2025-05-08 12:33:21 +01:00
Michael Telatynski 2b1fb75f44 Standardise lint/type scripts between modules/packages 2025-05-08 12:23:13 +01:00
Michael Telatynski b55feb5a7b Standardise lint/type scripts between modules/packages 2025-05-08 12:23:13 +01:00
Michael Telatynski 03e04dec08 Create module element-web-module-banner 2025-05-08 12:06:05 +01:00
Michael Telatynski ad0a276af2 Bump element-web-playwright-common version 2025-05-07 12:02:12 +01:00
Michael Telatynski afcf4593bc Merge pull request #19 from element-hq/t3chguy/tar-fs 2025-05-07 08:35:33 +01:00
Michael Telatynski df54bc9a52 Merge pull request #19 from element-hq/t3chguy/tar-fs 2025-05-07 08:35:33 +01:00
Michael Telatynski e8ed2f8f41 Update playwright 2025-04-30 13:26:49 +01:00
Michael Telatynski 737d306f53 Iterate 2025-04-28 12:43:17 +01:00
Michael Telatynski 586ad25600 Update testcontainers, tar-fs and remove duplicate script and stray lockfiles 2025-04-11 09:26:32 +01:00
Michael Telatynski f0686ce9a6 Update testcontainers, tar-fs and remove duplicate script and stray lockfiles 2025-04-11 09:26:32 +01:00
Michael Telatynski 8ddc8020d7 Merge pull request #16 from element-hq/t3chguy/docker-avoid-tmp
Update EW modules docker path
2025-03-27 12:00:21 +00:00
Michael Telatynski 12463365d6 Merge branch 'main' into t3chguy/docker-avoid-tmp 2025-03-27 10:44:40 +00:00
Michael Telatynski bb972bb084 Merge pull request #18 from element-hq/t3chguy-patch-1
Make mas-cli testcontainer method public
2025-03-25 10:32:01 +00:00
Michael Telatynski d93c34926b Make mas-cli testcontainer method public 2025-03-21 17:34:39 +00:00
Michael Telatynski f1372747db Merge pull request #13 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-2c631a4876
Bump @babel/runtime from 7.26.0 to 7.26.10 in the npm_and_yarn group across 1 directory
2025-03-13 16:49:14 +00:00
Michael Telatynski 46a5a594f5 Update Dockerfile to consider all package.json files for frozen lockfile 2025-03-13 16:43:03 +00:00
Michael Telatynski 6837bbab67 Update EW modules docker path 2025-03-13 14:06:02 +00:00
Michael Telatynski 98cc18fd5f Bump versions 2025-03-13 11:59:43 +00:00
Michael Telatynski 2954e39346 Bump versions 2025-03-13 11:59:43 +00:00
Michael Telatynski e6bdd86c4c Fix repository URLs 2025-03-13 11:59:17 +00:00
Michael Telatynski 3825bd80cd Fix repository URLs 2025-03-13 11:59:17 +00:00
Michael Telatynski df19fbc259 Specify node version 2025-03-13 11:55:10 +00:00
Michael Telatynski 8cfa277cd8 Specify node version 2025-03-13 11:55:10 +00:00
Michael Telatynski 98ae690c6f Who'd have thunk provenance doesn't behave as the docs describe 2025-03-13 11:40:42 +00:00
Michael Telatynski a9b1311cb3 Who'd have thunk provenance doesn't behave as the docs describe 2025-03-13 11:40:42 +00:00
Michael Telatynski 0fa87a2d7e Fix package.json bin & repository fields 2025-03-13 11:32:18 +00:00
Michael Telatynski 2f1bc2ab78 Fix package.json bin & repository fields 2025-03-13 11:32:18 +00:00
Michael Telatynski 5d866e86ba Add repository field to fix provenance 2025-03-13 11:24:52 +00:00
Michael Telatynski cae6c42eb4 Iterate 2025-03-12 11:41:28 +00:00
Michael Telatynski 2fa2805b8d Iterate 2025-03-12 11:31:38 +00:00
Michael Telatynski c9288b846e Iterate 2025-03-12 10:50:09 +00:00
Michael Telatynski 0a4706da1e Iterate 2025-03-12 10:39:48 +00:00
Michael Telatynski 0b12fac200 Iterate 2025-03-12 10:33:29 +00:00
Michael Telatynski 5f28c50af8 Create playwright-common package 2025-03-12 10:15:24 +00:00
Michael Telatynski ca0b82d6e3 Merge pull request #6 from element-hq/t3chguy/docker-bake
Add release & publishing pipelines for Element Web modules
2025-03-04 09:22:45 +00:00
Michael Telatynski ea906ed8a9 Iterate 2025-03-03 13:09:10 +00:00
Michael Telatynski f004a93e15 Iterate 2025-03-03 12:30:57 +00:00
Michael Telatynski 3a729d0487 Stash docker & bake 2025-02-25 15:29:56 +00:00
Andrew Ferrazzutti 3ecce9efe0 Merge pull request #5 from element-hq/af/workflow-fixes
* Fix synapse guest module releases
* Make other miscellaneous workflow fixes/improvements
2025-02-18 11:08:09 -05:00
Michael Telatynski 418598caa8 Merge branch 'main' of github.com:/element-hq/element-web-modules into t3chguy/docker-bake 2025-02-18 09:59:53 +00:00
Michael Telatynski 0d32376f8d Add docker bake environment
with support for building an Element Web docker image with build & runtime module loader
with support for building docker images with a module pre-baked in
2025-02-17 09:49:12 +00:00
Andrew Ferrazzutti d45edc8c4d Include Python in static analysis job
Also refactor "yarn lint" of each module/package to run whatever lint
task is appropriate for it
2025-02-13 16:04:03 -05:00
Andrew Ferrazzutti 3253b73029 Merge pull request #3 from element-hq/af/nordeck-synapse-guest-module
Add Nordeck's Synapse Guest Module
2025-02-13 12:53:25 -05:00
Michael Telatynski 96893e8191 Merge branch 'main' into af/nordeck-synapse-guest-module 2025-02-13 17:14:04 +00:00
Andrew Ferrazzutti 1744b18955 Make "yarn test" always enable coverage 2025-02-13 11:37:53 -05:00
Michael Telatynski 30ac522e83 Merge pull request #4 from element-hq/dependabot/npm_and_yarn/npm_and_yarn-d608bfffa8
Bump vitest from 3.0.4 to 3.0.5 in the npm_and_yarn group across 1 directory
2025-02-12 14:43:10 +00:00
dependabot[bot] e1c29f6ff1 Bump vitest in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).


Updates `vitest` from 3.0.4 to 3.0.5
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v3.0.5/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-12 13:18:06 +00:00
Michael Telatynski 47be004a2c Fix sonar-project.properties and be consistent with test naming 2025-01-31 09:40:51 +00:00
Michael Telatynski dd521f5a21 v0.1.1 2025-01-31 09:17:08 +00:00
Michael Telatynski b8633472eb Merge pull request #2 from element-hq/t3chguy/123 2025-01-31 09:09:59 +00:00
Michael Telatynski af435b4f1a Delint 2025-01-30 15:14:30 +00:00
Michael Telatynski 8d05c5329e Iterate 2025-01-30 15:12:15 +00:00
Michael Telatynski 0a2f311cc8 Wire up tests & sonarcloud 2025-01-30 10:58:23 +00:00
Michael Telatynski 06fcf783a1 Fix isModule check not working for new class modules 2025-01-30 10:57:18 +00:00
Michael Telatynski 776d07730a Prettier -_- 2025-01-29 10:56:48 +00:00
Michael Telatynski 2edfce5e7a Iterate 2025-01-29 10:50:56 +00:00
Michael Telatynski 3a5baec699 Iterate 2025-01-29 10:48:35 +00:00
Michael Telatynski 3d94420f9f Iterate 2025-01-29 09:02:46 +00:00
Michael Telatynski b0c81d53d9 Iterate 2025-01-29 08:35:40 +00:00
Michael Telatynski 505533a5f5 Iterate 2025-01-28 17:38:52 +00:00
Michael Telatynski 35b33ac893 Iterate 2025-01-28 11:52:33 +00:00
Michael Telatynski 0e8315493e Iterate 2025-01-28 11:31:38 +00:00
Michael Telatynski e71f9e327e Iterate 2025-01-28 11:27:53 +00:00
Michael Telatynski 5bc85e8ae4 Iterate 2025-01-28 11:03:02 +00:00
Michael Telatynski 3dde93bb69 Initial runtime Modules work 2025-01-27 10:11:16 +00:00
1035 changed files with 52734 additions and 30961 deletions
+4 -3
View File
@@ -4,12 +4,13 @@
/pnpm-lock.yaml @element-hq/element-web-team
/apps/web/src/SecurityManager.ts @element-hq/element-crypto-web-reviewers
/apps/web/test/SecurityManager-test.ts @element-hq/element-crypto-web-reviewers
/apps/web/test/unit-tests/SecurityManager-test.ts @element-hq/element-crypto-web-reviewers
/apps/web/src/async-components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
/apps/web/test/unit-tests/async-components/dialogs/security/ @element-hq/element-crypto-web-reviewers
/apps/web/src/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
/apps/web/test/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
/apps/web/test/unit-tests/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
/apps/web/src/stores/SetupEncryptionStore.ts @element-hq/element-crypto-web-reviewers
/apps/web/test/stores/SetupEncryptionStore-test.ts @element-hq/element-crypto-web-reviewers
/apps/web/test/unit-tests/stores/SetupEncryptionStore-test.ts @element-hq/element-crypto-web-reviewers
/apps/web/src/components/views/settings/tabs/user/EncryptionUserSettingsTab.tsx @element-hq/element-crypto-web-reviewers
/apps/web/src/components/views/settings/encryption/ @element-hq/element-crypto-web-reviewers
/apps/web/test/unit-tests/components/views/settings/encryption/ @element-hq/element-crypto-web-reviewers
@@ -11,7 +11,7 @@ runs:
using: composite
steps:
- name: Download release tarball
uses: robinraju/release-downloader@daf26c55d821e836577a15f77d86ddc078948b05 # v1
uses: robinraju/release-downloader@28fc21f50d76778e7023361aa1f863e717d3d56f # v1
with:
tag: ${{ inputs.tag }}
fileName: element-*.tar.gz*
@@ -31,7 +31,9 @@ runs:
- name: Move webapp to out-file-path
shell: bash
run: mv ${{ runner.temp }}/download-verify-element-tarball/webapp ${{ inputs.out-file-path }}
run: mv ${{ runner.temp }}/download-verify-element-tarball/webapp "$OUT_PATH"
env:
OUT_PATH: ${{ inputs.out-file-path }}
- name: Clean up temp directory
shell: bash
@@ -0,0 +1,49 @@
name: Setup playwright
description: Installs playwright browsers and sets up a cache
inputs:
needs-webkit:
description: Whether to install the additional dependencies for webkit
required: false
default: "false"
write-cache:
description: Whether to write the cache back
required: true
runs:
using: composite
steps:
- name: Calculate cache key
id: key
run: |
PW_VERSION=$(pnpm --silent -- playwright --version | awk '{print $2}')
echo "key=${PREFIX}-playwright-${PW_VERSION}" >> $GITHUB_OUTPUT
shell: bash
env:
PREFIX: ${{ runner.os }}-${{ runner.arch }}
- name: Cache playwright binaries
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
if: inputs.write-cache == 'true'
id: cache
with:
path: ~/.cache/ms-playwright
key: ${{ steps.key.outputs.key }}
# When running in merge queue only restore the cache, never write it
- name: Restore playwright binaries cache
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
if: inputs.write-cache != 'true'
id: cache-restore
with:
path: ~/.cache/ms-playwright
key: ${{ steps.key.outputs.key }}
- name: Install Playwright browsers
if: (steps.cache.outputs.cache-hit || steps.cache-restore.outputs.cache-hit) != 'true'
shell: bash
run: pnpm playwright install --with-deps
# Some WebKit dependencies seem to lay outside the cache and will need to be installed separately
- name: Install system dependencies for WebKit
if: inputs.needs-webkit == 'true' && (steps.cache.outputs.cache-hit || steps.cache-restore.outputs.cache-hit) == 'true'
shell: bash
run: pnpm playwright install-deps webkit
+33 -2
View File
@@ -2,14 +2,45 @@
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["github>matrix-org/renovate-config-element-web"],
"postUpdateOptions": ["pnpmDedupe"],
"stopUpdatingLabel": "X-Blocked",
"packageRules": [
{
"description": "Group all testcontainers docker digests",
"groupName": "testcontainers docker digests",
"groupSlug": "testcontainers-docker",
"matchDepTypes": ["testcontainers-docker"],
"matchPackageNames": ["*"]
},
{
"description": "Separate updates to overrides from other groups",
"matchDepTypes": ["pnpm.overrides"],
"groupSlug": null
},
{
"description": "Disable any major updates to overrides as this almost always is wrong",
"matchDepTypes": ["pnpm.overrides"],
"matchUpdateTypes": ["major"],
"enabled": false
}
],
"customManagers": [
{
"description": "Update testcontainers docker digests",
"customType": "regex",
"datasourceTemplate": "docker",
"versioningTemplate": "loose",
"description": "Update testcontainers docker digests",
"managerFilePatterns": ["**/testcontainers/*.ts"],
"matchStrings": ["\\s+\"(?<depName>[^@]+):(?<currentValue>[^@]+)@(?<currentDigest>sha256:[a-f0-9]+)\""]
"matchStrings": ["\\s+\"(?<depName>[^@]+):(?<currentValue>[^@]+)@(?<currentDigest>sha256:[a-f0-9]+)\""],
"depTypeTemplate": "testcontainers-docker"
},
{
"description": "Update element-desktop hakDependencies",
"customType": "jsonata",
"managerFilePatterns": ["/(^|/)package\\.json$/"],
"fileFormat": "json",
"matchStrings": ["hakDependencies.$each(function($v, $k) { { 'packageName': $k, 'currentValue': $v } })"],
"datasourceTemplate": "npm",
"depTypeTemplate": "hak"
}
]
}
@@ -5,7 +5,7 @@ on:
# Privilege escalation necessary to publish to Netlify
# 🚨 We must not execute any checked out code here.
workflow_run: # zizmor: ignore[dangerous-triggers]
workflows: ["End to End Tests"]
workflows: ["Build & Test"]
types:
- completed
@@ -1,7 +1,13 @@
# Produce a build of element-web with this version of react-sdk
# and any matching branches of element-web and js-sdk, output it
# as an artifact and run end-to-end tests.
name: End to End Tests
# builds Element Web
# runs Playwright tests against the built Element Web
# builds Element Desktop using the built Element Web
#
# 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:
# CRON to run all Projects at 6am UTC
schedule:
@@ -10,9 +16,8 @@ on:
merge_group:
types: [checks_requested]
push:
branches: [develop, master]
repository_dispatch:
types: [element-web-notify]
# We do not build on push to develop as the merge_group check handles that
branches: [staging, master]
# support triggering from other workflows
workflow_call:
@@ -35,20 +40,22 @@ concurrency:
env:
# fetchdep.sh needs to know our PR 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)
NUM_RUNNERS: ${{ github.event_name == 'schedule' && 4 || 6 }}
# 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' && 1 || 4 }}
NX_DEFAULT_OUTPUT_STYLE: stream-without-prefixes
permissions: {} # No permissions required
jobs:
build:
name: "Build Element-Web"
build_ew:
name: "Build Element Web"
runs-on: ubuntu-24.04
if: inputs.skip != true
outputs:
num-runners: ${{ env.NUM_RUNNERS }}
runners-matrix: ${{ steps.runner-vars.outputs.matrix }}
# Skip pull_request runs on renovate PRs to speed up CI time, delegating to the full run in merge queue
skip: ${{ inputs.skip || (github.event_name == 'pull_request' && startsWith(github.head_ref, 'renovate/')) }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
@@ -57,7 +64,7 @@ jobs:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
cache: "pnpm"
node-version: "lts/*"
@@ -79,7 +86,7 @@ jobs:
run: VERSION=$(scripts/get-version-from-git.sh) pnpm run build
- name: Upload Artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: webapp
path: apps/web/webapp
@@ -87,17 +94,17 @@ jobs:
- name: Calculate runner variables
id: runner-vars
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
const numRunners = parseInt(process.env.NUM_RUNNERS, 10);
const matrix = Array.from({ length: numRunners }, (_, i) => i + 1);
core.setOutput("matrix", JSON.stringify(matrix));
playwright:
name: "Run Tests [${{ matrix.project }}] ${{ matrix.runner }}/${{ needs.build.outputs.num-runners }}"
needs: build
if: inputs.skip != true
playwright_ew:
name: "Run Tests [${{ matrix.project }}] ${{ matrix.runner }}/${{ needs.build_ew.outputs.num-runners }}"
needs: build_ew
if: needs.build_ew.outputs.skip == 'false'
runs-on: ubuntu-24.04
permissions:
actions: read
@@ -107,7 +114,7 @@ jobs:
fail-fast: false
matrix:
# 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:
- Chrome
- Firefox
@@ -139,7 +146,7 @@ jobs:
path: apps/web/webapp
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
cache: "pnpm"
cache-dependency-path: pnpm-lock.yaml
@@ -148,105 +155,155 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Get installed Playwright version
id: playwright
run: echo "version=$(pnpm --silent -- playwright --version | awk '{print $2}')" >> $GITHUB_OUTPUT
- name: Cache playwright binaries
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
id: playwright-cache
- name: Setup playwright
uses: ./.github/actions/setup-playwright
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ steps.playwright.outputs.version }}
- name: Install Playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
working-directory: apps/web
run: pnpm playwright install --with-deps --no-shell
- name: Install system dependencies for WebKit
# Some WebKit dependencies seem to lay outside the cache and will need to be installed separately
if: matrix.project == 'WebKit' && steps.playwright-cache.outputs.cache-hit == 'true'
working-directory: apps/web
run: pnpm playwright install-deps webkit
needs-webkit: ${{ matrix.project == 'WebKit' }}
write-cache: ${{ github.event_name != 'merge_group' }}
# We skip tests tagged with @mergequeue when running on PRs, but run them in MQ and everywhere else
- name: Run Playwright tests
working-directory: apps/web
run: |
pnpm playwright test \
pnpm test:playwright \
--shard "$SHARD" \
--project="${{ matrix.project }}" \
${{ (github.event_name == 'pull_request' && matrix.runAllTests == false ) && '--grep-invert @mergequeue' || '' }}
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
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: all-blob-reports-${{ matrix.project }}-${{ matrix.runner }}
name: blob-report-${{ matrix.project }}-${{ matrix.runner }}
path: apps/web/blob-report
retention-days: 1
if-no-files-found: error
downstream-modules:
name: Downstream Playwright tests [element-modules]
needs: build
if: inputs.skip != true && github.event_name == 'merge_group'
needs: build_ew
if: needs.build_ew.outputs.skip == 'false' && github.event_name == 'merge_group'
uses: element-hq/element-modules/.github/workflows/reusable-playwright-tests.yml@main # zizmor: ignore[unpinned-uses]
with:
webapp-artifact: webapp
reporter: blob
prepare_ed:
name: "Prepare Element Desktop"
uses: ./.github/workflows/build_desktop_prepare.yaml
needs: build_ew
if: needs.build_ew.outputs.skip == 'false'
permissions:
contents: read
with:
config: ${{ (github.event.pull_request.base.ref || github.ref_name) == 'develop' && 'element.io/nightly' || 'element.io/release' }}
version: ${{ case((github.event.pull_request.base.ref || github.ref_name) == 'develop' || github.event_name == 'merge_group', 'develop', '') }}
webapp-artifact: webapp
build_ed_windows:
needs: prepare_ed
name: "Desktop Windows"
uses: ./.github/workflows/build_desktop_windows.yaml
# Skip Windows builds on PRs, as the Linux amd64 build is enough of a smoke test and includes the screenshot tests
if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'X-Run-All-Tests')
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
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') }}
exclude:
# We ship static sqlcipher builds, so delegate testing the system builds to the merge queue
- runAllTests: false
sqlcipher: system
# Additionally skip arm64 system builds on PRs, as the amd64 test is enough for a smoke test and includes the screenshot tests
- runAllTests: false
arch: arm64
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
# Skip macOS builds on PRs, as the Linux amd64 build is enough of a smoke test and includes the screenshot tests
# and we have a very low limit of concurrent macos runners (5) across the Github org.
if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'X-Run-All-Tests')
with:
blob_report: true
complete:
name: end-to-end-tests
needs:
- playwright
- build_ew
- playwright_ew
- downstream-modules
- prepare_ed
- build_ed_windows
- build_ed_linux
- build_ed_macos
if: always()
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
if: inputs.skip != true
if: needs.build_ew.outputs.skip == 'false'
with:
persist-credentials: false
repository: element-hq/element-web
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
if: inputs.skip != true
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
if: inputs.skip != true
if: needs.build_ew.outputs.skip == 'false'
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
if: needs.build_ew.outputs.skip == 'false'
with:
cache: "pnpm"
node-version: "lts/*"
- name: Install dependencies
if: inputs.skip != true
if: needs.build_ew.outputs.skip == 'false'
run: pnpm install --frozen-lockfile
- name: Download blob reports from GitHub Actions Artifacts
if: inputs.skip != true
if: needs.build_ew.outputs.skip == 'false'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
pattern: all-blob-reports-*
path: apps/web/all-blob-reports
pattern: blob-report-*
path: all-blob-reports
merge-multiple: true
- name: Merge into HTML Report
if: inputs.skip != true
working-directory: apps/web
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
if: needs.build_ew.outputs.skip == 'false'
run: |
pnpm playwright merge-reports \
--config=playwright-merge.config.ts \
./all-blob-reports
env:
# Only pass creds to the flaky-reporter on main branch runs
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
- name: Upload HTML report
if: always() && inputs.skip != true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
if: always() && needs.build_ew.outputs.skip == 'false'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: html-report
path: apps/web/playwright-report
path: playwright-report
retention-days: 14
if-no-files-found: error
+2 -2
View File
@@ -48,7 +48,7 @@ jobs:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
# Disable cache on Windows as it is slower than not caching
# https://github.com/actions/setup-node/issues/975
@@ -69,7 +69,7 @@ jobs:
run: VERSION=$(scripts/get-version-from-git.sh) pnpm run build
- name: Upload Artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: webapp-${{ matrix.image }}
path: apps/web/webapp
+1 -1
View File
@@ -69,7 +69,7 @@ jobs:
dpkg-gencontrol -v"$VERSION" -ldebian/tmp/DEBIAN/changelog
dpkg-deb -Zxz --root-owner-group --build debian/tmp element-web.deb
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: element-web.deb
path: apps/web/element-web.deb
@@ -212,7 +212,7 @@ jobs:
- name: Stash packages.element.io
if: needs.prepare.outputs.deploy == 'false'
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: packages.element.io
path: packages.element.io
@@ -250,7 +250,7 @@ jobs:
- name: Stash debs
if: needs.prepare.outputs.deploy == 'false' && needs.linux.result == 'success'
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: debs
path: |
@@ -289,7 +289,7 @@ jobs:
id-token: write # This is required for requesting the JWT
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6
uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6
with:
role-to-assume: arn:aws:iam::264135176173:role/Push-ElementDesktop-MSI
role-session-name: githubaction-run-${{ github.run_id }}
@@ -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
+10 -24
View File
@@ -28,7 +28,7 @@ on:
type: string
required: false
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:
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
+ 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,
for example icons in the `build/` directory to override the app icons.
default: "webapp"
default: "desktop-prepare"
test:
type: boolean
required: false
@@ -73,20 +73,8 @@ jobs:
# https://github.com/matrix-org/seshat/issues/135
runs-on: ${{ inputs.runs-on || (inputs.arch == 'arm64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04') }}
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:
- 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
id: config
with:
@@ -95,11 +83,9 @@ jobs:
map: |
{
"amd64": {
"target": "x86_64-unknown-linux-gnu",
"arch": "x86-64"
},
"arm64": {
"target": "aarch64-unknown-linux-gnu",
"arch": "aarch64",
"build-args": "--arm64"
}
@@ -118,14 +104,14 @@ jobs:
- name: Cache .hak
id: cache
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
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: |
apps/desktop/.hak
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version-file: apps/desktop/.node-version
cache: "pnpm"
@@ -135,19 +121,19 @@ jobs:
- name: Install Deps
working-directory: apps/desktop
run: pnpm install --frozen-lockfile
run: "pnpm install --frozen-lockfile --filter element-desktop"
- name: "Get modified files"
id: changed_files
if: steps.cache.outputs.cache-hit != 'true' && github.event_name == 'pull_request' && github.repository == 'element-hq/element-web'
uses: tj-actions/changed-files@823fcebdb31bb35fdf2229d9f769b400309430d0 # v46
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47
with:
files: |
apps/desktop/dockerbuild/**
# This allows contributors to test changes to the dockerbuild image within a pull request
- name: Build docker image
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
if: steps.changed_files.outputs.any_modified == 'true'
with:
file: apps/desktop/dockerbuild/Dockerfile
@@ -230,7 +216,7 @@ jobs:
# We exclude *-unpacked as it loses permissions and the tarball contains it with correct permissions
- name: Upload Artifacts
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: ${{ inputs.artifact-prefix }}linux-${{ inputs.arch }}-sqlcipher-${{ inputs.sqlcipher }}
path: |
+7 -7
View File
@@ -37,7 +37,7 @@ on:
type: string
required: false
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:
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
+ 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,
for example icons in the `build/` directory to override the app icons.
default: "webapp"
default: "desktop-prepare"
test:
type: boolean
required: false
@@ -90,9 +90,9 @@ jobs:
- name: Cache .hak
id: cache
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
key: ${{ runner.os }}-${{ hashFiles('hakHash', 'electronVersion') }}
key: ${{ runner.os }}-${{ hashFiles('apps/desktop/hakHash', 'apps/desktop/electronVersion') }}
path: |
apps/desktop/.hak
@@ -114,14 +114,14 @@ jobs:
- run: sudo pip3 install pyobjc-framework-Quartz
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version-file: apps/desktop/.node-version
cache: "pnpm"
- name: Install Deps
working-directory: apps/desktop
run: "pnpm install --frozen-lockfile"
run: "pnpm install --frozen-lockfile --filter element-desktop"
- name: Build Natives
if: steps.cache.outputs.cache-hit != 'true'
@@ -194,7 +194,7 @@ jobs:
# We exclude mac-universal as the unpacked app takes forever to upload and zip and dmg already contains it
- name: Upload Artifacts
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: ${{ inputs.artifact-prefix }}macos
path: |
+19 -21
View File
@@ -20,11 +20,10 @@ on:
required: false
default: false
description: "Whether the build should be deployed to production"
branch-matching:
type: boolean
webapp-artifact:
type: string
required: false
default: false
description: "Whether the branch name should be matched to find the element-web commit"
description: "Name of the webapp artifact that should be used, will fetch a relevant build if omitted"
secrets:
# Required if `nightly` is set
CF_R2_ACCESS_KEY_ID:
@@ -57,37 +56,36 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
repository: element-hq/element-web
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version-file: apps/desktop/.node-version
cache: "pnpm"
- name: Install Deps
working-directory: apps/desktop
run: "pnpm install --frozen-lockfile"
run: "pnpm install --frozen-lockfile --filter element-desktop"
- name: Fetch Element Web (matching branch)
id: branch-matching
if: inputs.branch-matching
- name: Fetch Element Web (from artifact)
if: inputs.webapp-artifact != ''
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
continue-on-error: true
run: |
scripts/branch-match.sh
cp "$CONFIG_DIR/config.json" element-web/
pnpm --cwd element-web install --frozen-lockfile
pnpm --cwd element-web run build
mv element-web/webapp .
cp -f "$CONFIG_DIR/config.json" webapp/config.json
pnpm run asar-webapp
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 }}
- 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
run: pnpm run fetch --noverify -d ${CONFIG} ${VERSION}
env:
@@ -187,9 +185,9 @@ jobs:
env:
NIGHTLY_VERSION: ${{ steps.versions.outputs.nightly }}
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: webapp
name: desktop-prepare
retention-days: 1
path: |
apps/desktop/webapp.asar
+18 -9
View File
@@ -38,18 +38,17 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
repository: ${{ github.repository == 'element-hq/element-web-pro' && 'element-hq/element-web' || github.repository }}
repository: element-hq/element-web
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version-file: apps/desktop/.node-version
cache: "pnpm"
- name: Install Deps
working-directory: apps/desktop
run: "pnpm install --frozen-lockfile"
run: "pnpm install --frozen-lockfile --filter element-desktop"
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
@@ -85,25 +84,35 @@ jobs:
EXECUTABLE: ${{ steps.executable.outputs.path }}
- name: Run tests
uses: coactions/setup-xvfb@6b00cf1889f4e1d5a48635647013c0508128ee1a
timeout-minutes: 20
with:
run: pnpm -C apps/desktop test --project=${{ inputs.project }} ${{ runner.os != 'Linux' && '--ignore-snapshots' || '' }} ${{ inputs.blob_report == false && '--reporter=html' || '' }} ${{ inputs.args }}
shell: bash
working-directory: apps/desktop
run: |
$PREFIX pnpm playwright test \
${{ runner.os != 'Linux' && '--ignore-snapshots' || '' }} \
${{ inputs.blob_report == false && '--reporter=html' || '' }} \
$ARGS
env:
PREFIX: ${{ runner.os == 'Linux' && 'xvfb-run' || '' }}
PW_TAG: ${{ inputs.project }}
ELEMENT_DESKTOP_EXECUTABLE: ${{ steps.executable.outputs.path }}
ARGS: ${{ inputs.args }}
DEBUG: pw:browser
- name: Upload blob report
if: always() && inputs.blob_report
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: blob-report-${{ inputs.artifact }}
path: apps/desktop/blob-report
retention-days: 1
if-no-files-found: error
- name: Upload HTML report
if: always() && inputs.blob_report == false
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: ${{ inputs.artifact }}-test
path: apps/desktop/playwright-report
retention-days: 14
if-no-files-found: error
+7 -7
View File
@@ -42,7 +42,7 @@ on:
type: string
required: false
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:
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
+ 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,
for example icons in the `build/` directory to override the app icons.
default: "webapp"
default: "desktop-prepare"
test:
type: boolean
required: false
@@ -121,9 +121,9 @@ jobs:
- name: Cache .hak
id: cache
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
key: ${{ runner.os }}-${{ inputs.arch }}-${{ hashFiles('hakHash', 'electronVersion') }}
key: ${{ runner.os }}-${{ inputs.arch }}-${{ hashFiles('apps/desktop/hakHash', 'apps/desktop/electronVersion') }}
path: |
apps/desktop/.hak
@@ -153,14 +153,14 @@ jobs:
TARGET: ${{ steps.config.outputs.target }}
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version-file: apps/desktop/.node-version
cache: "pnpm"
- name: Install Deps
working-directory: apps/desktop
run: "pnpm install --frozen-lockfile"
run: "pnpm install --frozen-lockfile --filter element-desktop"
- name: Insert config snippet
if: steps.config.outputs.extra_config != ''
@@ -274,7 +274,7 @@ jobs:
| ForEach-Object -Process {. $env:SIGNTOOL_PATH verify /pa $_.FullName; if(!$?) { throw }}
- name: Upload Artifacts
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: ${{ inputs.artifact-prefix }}win-${{ inputs.arch }}
path: |
+3 -3
View File
@@ -33,7 +33,7 @@ jobs:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
cache: "pnpm"
node-version: "lts/*"
@@ -60,7 +60,7 @@ jobs:
- run: mv dist/element-*.tar.gz dist/develop.tar.gz
working-directory: apps/web
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: webapp
path: apps/web/dist/develop.tar.gz
@@ -111,7 +111,7 @@ jobs:
running-workflow-name: "Build & Deploy develop.element.io"
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 10
check-regexp: ^((?!SonarCloud|SonarQube|issue|board|label|Release|prepare|GitHub Pages|Upload).)*$
check-regexp: ^((?!SonarCloud|SonarQube|issue|board|label|Release|prepare|GitHub Pages|Upload|Netlify|Report).)*$
# We keep the latest develop.tar.gz on R2 instead of relying on the github artifact uploaded earlier
# as the expires after 24h and requires auth to download.
+10 -3
View File
@@ -2,6 +2,13 @@ name: CD # Continuous Delivery
on:
push:
branches: [master, staging, develop]
paths:
- "**/Dockerfile"
- "**/dockerbuild"
- "**/docker"
- "**/docker-*"
- "pnpm-lock.yaml"
concurrency: ${{ github.workflow }}-${{ github.ref_name }}
permissions: {}
@@ -24,7 +31,7 @@ jobs:
persist-credentials: false
- name: Install Cosign
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3
uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
- name: Set up QEMU
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4
@@ -34,7 +41,7 @@ jobs:
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version-file: package.json
cache: "pnpm"
@@ -43,7 +50,7 @@ jobs:
run: "pnpm install --frozen-lockfile"
- name: Login to GitHub Container Registry
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
+6 -6
View File
@@ -26,7 +26,7 @@ jobs:
persist-credentials: false
- name: Install Cosign
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3
uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
if: github.event_name != 'pull_request'
- name: Set up QEMU
@@ -39,7 +39,7 @@ jobs:
- name: Build and load
id: test-build
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
with:
context: .
file: apps/web/Dockerfile
@@ -97,14 +97,14 @@ jobs:
latest=${{ contains(github.ref_name, '-rc.') && 'false' || 'auto' }}
- name: Login to Docker Hub
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
if: github.event_name != 'pull_request'
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
if: github.event_name != 'pull_request'
with:
registry: ghcr.io
@@ -140,7 +140,7 @@ jobs:
services/web-repositories/secret/data/oci.element.io password | OCI_PASSWORD ;
- name: Login to oci.element.io Registry
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
if: github.event_name != 'pull_request'
with:
registry: oci-push.vpn.infra.element.io
@@ -149,7 +149,7 @@ jobs:
- name: Build and push
id: build-and-push
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
if: github.event_name != 'pull_request'
with:
context: .
+2 -2
View File
@@ -23,7 +23,7 @@ jobs:
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
with:
package_json_file: package.json
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
cache: "pnpm"
cache-dependency-path: pnpm-lock.yaml
@@ -36,7 +36,7 @@ jobs:
run: pnpm run docs:build
- name: Upload artifact
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5
with:
path: ./docs/.vitepress/dist
+2 -2
View File
@@ -10,7 +10,7 @@ jobs:
name: Tidy closed issues
runs-on: ubuntu-24.04
steps:
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
id: main
with:
# PAT needed as the GITHUB_TOKEN won't be able to see cross-references from other orgs (matrix-org)
@@ -142,7 +142,7 @@ jobs:
});
}
}
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
name: Close duplicate as Not Planned
if: steps.main.outputs.closeAsNotPlanned
with:
+29
View File
@@ -0,0 +1,29 @@
# Tweaks the behaviour of Merge Queue to skip certain checks
name: Merge Queue tweaks
on:
merge_group:
types: [checks_requested]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
permissions: {}
jobs:
run:
runs-on: ubuntu-24.04
permissions:
statuses: write
steps:
# This is only needed as license/cla at time of writing seems to be extraordinarily flaky
# and Github doesn't support conditional checks between PR & merge queue.
# This is fine to do as a PR won't make it to merge queue until it has license/cla passing.
- name: Skip license/cla on merge queues
uses: guibranco/github-status-action-v2@9bfa8773cdbdc6c185747fd43cd7faa9d7c32f09
with:
authToken: ${{ secrets.GITHUB_TOKEN }}
state: success
context: license/cla
sha: ${{ github.sha }}
target_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
@@ -1,6 +1,16 @@
name: Publish shared component npm package
name: Publish npm package
run-name: Publish ${{ inputs.package }}
on:
workflow_dispatch: {}
workflow_dispatch:
inputs:
package:
description: Which package to release
required: true
type: choice
options:
- playwright-common
- shared-components
- module-api
concurrency: release
jobs:
@@ -19,7 +29,7 @@ jobs:
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- name: 🔧 Set up node environment
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
cache: "pnpm"
node-version-file: ".node-version"
@@ -29,10 +39,9 @@ jobs:
- name: Update npm
run: npm install -g npm@latest
# Need to setup element web too as it needs the translations
- name: 🛠️ Setup EW
- name: 🛠️ Install dependencies
run: pnpm install --frozen-lockfile
- name: 🚀 Publish to npm
working-directory: packages/shared-components
working-directory: packages/${{ inputs.package }}
run: npm publish --access public --provenance
@@ -8,7 +8,7 @@ jobs:
name: Check PR base branch
runs-on: ubuntu-24.04
steps:
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
const baseBranch = context.payload.pull_request.base.ref;
+2 -1
View File
@@ -30,7 +30,8 @@ jobs:
asset-path: dist/*.tar.gz
expected-asset-count: 3
# Desktop has no dist script so we only target web here
dir: apps/web
dist-dir: apps/web
version-dirs: apps/web apps/desktop
check:
name: Post release checks
@@ -18,7 +18,7 @@ jobs:
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- name: 🔧 Pnpm cache
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
cache: "pnpm"
node-version-file: package.json
@@ -31,7 +31,7 @@ jobs:
working-directory: packages/shared-components
run: pnpm build:storybook
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: shared-components-storybook
path: packages/shared-components/storybook-static
@@ -26,7 +26,7 @@ jobs:
path: storybook-static
- name: 🚀 Deploy to Cloudflare Pages
uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # v3
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3
with:
apiToken: ${{ secrets.CF_PAGES_TOKEN }}
accountId: ${{ secrets.CF_PAGES_ACCOUNT_ID }}
@@ -2,7 +2,9 @@
# It uploads the received images and diffs to netlify, printing the URLs to the console
name: Upload Shared Component Visual Test Diffs
on:
workflow_run:
# Privilege escalation necessary to deploy to Netlify
# 🚨 We must not execute any checked out code here.
workflow_run: # zizmor: ignore[dangerous-triggers]
workflows: ["Shared Component Visual Tests"]
types:
- completed
@@ -23,9 +25,6 @@ jobs:
actions: read
deployments: write
steps:
- name: Install tree
run: "sudo apt-get install -y tree"
- name: Download Diffs
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
@@ -27,7 +27,7 @@ jobs:
repository: element-hq/element-web
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
cache: "pnpm"
node-version: "lts/*"
@@ -36,36 +36,25 @@ jobs:
working-directory: packages/shared-components
run: pnpm install --frozen-lockfile
- name: Get installed Playwright version
working-directory: packages/shared-components
id: playwright
run: echo "version=$(pnpm list @playwright/test --depth=0 --json | jq -r '.[].devDependencies["@playwright/test"].version')" >> $GITHUB_OUTPUT
- name: Cache playwright binaries
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
id: playwright-cache
- name: Setup playwright
uses: ./.github/actions/setup-playwright
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ steps.playwright.outputs.version }}-onlyshell
- name: Install Playwright browsers
working-directory: packages/shared-components
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: "pnpm playwright install --with-deps --only-shell"
write-cache: ${{ github.event_name != 'merge_group' }}
- name: Run Visual tests
working-directory: packages/shared-components
run: "pnpm test:storybook --run"
# Workaround for vis silently adding new baselines if they didn't exist
# Can be removed once https://github.com/repobuddy/visual-testing/issues/516 is released
- run: |
git add -N .
git diff --exit-code
- name: Detect stale screenshots
run: |
if diff -rq __baselines__ __results__ | grep "^Only in __baselines__"; then
exit 1
fi
working-directory: packages/shared-components/__vis__/linux
- name: Upload received images & diffs
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: received-images
path: packages/shared-components/__vis__/linux
+3 -1
View File
@@ -1,6 +1,8 @@
name: SonarQube
on:
workflow_run:
# Privilege escalation necessary to call upon SonarCloud
# 🚨 We must not execute any checked out code here.
workflow_run: # zizmor: ignore[dangerous-triggers]
workflows: ["Tests"]
types:
- completed
+7 -7
View File
@@ -5,8 +5,6 @@ on:
branches: [develop, master]
merge_group:
types: [checks_requested]
repository_dispatch:
types: [element-web-notify]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
@@ -56,7 +54,7 @@ jobs:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
if: matrix.install != ''
with:
cache: "pnpm"
@@ -89,7 +87,7 @@ jobs:
persist-credentials: false
- name: Run zizmor
uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2
uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3
i18n:
strategy:
@@ -105,7 +103,7 @@ jobs:
voip|element_call
error|invalid_json
error|misconfigured
welcome_to_element
welcome|title_element
devtools|settings|elementCallUrl
labs|sliding_sync_description
settings|voip|noise_suppression_description
@@ -127,7 +125,9 @@ jobs:
# Dummy job to simplify branch protections
ci:
name: Static Analysis
needs: [lint, i18n]
needs: [lint, i18n, zizmor]
if: always()
runs-on: ubuntu-24.04
steps:
- run: echo "Ok"
- if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1
+30 -34
View File
@@ -5,8 +5,6 @@ on:
types: [checks_requested]
push:
branches: [develop, master]
repository_dispatch:
types: [element-web-notify]
workflow_call:
inputs:
disable_coverage:
@@ -47,7 +45,7 @@ jobs:
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- name: pnpm cache
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: "lts/*"
cache: "pnpm"
@@ -58,7 +56,7 @@ jobs:
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
- name: Jest Cache
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: /tmp/jest_cache
key: ${{ hashFiles('**/pnpm-lock.yaml') }}
@@ -93,7 +91,7 @@ jobs:
- name: Upload Artifact
if: env.ENABLE_COVERAGE == 'true'
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: coverage-${{ matrix.runner }}
path: |
@@ -102,7 +100,7 @@ jobs:
complete:
name: jest-tests
needs: [jest_ew, vitest_sc]
needs: [jest_ew, vitest]
if: always()
runs-on: ubuntu-24.04
permissions:
@@ -122,8 +120,13 @@ jobs:
sha: ${{ github.sha }}
target_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
vitest_sc:
name: Vitest (Shared Components)
vitest:
name: Vitest
strategy:
matrix:
package:
- shared-components
- module-api
runs-on: ubuntu-24.04
steps:
- name: Checkout code
@@ -134,49 +137,42 @@ jobs:
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- name: pnpm cache
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: "lts/*"
cache: "pnpm"
- name: Install Shared Component Deps
working-directory: "packages/shared-components"
- name: Install Deps
run: "pnpm install"
- name: Cache storybook & vitest
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: |
packages/shared-components/node_modules/.cache
packages/shared-components/node_modules/.vite/vitest
packages/${{ matrix.package }}/node_modules/.cache
packages/${{ matrix.package }}/node_modules/.vite/vitest
key: ${{ hashFiles('pnpm-lock.yaml') }}
- name: Get installed Playwright version
working-directory: packages/shared-components
id: playwright
run: echo "version=$(pnpm list @playwright/test --depth=0 --json | jq -r '.[].devDependencies["@playwright/test"].version')" >> $GITHUB_OUTPUT
- name: Cache playwright binaries
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
id: playwright-cache
- name: Setup playwright
uses: ./.github/actions/setup-playwright
if: matrix.package == 'shared-components'
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ steps.playwright.outputs.version }}-onlyshell
- name: Install Playwright browsers
working-directory: packages/shared-components
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: "pnpm playwright install --with-deps --only-shell"
write-cache: ${{ github.event_name != 'merge_group' }}
- name: Run tests
working-directory: "packages/shared-components"
working-directory: "packages/${{ matrix.package }}"
run: pnpm test:unit --coverage=$ENABLE_COVERAGE
# Dump the disk usage on failure, because this job seems to fail with disk fills sometimes
- name: df
run: df
if: ${{ failure() }}
- name: Upload Artifact
if: env.ENABLE_COVERAGE == 'true'
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: coverage-sharedcomponents
name: coverage-${{ matrix.package }}
path: |
packages/shared-components/coverage
!packages/shared-components/coverage/lcov-report
packages/${{ matrix.package }}/coverage
!packages/${{ matrix.package }}/coverage/lcov-report
+2 -2
View File
@@ -27,7 +27,7 @@ jobs:
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor') ||
contains(github.event.issue.labels.*.name, 'A-Element-Call')
steps:
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
github.rest.issues.addLabels({
@@ -44,7 +44,7 @@ jobs:
contains(github.event.issue.labels.*.name, 'good first issue') ||
contains(github.event.issue.labels.*.name, 'Hacktoberfest')
steps:
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
github.rest.issues.addLabels({
+1 -1
View File
@@ -43,7 +43,7 @@ jobs:
contains(github.event.issue.labels.*.name, 'A-Element-Call')) &&
contains(github.event.issue.labels.*.name, 'Z-Labs')
steps:
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
github.rest.issues.removeLabel({
+2 -2
View File
@@ -14,7 +14,7 @@ jobs:
persist-credentials: false
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
cache: "pnpm"
node-version: "lts/*"
@@ -27,7 +27,7 @@ jobs:
run: "pnpm vendor:jitsi"
- name: Create Pull Request
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8
with:
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
branch: actions/jitsi-update
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-24.04
environment: Matrix
steps:
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
env:
HS_URL: ${{ secrets.BETABOT_HS_URL }}
LOBBY_ROOM_ID: ${{ secrets.ROOM_ID }}
+3 -1
View File
@@ -14,7 +14,8 @@ webpack-stats.json
.vscode/
.env
coverage
# Auto-generated file
# Auto-generated files
*.api.md
/apps/web/src/modules.ts
/apps/web/src/modules.js
src/i18n/strings
@@ -49,6 +50,7 @@ CHANGELOG.md
/apps/desktop/dist/
/apps/desktop/build/
/apps/desktop/dockerbuild/
/apps/desktop/deploys/
/apps/desktop/lib/
/apps/desktop/webapp
/apps/desktop/playwright/html-report
+15
View File
@@ -49,6 +49,21 @@ As for your PR description, it should include these things:
Please **_do not use force push_** in your PRs. Doing so means we can't see what
has changed. We use squash merge to get a "clean" git history.
### Adding a new feature or enhancement
To make a great product with a great user experience, all the small efforts need to go in the same direction and be aligned and consistent with each other.
Before making your contribution, please consider the following:
- One product cant do everything well. Element is focusing on private end-to-end encrypted messaging and voice - this can either be for consumers (e.g. friends and family) or for professional teams and organizations. Public forums and other types of chats without E2EE remain supported but are not the primary use case in case UX compromises need to be made.
- There are 3 platforms - Web/Desktop, [Android](https://github.com/element-hq/element-x-android) and [iOS](https://github.com/element-hq/element-x-ios). These platforms need to have feature parity and design consistency. For some features, supporting all platforms is a must have, in some cases exceptions can be made to have it on one platform only.
- To make sure your idea fits both from a design/solution and use case perspective, please open a new issue (or find an existing issue) in [element-meta](https://github.com/element-hq/element-meta/issues) repository describing the use case and how you plan to tackle it. Do not just describe what feature is missing, explain why the users need it with a couple of real life examples from the field.
- In case of an existing issue, please comment that you're planning to contribute. If you create a new issue, please specify that in the issue. In such a case we will try to review the issue ASAP and provide you with initial feedback so you can be confident if and at which conditions your contributions will be accepted.
Once we know that you want to contribute and have confirmed that the new feature is overall aligned with the product direction, the designers of the core team will help you with the designs and any other type of guidance when it comes to the user experience. We will try to unblock you as quickly as we can, but it may not be instant. Having a clear understanding of the use case and the impact of the feature will help us with the prioritization and faster responses.
Only once all of the above is met should you open a PR with your proposed changes.
### Changelogs
There's no need to manually add Changelog entries: we use information in the
+1 -1
View File
@@ -1 +1 @@
24.14.0
24.15.0
+1 -1
View File
@@ -1,7 +1,7 @@
# Docker image to facilitate building Element Desktop's native bits using a glibc version (2.31)
# with broader compatibility, down to Debian bullseye & Ubuntu focal.
FROM rust:bullseye@sha256:16950191527a4cb9e0762d9d48b705a6315158e4035e64f7a93ce8656a1b053c
FROM rust:bullseye@sha256:949b0903defbfc4e374dc85f947b153859e9ee0104e425cd9a74d94474a9a335
ENV DEBIAN_FRONTEND=noninteractive
+2 -1
View File
@@ -1,6 +1,7 @@
{
"compilerOptions": {
"moduleResolution": "node",
"moduleResolution": "node16",
"module": "Node16",
"esModuleInterop": true,
"target": "es2022",
"sourceMap": false,
+21 -20
View File
@@ -28,7 +28,7 @@
"mkdirs": "mkdirp packages deploys",
"fetch": "pnpm run mkdirs && node scripts/fetch-package.ts",
"asar-webapp": "asar p webapp webapp.asar",
"start": "pnpm run build:ts && pnpm run build:res && electron .",
"start": "nx start",
"lint": "pnpm lint:types && pnpm lint:js",
"lint:js": "eslint --max-warnings 0 src hak playwright scripts",
"lint:js-fix": "eslint --fix --max-warnings 0 src hak playwright scripts && prettier --log-level=warn --write .",
@@ -39,22 +39,19 @@
"lint:types:hak": "tsc --noEmit -p hak/tsconfig.json",
"build:native": "pnpm run hak",
"build:native:universal": "pnpm run hak --target x86_64-apple-darwin fetchandbuild && pnpm run hak --target aarch64-apple-darwin fetchandbuild && pnpm run hak --target x86_64-apple-darwin --target aarch64-apple-darwin copyandlink",
"build:32": "pnpm run build:ts && pnpm run build:res && electron-builder --ia32",
"build:64": "pnpm run build:ts && pnpm run build:res && electron-builder --x64",
"build:universal": "pnpm run build:ts && pnpm run build:res && electron-builder --universal",
"build": "pnpm run build:ts && pnpm run build:res && electron-builder",
"build:ts": "tsc",
"build:res": "node scripts/copy-res.ts",
"build:32": "nx build --ia32",
"build:64": "nx build --x64",
"build:universal": "nx build --universal",
"build": "nx build --",
"docker:setup": "docker build --platform linux/amd64 -t element-desktop-dockerbuild -f dockerbuild/Dockerfile .",
"docker:build:native": "scripts/in-docker.sh pnpm run hak",
"docker:build": "scripts/in-docker.sh pnpm run build",
"docker:install": "scripts/in-docker.sh pnpm install",
"clean": "rimraf webapp.asar dist packages deploys lib",
"hak": "node scripts/hak/index.ts",
"test": "playwright test",
"test:open": "pnpm test --ui",
"test:screenshots:build": "docker build playwright -t element-desktop-playwright --platform linux/amd64",
"test:screenshots:run": "docker run --rm --network host -v $(pwd):/work/element-desktop -v element-desktop-playwright:/work/element-desktop/node_modules -v /var/run/docker.sock:/var/run/docker.sock --platform linux/amd64 -it element-desktop-playwright",
"test:playwright": "nx test:playwright --",
"test:playwright:open": "nx test:playwright -- --ui",
"test:playwright:screenshots": "nx test:playwright:screenshots --",
"sane-postinstall": "electron-builder install-app-deps"
},
"dependencies": {
@@ -65,13 +62,14 @@
"electron-window-state": "^5.0.3",
"minimist": "^1.2.6",
"png-to-ico": "^3.0.0",
"uuid": "^13.0.0"
"uuid": "^14.0.0"
},
"devDependencies": {
"@babel/core": "^7.18.10",
"@babel/preset-env": "^7.18.10",
"@babel/preset-typescript": "^7.18.6",
"@electron/asar": "4.1.0",
"@electron/asar": "4.2.0",
"@electron/fuses": "^2.1.1",
"@playwright/test": "catalog:",
"@stylistic/eslint-plugin": "^5.0.0",
"@types/auto-launch": "^5.0.1",
@@ -81,12 +79,12 @@
"@types/pacote": "^11.1.1",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"app-builder-lib": "26.8.2",
"app-builder-lib": "26.9.0",
"chokidar": "^5.0.0",
"detect-libc": "^2.0.0",
"electron": "41.0.3",
"electron-builder": "26.8.2",
"electron-builder-squirrel-windows": "26.8.2",
"electron": "41.2.2",
"electron-builder": "26.9.0",
"electron-builder-squirrel-windows": "26.9.0",
"electron-devtools-installer": "^4.0.0",
"eslint": "^8.26.0",
"eslint-config-google": "^0.14.0",
@@ -102,10 +100,13 @@
"prettier": "^3.0.0",
"rimraf": "^6.0.0",
"tar": "^7.5.8",
"typescript": "5.9.3"
"typescript": "6.0.3"
},
"hakDependencies": {
"matrix-seshat": "^4.0.1"
"matrix-seshat": "4.2.0"
},
"packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be"
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319",
"nx": {
"includedScripts": []
}
}
+2 -18
View File
@@ -8,25 +8,9 @@ Please see LICENSE files in the repository root for full details.
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({
// Allows the GitHub action to specify a project name (OS + arch) for the combined report to make sense
// workaround for https://github.com/microsoft/playwright/issues/33521
projects: process.env.CI
? projects.map((name) => ({
name,
}))
: undefined,
projects: [{ name: "Desktop" }],
tag: process.env.PW_TAG ? `@${process.env.PW_TAG}` : undefined,
use: {
viewport: { width: 1280, height: 720 },
video: "retain-on-failure",
+12 -6
View File
@@ -1,13 +1,19 @@
FROM mcr.microsoft.com/playwright:v1.58.2-jammy@sha256:4698a73749c5848d3f5fcd42a2174d172fcad2b2283e087843b115424303a565
FROM mcr.microsoft.com/playwright:v1.59.1-jammy@sha256:8a0360d39d1973be506dd59002904a774f6d697d4946c94063b3fd006461c8ff
WORKDIR /work/element-desktop
WORKDIR /work
RUN apt-get update && apt-get -y install xvfb dbus-x11 && apt-get purge -y --auto-remove && rm -rf /var/lib/apt/lists/*
RUN apt-get update && \
apt-get -y install xvfb dbus-x11 && \
apt-get purge -y --auto-remove && \
rm -rf /var/lib/apt/lists/* && \
corepack enable
# Create node_modules & dist dirs so that the volumes have the correct permissions
RUN mkdir node_modules dist && chown 1000:1000 node_modules dist
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
ENV GITHUB_ACTIONS=1
ENV DEBUG=pw:browser
# switch to node user
USER 1000:1000
COPY docker-entrypoint.sh /opt/docker-entrypoint.sh
COPY apps/desktop/playwright/docker-entrypoint.sh /opt/docker-entrypoint.sh
ENTRYPOINT ["bash", "/opt/docker-entrypoint.sh"]
+1 -7
View File
@@ -8,11 +8,5 @@ sleep 2
export DISPLAY=:99
pnpm install --frozen-lockfile
pnpm build -l --dir
PLAYWRIGHT_HTML_OPEN=never ELEMENT_DESKTOP_EXECUTABLE="./dist/linux-unpacked/element-desktop" \
npx playwright test --update-snapshots --reporter line,html "$1"
# Clean up
rm -R core qemu_* || exit 0
exec pnpm -C apps/desktop exec playwright test --update-snapshots --reporter line,html "$1"
@@ -17,14 +17,14 @@ import { PassThrough } from "node:stream";
* A PassThrough stream that captures all data written to it.
*/
class CapturedPassThrough extends PassThrough {
private _chunks = [];
private _chunks: any[] = [];
public constructor() {
super();
super.on("data", this.onData);
}
private onData = (chunk): void => {
private onData = (chunk: any): void => {
this._chunks.push(chunk);
};
@@ -69,7 +69,13 @@ export const test = base.extend<Fixtures>({
const args = ["--profile-dir", tmpDir, ...extraArgs];
if (process.env.GITHUB_ACTIONS) {
args.push("--disable-gpu");
if (process.platform === "linux") {
if (process.getuid() === 0) {
args.push("--no-sandbox");
}
// GitHub Actions hosted runner lacks dbus and a compatible keyring, so we need to force plaintext storage
args.push("--storage-mode", "force-plaintext");
} else if (process.platform === "darwin") {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 957 KiB

+4 -3
View File
@@ -1,11 +1,12 @@
{
"compilerOptions": {
"resolveJsonModule": true,
"moduleResolution": "node",
"moduleResolution": "bundler",
"esModuleInterop": true,
"target": "es2022",
"module": "es2022",
"lib": ["es2022", "dom"],
"module": "ESNext",
"lib": ["es2024", "dom", "dom.iterable"],
"strictNullChecks": false,
"types": ["node"]
},
"include": ["**/*.ts"]
+61 -1
View File
@@ -1,6 +1,7 @@
{
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "app",
"projectType": "application",
"implicitDependencies": ["element-web"],
"root": "apps/desktop",
"targets": {
"docker:build": {
@@ -18,6 +19,65 @@
"tags": ["type=ref,event=branch"]
}
}
},
"build:ts": {
"cache": true,
"command": "tsc",
"inputs": ["src", "{projectRoot}/tsconfig.json"],
"outputs": ["{projectRoot}/lib/*.js", "{projectRoot}/lib/*.d.ts"],
"options": { "cwd": "apps/desktop" }
},
"build:res": {
"cache": true,
"command": "node scripts/copy-res.ts",
"inputs": ["{projectRoot}/i18n"],
"outputs": ["{projectRoot}/lib/i18n"],
"options": { "cwd": "apps/desktop" }
},
"build": {
"cache": true,
"command": "pnpm exec electron-builder",
"inputs": [
"src",
"{projectRoot}/.hak/hakModules",
"{projectRoot}/electron-builder.json",
"{projectRoot}/webapp.asar"
],
"outputs": ["{projectRoot}/dist"],
"options": { "cwd": "apps/desktop" },
"dependsOn": ["build:*"]
},
"start": {
"command": "electron .",
"options": { "cwd": "apps/desktop" },
"dependsOn": ["build:*"]
},
"test:playwright": {
"command": "playwright test",
"options": { "cwd": "apps/desktop" }
},
"test:playwright:screenshots:build-app": {
"executor": "nx:run-commands",
"options": {
"commands": [
"pnpm run build -l --x64 --dir --publish=never",
"pnpm exec electron-fuses write --app ./dist/linux-unpacked/element-desktop EnableNodeCliInspectArguments=on"
],
"parallel": false,
"cwd": "apps/desktop"
},
"dependsOn": ["build:*"]
},
"test:playwright:screenshots:build-docker": {
"cache": true,
"command": "docker build -f playwright/Dockerfile -t element-desktop-playwright --platform linux/amd64 ../..",
"inputs": ["{projectRoot}/playwright/Dockerfile", "{projectRoot}/playwright/docker-entrypoint.sh"],
"options": { "cwd": "apps/desktop" }
},
"test:playwright:screenshots": {
"command": "docker run --rm --network host -v $(pwd)/../../:/work/ --platform linux/amd64 -it element-desktop-playwright",
"options": { "cwd": "apps/desktop" },
"dependsOn": ["test:playwright:screenshots:*"]
}
}
}
-48
View File
@@ -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
+29 -1
View File
@@ -22,7 +22,9 @@
"about": "关于",
"brand_help": "%(brand)s帮助",
"help": "帮助",
"preferences": "偏好"
"no": "否",
"preferences": "偏好",
"yes": "是"
},
"confirm_quit": "你确定要退出吗?",
"edit_menu": {
@@ -30,9 +32,20 @@
"speech_start_speaking": "开始讲话",
"speech_stop_speaking": "停止讲话"
},
"eol": {
"no_more_updates": "你正在使用的 macOS 版本不受支持。请升级以获取 %(brand)s 更新。",
"title": "不受支持的系统",
"warning": "你正在使用的 macOS 版本不受支持。请升级系统以确保 %(brand)s 能保持运行。"
},
"file_menu": {
"label": "文件"
},
"icon_overlay": {
"description_error": "错误",
"description_notifications": {
"other": "你有 %(count)s 条未读通知。"
}
},
"menu": {
"hide": "隐藏",
"hide_others": "隐藏其他",
@@ -49,6 +62,21 @@
"save_image_as_error_description": "图片保存失败",
"save_image_as_error_title": "图片保存失败"
},
"store": {
"error": {
"backend_changed": "清除数据并重新加载?",
"backend_changed_detail": "无法从系统密钥环访问密钥,该密钥似乎已被更改。",
"backend_changed_title": "数据库加载失败",
"backend_no_encryption": "你的系统支持密钥环,但加密功能不可用。",
"backend_no_encryption_detail": "Electron 检测到你的密钥环 %(backend)s 的加密不可用。请确保已安装该密钥环。若已安装请重启设备后重试。也可选择允许 %(brand)s 使用弱加密方式。",
"backend_no_encryption_title": "不支持加密",
"unsupported_keyring": "你的系统存在不受支持的密钥环,这意味着无法打开数据库。",
"unsupported_keyring_detail": "Electron 的密钥环检测未找到受支持的后端。你可以尝试通过命令行参数启动 %(brand)s 来手动配置后端,此操作仅需执行一次。详情请参阅:%(link)s。",
"unsupported_keyring_title": "不受支持的系统",
"unsupported_keyring_use_basic_text": "使用弱加密",
"unsupported_keyring_use_plaintext": "不使用加密"
}
},
"view_menu": {
"actual_size": "实际大小",
"toggle_developer_tools": "切换开发者工具",
+1
View File
@@ -56,6 +56,7 @@ module.exports = {
{ from: "res/css/views/rooms/_EditMessageComposer.pcss", type: "css" },
{ from: "res/css/views/right_panel/_BaseCard.pcss", type: "css" },
{ from: "res/css/views/messages/_MessageActionBar.pcss", type: "css" },
{ from: "res/css/views/messages/_ThreadActionBar.pcss", type: "css" },
{ from: "res/css/views/voip/LegacyCallView/_LegacyCallViewButtons.pcss", type: "css" },
{ from: "res/css/views/elements/_ToggleSwitch.pcss", type: "css" },
{ from: "res/css/views/settings/tabs/_SettingsTab.pcss", type: "css" },
+3 -3
View File
@@ -1,8 +1,8 @@
# syntax=docker.io/docker/dockerfile:1.22-labs@sha256:4c116b618ed48404d579b5467127b20986f2a6b29e4b9be2fee841f632db6a86
# syntax=docker.io/docker/dockerfile:1.23-labs@sha256:7eca9451d94f9b8ad22e44988b92d595d3e4d65163794237949a8c3413fbed5d
# Context must be the root of the monorepo
# Builder
FROM --platform=$BUILDPLATFORM node:24-bullseye@sha256:4bfbd78e049926e4ca595c1798810691ca7bb5aedd829ffd8a78b2ab30689810 AS builder
FROM --platform=$BUILDPLATFORM node:24-bullseye@sha256:d2059a9c157c9f70739736979fa3635008bf3ca74560b30930dc181228bc427f AS builder
# Support custom branch of the js-sdk. This also helps us build images of element-web develop.
ARG USE_CUSTOM_SDKS=false
@@ -25,7 +25,7 @@ RUN --mount=type=bind,source=.git,target=/src/.git /src/scripts/docker-package.s
RUN cp /src/apps/web/config.sample.json /src/apps/web/webapp/config.json
# App
FROM nginxinc/nginx-unprivileged:alpine-slim@sha256:4011c42f28e9b54c86b52211598dbc6bcaa520311ddd55f211587cdd71f88a9c
FROM nginxinc/nginx-unprivileged:alpine-slim@sha256:360465db60105a4cbf5215cd9e5a2ba40ef956978dd94f99707e9674050e38ea
# Need root user to install packages & manipulate the usr directory
USER root
+3
View File
@@ -10,6 +10,7 @@
**/.pnpm-store
**/tsconfig.node.tsbuildinfo
**/*.md
!**/*.api.md
**/*.rst
.idea/
@@ -22,6 +23,8 @@ apps/web/webpack-stats.json
apps/web/playwright/
apps/web/webapp/
apps/web/debian/
apps/desktop
!apps/desktop/package.json
packages/shared-components/__vis__/
packages/shared-components/storybook-static/
+1 -1
View File
@@ -46,7 +46,7 @@ const config: Config = {
"@vector-im/compound-web": "<rootDir>/../../node_modules/@vector-im/compound-web",
},
transformIgnorePatterns: [
"/node_modules/(?!(mime|matrix-js-sdk|uuid|p-retry|is-network-error|react-merge-refs|is-ip|ip-regex|super-regex|function-timeout|time-span|convert-hrtime|clone-regexp|is-regexp|matrix-web-i18n|await-lock|@element-hq/web-shared-components|react-virtuoso|lodash)).+$",
"/node_modules/(?!(mime|matrix-js-sdk|uuid|p-retry|is-network-error|react-merge-refs|is-ip|ip-regex|super-regex|function-timeout|time-span|convert-hrtime|clone-regexp|is-regexp|matrix-web-i18n|await-lock|@element-hq/web-shared-components|react-virtuoso|lodash|domutils|domhandler|domelementtype|dom-serializer|entities)).+$",
],
collectCoverageFrom: [
"<rootDir>/src/**/*.{js,ts,tsx}",
+19 -21
View File
@@ -30,15 +30,15 @@
"lint:types": "nx lint:types",
"lint:style": "stylelint \"res/css/**/*.pcss\"",
"test": "nx test:unit",
"test:playwright": "playwright test",
"test:playwright:open": "pnpm test:playwright --ui",
"test:playwright:screenshots": "playwright-screenshots-experimental pnpm playwright test --update-snapshots --project=Chrome --grep @screenshot",
"test:playwright": "nx test:playwright --",
"test:playwright:open": "nx test:playwright -- --ui",
"test:playwright:screenshots": "nx test:playwright:screenshots --",
"coverage": "pnpm test --coverage",
"analyse:webpack-bundles": "webpack-bundle-analyzer webpack-stats.json webapp"
},
"dependencies": {
"@babel/runtime": "^7.12.5",
"@element-hq/element-web-module-api": "catalog:",
"@element-hq/element-web-module-api": "workspace:*",
"@element-hq/web-shared-components": "workspace:*",
"@fontsource/fira-code": "^5",
"@fontsource/inter": "catalog:",
@@ -63,25 +63,25 @@
"css-tree": "^3.0.0",
"diff-dom": "^5.0.0",
"diff-match-patch": "^1.0.5",
"domutils": "^3.2.2",
"domutils": "^4.0.0",
"emojibase-regex": "^17.0.0",
"escape-html": "^1.0.3",
"file-saver": "^2.0.5",
"filesize": "11.0.13",
"filesize": "11.0.15",
"github-markdown-css": "^5.5.1",
"glob-to-regexp": "^0.4.1",
"highlight.js": "^11.3.1",
"html-entities": "^2.0.0",
"html-react-parser": "^5.2.2",
"html-react-parser": "^6.0.0",
"is-ip": "^5.0.0",
"js-xxhash": "^5.0.0",
"jsrsasign": "^11.0.0",
"jszip": "^3.7.0",
"katex": "^0.16.0",
"lodash": "npm:lodash-es@^4.17.21",
"lodash": "npm:lodash-es@4.18.1",
"maplibre-gl": "^5.0.0",
"matrix-encrypt-attachment": "^1.0.3",
"matrix-js-sdk": "41.3.0",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
"matrix-widget-api": "^1.16.1",
"memoize-one": "^6.0.0",
"mime": "^4.0.4",
@@ -89,7 +89,7 @@
"opus-recorder": "^8.0.3",
"pako": "^2.0.3",
"png-chunks-extract": "^1.0.0",
"posthog-js": "1.360.2",
"posthog-js": "1.369.3",
"qrcode": "1.5.4",
"re-resizable": "6.11.2",
"react": "catalog:",
@@ -101,10 +101,9 @@
"react-transition-group": "^4.4.1",
"rfc4648": "^1.4.0",
"sanitize-filename": "^1.6.3",
"sanitize-html": "2.17.1",
"sanitize-html": "2.17.3",
"tar-js": "^0.3.0",
"ua-parser-js": "1.0.40",
"uuid": "^13.0.0",
"what-input": "^5.2.10"
},
"devDependencies": {
@@ -125,10 +124,9 @@
"@babel/preset-env": "^7.12.11",
"@babel/preset-react": "^7.12.10",
"@babel/preset-typescript": "^7.12.7",
"@casualbot/jest-sonar-reporter": "2.5.0",
"@element-hq/element-call-embedded": "0.18.0",
"@element-hq/element-web-playwright-common": "catalog:",
"@element-hq/element-web-playwright-common-local": "workspace:*",
"@casualbot/jest-sonar-reporter": "2.6.0",
"@element-hq/element-call-embedded": "0.19.1",
"@element-hq/element-web-playwright-common": "workspace:*",
"@fetch-mock/jest": "^0.2.20",
"@jest/globals": "^30.2.0",
"@peculiar/webcrypto": "^1.4.3",
@@ -203,20 +201,20 @@
"jest-raw-loader": "^1.0.1",
"jsqr": "^1.4.0",
"matrix-web-i18n": "catalog:",
"mini-css-extract-plugin": "2.10.1",
"mini-css-extract-plugin": "2.10.2",
"modernizr": "^3.12.0",
"playwright-core": "catalog:",
"postcss": "8.5.8",
"postcss": "8.5.10",
"postcss-easings": "4.0.0",
"postcss-hexrgba": "2.1.0",
"postcss-import": "16.1.1",
"postcss-loader": "8.2.1",
"postcss-mixins": "12.1.2",
"postcss-nested": "7.0.2",
"postcss-preset-env": "11.2.0",
"postcss-preset-env": "11.2.1",
"postcss-scss": "4.0.9",
"postcss-simple-vars": "7.0.1",
"prettier": "3.8.1",
"prettier": "3.8.3",
"process": "^0.11.10",
"raw-loader": "^4.0.2",
"semver": "^7.5.2",
@@ -246,6 +244,6 @@
"engines": {
"node": ">=22.18"
},
"packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be",
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319",
"private": true
}
+1 -1
View File
@@ -91,7 +91,7 @@ export default defineConfig<{}, WorkerOptions>({
trace: "on-first-retry",
},
webServer: {
command: process.env.CI ? "npx serve -p 8080 -L ./webapp" : "pnpm start",
command: process.env.CI ? "npx serve -p 8080 -L ./webapp" : "nx --outputStyle stream start",
url: `${baseURL}/config.json`,
reuseExistingServer: true,
timeout: (process.env.CI ? 30 : 120) * 1000,
@@ -20,7 +20,7 @@ test.use({
test("Shows the welcome page by default", async ({ page }) => {
await page.goto("/");
await expect(page.getByRole("heading", { name: "Welcome to Element!" })).toBeVisible();
await expect(page.getByRole("heading", { name: "Be in your element" })).toBeVisible();
await expect(page.getByRole("link", { name: "Sign in" })).toBeVisible();
});
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
*/
import type { Locator, Page } from "@playwright/test";
import { test, expect } from "../../element-web-test";
import { test, expect, type ExtendedToMatchScreenshotOptions } from "../../element-web-test";
import { SettingLevel } from "../../../src/settings/SettingLevel";
import { Layout } from "../../../src/settings/enums/Layout";
import { type ElementAppPage } from "../../pages/ElementAppPage";
@@ -94,7 +94,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
// Assert that rendering of the player settled and the play button is visible before taking a snapshot
await checkPlayerVisibility(ircTile);
const screenshotOptions = {
const screenshotOptions: ExtendedToMatchScreenshotOptions = {
css: `
/* The timestamp is of inconsistent width depending on the time the test runs at */
.mx_MessageTimestamp {
@@ -120,7 +120,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
};
// Take a snapshot of mx_EventTile_last on IRC layout
screenshotOptions.clip = await page.locator(".mx_EventTile_last").boundingBox();
screenshotOptions.clip = (await page.locator(".mx_EventTile_last").boundingBox()) ?? undefined;
await scrollToBottomOfTimeline(page);
await expect(page).toMatchScreenshot(`${detail.replaceAll(" ", "-")}-irc-layout.png`, screenshotOptions);
@@ -129,7 +129,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
const groupTile = page.locator(".mx_EventTile_last[data-layout='group']");
await groupTile.locator(".mx_MessageTimestamp").click();
await checkPlayerVisibility(groupTile);
screenshotOptions.clip = await page.locator(".mx_EventTile_last").boundingBox();
screenshotOptions.clip = (await page.locator(".mx_EventTile_last").boundingBox()) ?? undefined;
await scrollToBottomOfTimeline(page);
await expect(page).toMatchScreenshot(`${detail.replaceAll(" ", "-")}-group-layout.png`, screenshotOptions);
@@ -138,7 +138,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
const bubbleTile = page.locator(".mx_EventTile_last[data-layout='bubble']");
await bubbleTile.locator(".mx_MessageTimestamp").click();
await checkPlayerVisibility(bubbleTile);
screenshotOptions.clip = await page.locator(".mx_EventTile_last").boundingBox();
screenshotOptions.clip = (await page.locator(".mx_EventTile_last").boundingBox()) ?? undefined;
await scrollToBottomOfTimeline(page);
await expect(page).toMatchScreenshot(`${detail.replaceAll(" ", "-")}-bubble-layout.png`, screenshotOptions);
};
@@ -27,6 +27,9 @@ const startDMWithBob = async (page: Page, bob: Bot) => {
await page.getByRole("option", { name: bob.credentials.displayName }).click();
await expect(page.getByTestId("invite-dialog-input-wrapper").getByText("Bob")).toBeVisible();
await page.getByRole("button", { name: "Go" }).click();
await expect(page.getByRole("heading", { name: "Start a chat with this new contact?" })).toBeVisible();
await page.getByRole("button", { name: "Continue" }).click();
};
const testMessages = async (page: Page, bob: Bot, bobRoomId: string) => {
@@ -44,7 +47,7 @@ const bobJoin = async (page: Page, bob: Bot) => {
const bobRooms = cli.getRooms();
if (!bobRooms.length) {
await new Promise<void>((resolve) => {
const onMembership = (_event) => {
const onMembership = () => {
cli.off(window.matrixcs.RoomMemberEvent.Membership, onMembership);
resolve();
};
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import type { EmittedEvents, Preset } from "matrix-js-sdk/src/matrix";
import type { Preset, RoomMemberEvent, RoomStateEvent } from "matrix-js-sdk/src/matrix";
import { expect, test } from "../../element-web-test";
import {
createRoom,
@@ -122,7 +122,7 @@ test.describe("Cryptography", function () {
const roomId = await bob.evaluate(
async (client, { alice }) => {
const encryptionStatePromise = new Promise<void>((resolve) => {
client.on("RoomState.events" as EmittedEvents, (event, _state, _lastStateEvent) => {
client.on("RoomState.events" as RoomStateEvent.Events, (event, _state, _lastStateEvent) => {
if (event.getType() === "m.room.encryption") {
resolve();
}
@@ -253,11 +253,14 @@ test.describe("Cryptography", function () {
// invite Alice
const inviteAlicePromise = new Promise<void>((resolve) => {
client.on("RoomMember.membership" as EmittedEvents, (_event, member, _oldMembership?) => {
if (member.userId === alice.userId && member.membership === "invite") {
resolve();
}
});
client.on(
"RoomMember.membership" as RoomMemberEvent.Membership,
(_event, member, _oldMembership?) => {
if (member.userId === alice.userId && member.membership === "invite") {
resolve();
}
},
);
});
await client.invite(roomId, alice.userId);
// wait for the invite to come back so that we encrypt to Alice
@@ -271,11 +274,14 @@ test.describe("Cryptography", function () {
// kick Alice
const kickAlicePromise = new Promise<void>((resolve) => {
client.on("RoomMember.membership" as EmittedEvents, (_event, member, _oldMembership?) => {
if (member.userId === alice.userId && member.membership === "leave") {
resolve();
}
});
client.on(
"RoomMember.membership" as RoomMemberEvent.Membership,
(_event, member, _oldMembership?) => {
if (member.userId === alice.userId && member.membership === "leave") {
resolve();
}
},
);
});
await client.kick(roomId, alice.userId);
await kickAlicePromise;
@@ -166,13 +166,9 @@ async function getDehydratedDeviceIds(client: Client): Promise<string[]> {
return await client.evaluate(async (client) => {
const userId = client.getUserId();
const devices = await client.getCrypto().getUserDeviceInfo([userId]);
return Array.from(
devices
.get(userId)
.values()
.filter((d) => d.dehydrated)
.map((d) => d.deviceId),
);
return Array.from(devices.get(userId).values())
.filter((d) => d.dehydrated)
.map((d) => d.deviceId);
});
}
@@ -21,7 +21,6 @@ import {
waitForVerificationRequest,
} from "./utils";
import { type Bot } from "../../pages/bot";
import { Toasts } from "../../pages/toasts.ts";
import type { ElementAppPage } from "../../pages/ElementAppPage.ts";
test.describe("Device verification", { tag: "@no-webkit" }, () => {
@@ -82,7 +81,11 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
);
// Regression test for https://github.com/element-hq/element-web/issues/29110
test("No toast after verification, even if the secrets take a while to arrive", async ({ page, credentials }) => {
test("No toast after verification, even if the secrets take a while to arrive", async ({
page,
credentials,
toasts,
}) => {
// Before we log in, the bot creates an encrypted room, so that we can test the toast behaviour that only happens
// when we are in an encrypted room.
await aliceBotClient.createRoom({
@@ -121,7 +124,6 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
await infoDialog.getByRole("button", { name: "Got it" }).click();
// There should be no toast (other than the notifications one)
const toasts = new Toasts(page);
await toasts.rejectToast("Notifications");
await toasts.assertNoToasts();
@@ -49,7 +49,7 @@ test.describe("History sharing", function () {
await sendMessageInCurrentRoom(alicePage, "A message from Alice");
// Send the invite to Bob
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId, { confirmUnknownUser: true });
// Bob accepts the invite
await bobPage.getByRole("option", { name: "TestRoom" }).click();
@@ -105,7 +105,7 @@ test.describe("History sharing", function () {
// Alice invites Bob, and Bob accepts
const roomId = await aliceElementApp.getCurrentRoomIdFromUrl();
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId, { confirmUnknownUser: true });
await bobPage.getByRole("option", { name: "TestRoom" }).click();
await bobPage.getByRole("button", { name: "Accept" }).click();
@@ -143,7 +143,7 @@ test.describe("History sharing", function () {
await sendMessageInCurrentRoom(bobPage, "Message3: 'shared' visibility, but Bob thinks it is still 'joined'");
// Alice now invites Charlie
await aliceElementApp.inviteUserToCurrentRoom(charlieCredentials.userId);
await aliceElementApp.inviteUserToCurrentRoom(charlieCredentials.userId, { confirmUnknownUser: true });
await charliePage.getByRole("option", { name: "TestRoom" }).click();
await charliePage.getByRole("button", { name: "Accept" }).click();
@@ -43,11 +43,7 @@ test.describe("Key storage out of sync toast", () => {
});
test("should prompt for recovery key if 'enter recovery key' pressed", { tag: "@screenshot" }, async ({ page }) => {
// We need to wait for there to be two toasts as the wait below won't work in isolation:
// playwright only evaluates the 'first()' call initially, not subsequent times it checks, so
// it would always be checking the same toast, even if another one is now the first.
await expect(page.getByRole("alert")).toHaveCount(2);
await expect(page.getByRole("alert").first()).toMatchScreenshot(
await expect(page.getByRole("alert").filter({ hasText: "Your key storage is out of sync." })).toMatchScreenshot(
"key-storage-out-of-sync-toast.png",
screenshotOptions,
);
+2 -2
View File
@@ -579,8 +579,8 @@ export async function deleteCachedSecrets(page: Page) {
await page.evaluate(async () => {
const removeCachedSecrets = new Promise((resolve) => {
const request = window.indexedDB.open("matrix-js-sdk::matrix-sdk-crypto");
request.onsuccess = (event: Event & { target: { result: IDBDatabase } }) => {
const db = event.target.result;
request.onsuccess = function (this: IDBRequest) {
const db = this.result as IDBDatabase;
const request = db.transaction("core", "readwrite").objectStore("core").delete("private_identity");
request.onsuccess = () => {
db.close();
@@ -0,0 +1,61 @@
/*
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 { test, expect } from "../../element-web-test";
import { getSampleFilePath } from "../../sample-files";
test.describe("Devtools", () => {
test.use({
displayName: "Alice",
});
test("should allow enabling low bandwidth mode", async ({ page, homeserver, user, app }) => {
// Upload a picture
const userSettings = await app.settings.openUserSettings("Account");
const profileSettings = userSettings.locator(".mx_UserProfileSettings");
await profileSettings.getByAltText("Upload").setInputFiles(getSampleFilePath("riot.png"));
await app.closeDialog();
// Create an initial room.
const createRoomDialog = await app.openCreateRoomDialog();
await createRoomDialog.getByRole("textbox", { name: "Name" }).fill("Test Room");
await createRoomDialog.getByRole("button", { name: "Create room" }).click();
const composer = app.getComposer().locator("[contenteditable]");
await composer.fill("/devtools");
await composer.press("Enter");
const dialog = page.locator(".mx_Dialog");
await dialog.getByLabel("Developer mode").check();
await dialog.getByLabel("Disable bandwidth-heavy features").click();
// Wait for refresh.
await page.waitForEvent("domcontentloaded");
await app.viewRoomByName("Test Room");
// This only appears when encryption has been disabled in the client.
await expect(page.getByText("The encryption used by this room isn't supported.")).toBeVisible();
// None of these should be requested.
let hasSentTyping = false;
let hasRequestedThumbnail = false;
await page.route("**/_matrix/client/v3/rooms/*/typing/*", async (route) => {
hasSentTyping = true;
await route.fulfill({ json: {} });
});
await page.route("**/_matrix/media/v3/thumbnail/**", async (route) => {
hasRequestedThumbnail = true;
await route.fulfill({ json: {} });
});
await page.route("**/_matrix/client/v1/media/thumbnail/**", async (route) => {
hasRequestedThumbnail = true;
await route.fulfill({ json: {} });
});
await composer.pressSequentially("Provoke typing request", { delay: 5 });
expect(hasSentTyping).toEqual(false);
expect(hasRequestedThumbnail).toEqual(false);
});
});
@@ -9,6 +9,15 @@ Please see LICENSE files in the repository root for full details.
import { test, expect } from "../../element-web-test";
/**
* CSS which will hide the mxid in the user list of the "unknown users" confirmation dialog. This is useful because the
* MXID is not stable and the screenshot tests will otherwise fail.
*
* Ideally RichItem would give us a way to do this that doesn't involve gnarly CSS.
*/
const UNKNOWN_IDENTITY_USERS_DIALOG_HIDE_MXID_CSS =
'[data-testid="userlist"] li > span:nth-last-child(1) { display: none }';
test.describe("Invite dialog", function () {
test.use({
displayName: "Hanako",
@@ -62,6 +71,15 @@ test.describe("Invite dialog", function () {
// Invite the bot
await other.getByRole("button", { name: "Invite" }).click();
// Expect a confirmation dialog, screenshot, and dismiss
await expect(
page.locator(".mx_Dialog").getByRole("heading", { name: "Invite new contacts to this room?" }),
).toBeVisible();
await expect(page.locator(".mx_Dialog")).toMatchScreenshot("confirm-invite-new-contact.png", {
css: UNKNOWN_IDENTITY_USERS_DIALOG_HIDE_MXID_CSS,
});
await page.locator(".mx_Dialog").getByRole("button", { name: "Invite" }).click();
// Assert that the invite dialog disappears
await expect(page.locator(".mx_InviteDialog_other")).not.toBeVisible();
@@ -104,6 +122,15 @@ test.describe("Invite dialog", function () {
// Open a direct message UI
await other.getByRole("button", { name: "Go" }).click();
// Expect a confirmation dialog, screenshot, and dismiss
await expect(
page.locator(".mx_Dialog").getByRole("heading", { name: "Start a chat with this new contact?" }),
).toBeVisible();
await expect(page.locator(".mx_Dialog")).toMatchScreenshot("confirm-chat-with-new-contact.png", {
css: UNKNOWN_IDENTITY_USERS_DIALOG_HIDE_MXID_CSS,
});
await page.locator(".mx_Dialog").getByRole("button", { name: "Continue" }).click();
// Assert that the invite dialog disappears
await expect(page.locator(".mx_InviteDialog_other")).not.toBeVisible();
@@ -0,0 +1,267 @@
/*
* 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 { type Page } from "@playwright/test";
import { expect, test } from "../../../element-web-test";
import { getRoomList, getRoomListHeader, getSectionHeader } from "./utils";
test.describe("Room list custom sections", () => {
test.use({
displayName: "Alice",
labsFlags: ["feature_new_room_list", "feature_room_list_sections"],
botCreateOpts: {
displayName: "BotBob",
autoAcceptInvites: true,
},
});
/**
* Create a custom section via the header compose menu and dialog.
* @param page
* @param sectionName The name of the section to create
*/
async function createCustomSection(page: Page, sectionName: string): Promise<void> {
const composeMenu = getRoomListHeader(page).getByRole("button", { name: "New conversation" });
await composeMenu.click();
await page.getByRole("menuitem", { name: "New section" }).click();
// Fill in the section name in the dialog
const dialog = page.getByRole("dialog", { name: "Create a section" });
await expect(dialog).toBeVisible();
await dialog.getByRole("textbox", { name: "Section name" }).fill(sectionName);
await dialog.getByRole("button", { name: "Create section" }).click();
// Wait for the dialog to close
await expect(dialog).not.toBeVisible();
}
test.beforeEach(async ({ page, app, user }) => {
// The notification toast is displayed above the search section
await app.closeNotificationToast();
// Focus the user menu to avoid hover decoration
await page.getByRole("button", { name: "User menu" }).focus();
});
test.describe("Section creation", () => {
test("should create a custom section via the header compose menu", async ({ page, app }) => {
await app.client.createRoom({ name: "my room" });
await createCustomSection(page, "Work");
// The custom section header should be visible (even though it is empty)
await expect(getSectionHeader(page, "Work")).toBeVisible();
// The Chats section should also be visible
await expect(getSectionHeader(page, "Chats")).toBeVisible();
});
test("should show 'Section created' toast after creating a section", async ({ page, app }) => {
await app.client.createRoom({ name: "my room" });
await createCustomSection(page, "Personal");
// The "Section created" toast should appear
await expect(page.getByText("Section created")).toBeVisible();
});
test("should create a custom section via the room option menu", async ({ page, app }) => {
await app.client.createRoom({ name: "my room" });
const roomList = getRoomList(page);
const roomItem = roomList.getByRole("option", { name: "Open room my room" });
await expect(roomItem).toBeVisible();
// Open the More Options menu
await roomItem.hover();
await roomItem.getByRole("button", { name: "More Options" }).click();
// Open the "Move to" submenu
await page.getByRole("menuitem", { name: "Move to" }).hover();
// Click on "New section"
await page.getByRole("menuitem", { name: "New section" }).click();
// Fill in the section name in the dialog
const dialog = page.getByRole("dialog", { name: "Create a section" });
await expect(dialog).toBeVisible();
await dialog.getByRole("textbox", { name: "Section name" }).fill("Projects");
await dialog.getByRole("button", { name: "Create section" }).click();
// Wait for the dialog to close
await expect(dialog).not.toBeVisible();
// The custom section should be created
await expect(getSectionHeader(page, "Projects")).toBeVisible();
});
test("should cancel section creation when dialog is dismissed", async ({ page, app }) => {
await app.client.createRoom({ name: "my room" });
const composeMenu = getRoomListHeader(page).getByRole("button", { name: "New conversation" });
await composeMenu.click();
await page.getByRole("menuitem", { name: "New section" }).click();
// The dialog should appear
const dialog = page.getByRole("dialog", { name: "Create a section" });
await expect(dialog).toBeVisible();
// Cancel the dialog
await dialog.getByRole("button", { name: "Cancel" }).click();
// The dialog should close
await expect(dialog).not.toBeVisible();
// No custom section should be created - should remain a flat list
await expect(getSectionHeader(page, "Chats")).not.toBeVisible();
});
test("should create multiple custom sections", async ({ page, app }) => {
await app.client.createRoom({ name: "my room" });
await createCustomSection(page, "Work");
await createCustomSection(page, "Personal");
// Both custom sections should be visible
await expect(getSectionHeader(page, "Work")).toBeVisible();
await expect(getSectionHeader(page, "Personal")).toBeVisible();
await expect(getSectionHeader(page, "Chats")).toBeVisible();
});
});
test.describe("Custom section display", () => {
test("should show empty custom sections", async ({ page, app }) => {
// Create a room so the Chats section has something
await app.client.createRoom({ name: "my room" });
await createCustomSection(page, "Empty Section");
// The custom section should be visible even with no rooms
await expect(getSectionHeader(page, "Empty Section")).toBeVisible();
// The room should still be in the Chats section
const roomList = getRoomList(page);
await expect(roomList.getByRole("row", { name: "Open room my room" })).toBeVisible();
});
test("should display custom sections between Favourites and Chats", async ({ page, app }) => {
// Create a favourite room
const favouriteId = await app.client.createRoom({ name: "favourite room" });
await app.client.evaluate(async (client, roomId) => {
await client.setRoomTag(roomId, "m.favourite");
}, favouriteId);
// Create a low priority room
const lowPrioId = await app.client.createRoom({ name: "low prio room" });
await app.client.evaluate(async (client, roomId) => {
await client.setRoomTag(roomId, "m.lowpriority");
}, lowPrioId);
// Create a regular room
await app.client.createRoom({ name: "regular room" });
// Create a custom section
await createCustomSection(page, "Work");
// All section headers should be visible
await expect(getSectionHeader(page, "Favourites")).toBeVisible();
await expect(getSectionHeader(page, "Work")).toBeVisible();
// Should be expanded by default
await expect(getSectionHeader(page, "Work")).toHaveAttribute("aria-expanded", "true");
await expect(getSectionHeader(page, "Chats")).toBeVisible();
await expect(getSectionHeader(page, "Low Priority")).toBeVisible();
});
});
test.describe("Adding a room to a custom section", () => {
/**
* Asserts a room is nested under a specific section using the treegrid aria-level hierarchy.
* Section header rows sit at aria-level=1; room rows nested within a section sit at aria-level=2.
* Verifies that the closest preceding aria-level=1 row is the expected section header.
*/
async function assertRoomInSection(page: Page, sectionName: string, roomName: string): Promise<void> {
const roomList = getRoomList(page);
const roomRow = roomList.getByRole("row", { name: `Open room ${roomName}` });
// Room row must be at aria-level=2 (i.e. inside a section)
await expect(roomRow).toHaveAttribute("aria-level", "2");
// The closest preceding aria-level=1 row must be the expected section header.
// XPath preceding:: axis returns nodes before the context in document order; [1] picks the nearest one.
const closestSectionHeader = roomRow.locator(`xpath=preceding::*[@role="row" and @aria-level="1"][1]`);
await expect(closestSectionHeader).toContainText(sectionName);
}
test("should add a room to a custom section via the More Options menu", async ({ page, app }) => {
await app.client.createRoom({ name: "my room" });
await createCustomSection(page, "Work");
const roomList = getRoomList(page);
// Room starts in Chats section (aria-level=2)
const roomItem = roomList.getByRole("row", { name: "Open room my room" });
await expect(roomItem).toBeVisible();
// Open More Options and move to the Work section
await roomItem.hover();
await roomItem.getByRole("button", { name: "More Options" }).click();
await page.getByRole("menuitem", { name: "Move to" }).hover();
await page.getByRole("menuitem", { name: "Work" }).click();
// Room should now be nested under the Work section header (aria-level=1 → aria-level=2)
await assertRoomInSection(page, "Work", "my room");
});
test(
"should show 'Chat moved' toast when adding a room to a custom section",
{ tag: "@screenshot" },
async ({ page, app }) => {
await app.client.createRoom({ name: "my room" });
await createCustomSection(page, "Work");
const roomList = getRoomList(page);
const roomItem = roomList.getByRole("row", { name: "Open room my room" });
await roomItem.hover();
await roomItem.getByRole("button", { name: "More Options" }).click();
await page.getByRole("menuitem", { name: "Move to" }).hover();
await page.getByRole("menuitem", { name: "Work" }).click();
// The "Chat moved" toast should appear
await expect(page.getByText("Chat moved")).toBeVisible();
// Remove focus outline from the room item before taking the screenshot
await page.getByRole("button", { name: "User menu" }).focus();
await expect(roomList).toMatchScreenshot("room-list-sections-chat-moved-toast.png");
},
);
test("should remove a room from a custom section when toggling the same section", async ({ page, app }) => {
await app.client.createRoom({ name: "my room" });
await createCustomSection(page, "Work");
const roomList = getRoomList(page);
// Move to Work section and verify placement via aria-level
let roomItem = roomList.getByRole("row", { name: "Open room my room" });
await roomItem.hover();
await roomItem.getByRole("button", { name: "More Options" }).click();
await page.getByRole("menuitem", { name: "Move to" }).hover();
await page.getByRole("menuitem", { name: "Work" }).click();
await assertRoomInSection(page, "Work", "my room");
// Toggle off by selecting the same section again
roomItem = roomList.getByRole("row", { name: "Open room my room" });
await roomItem.hover();
await roomItem.getByRole("button", { name: "More Options" }).click();
await page.getByRole("menuitem", { name: "Move to" }).hover();
await page.getByRole("menuitem", { name: "Work" }).click();
// Room is back in the Chats section
await assertRoomInSection(page, "Chats", "my room");
});
});
});
@@ -6,10 +6,11 @@
*/
import { type Visibility } from "matrix-js-sdk/src/matrix";
import { type Locator, type Page } from "@playwright/test";
import { type Page } from "@playwright/test";
import { expect, test } from "../../../element-web-test";
import { SettingLevel } from "../../../../src/settings/SettingLevel";
import { getFilterCollapseButton, getFilterExpandButton, getPrimaryFilters, getRoomOptionsMenu } from "./utils";
test.describe("Room list filters and sort", () => {
test.use({
@@ -21,22 +22,6 @@ test.describe("Room list filters and sort", () => {
labsFlags: ["feature_new_room_list"],
});
function getPrimaryFilters(page: Page): Locator {
return page.getByTestId("primary-filters");
}
function getRoomOptionsMenu(page: Page): Locator {
return page.getByRole("button", { name: "Room Options" });
}
function getFilterExpandButton(page: Page): Locator {
return getPrimaryFilters(page).getByRole("button", { name: "Expand filter list" });
}
function getFilterCollapseButton(page: Page): Locator {
return getPrimaryFilters(page).getByRole("button", { name: "Collapse filter list" });
}
/**
* Get the room list
* @param page
@@ -6,21 +6,13 @@
*/
import { test, expect } from "../../../element-web-test";
import type { Page } from "@playwright/test";
import { getHeaderSection } from "./utils";
test.describe("Header section of the room list", () => {
test.use({
labsFlags: ["feature_new_room_list"],
});
/**
* Get the header section of the room list
* @param page
*/
function getHeaderSection(page: Page) {
return page.getByTestId("room-list-header");
}
test.beforeEach(async ({ page, app, user }) => {
// The notification toast is displayed above the search section
await app.closeNotificationToast();
@@ -5,23 +5,14 @@
* Please see LICENSE files in the repository root for full details.
*/
import { type Page } from "@playwright/test";
import { test, expect } from "../../../element-web-test";
import { getRoomListView } from "./utils";
test.describe("Room list panel", () => {
test.use({
labsFlags: ["feature_new_room_list"],
});
/**
* Get the room list view
* @param page
*/
function getRoomListView(page: Page) {
return page.getByRole("navigation", { name: "Room list" });
}
test.beforeEach(async ({ page, app, user }) => {
// The notification toast is displayed above the search section
await app.closeNotificationToast();
@@ -5,23 +5,14 @@
* Please see LICENSE files in the repository root for full details.
*/
import { type Page } from "@playwright/test";
import { test, expect } from "../../../element-web-test";
import { getSearchSection } from "./utils";
test.describe("Search section of the room list", () => {
test.use({
labsFlags: ["feature_new_room_list"],
});
/**
* Get the search section of the room list
* @param page
*/
function getSearchSection(page: Page) {
return page.getByRole("search");
}
test.beforeEach(async ({ page, app, user }) => {
// The notification toast is displayed above the search section
await app.closeNotificationToast();
@@ -0,0 +1,259 @@
/*
* Copyright 2025 New Vector 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 { expect, test } from "../../../element-web-test";
import { getPrimaryFilters, getRoomList, getSectionHeader } from "./utils";
test.describe("Room list sections", () => {
test.use({
displayName: "Alice",
labsFlags: ["feature_new_room_list", "feature_room_list_sections"],
botCreateOpts: {
displayName: "BotBob",
autoAcceptInvites: true,
},
});
test.beforeEach(async ({ page, app, user }) => {
// The notification toast is displayed above the search section
await app.closeNotificationToast();
// focus the user menu to avoid to have hover decoration
await page.getByRole("button", { name: "User menu" }).focus();
});
test.describe("Section rendering", () => {
test.beforeEach(async ({ app, user }) => {
// Create regular rooms
for (let i = 0; i < 3; i++) {
await app.client.createRoom({ name: `room${i}` });
}
});
test("should render sections with correct rooms in each", { tag: "@screenshot" }, async ({ page, app }) => {
// Create a favourite room
const favouriteId = await app.client.createRoom({ name: "favourite room" });
await app.client.evaluate(async (client, roomId) => {
await client.setRoomTag(roomId, "m.favourite");
}, favouriteId);
// Create a low priority room
const lowPrioId = await app.client.createRoom({ name: "low prio room" });
await app.client.evaluate(async (client, roomId) => {
await client.setRoomTag(roomId, "m.lowpriority");
}, lowPrioId);
const roomList = getRoomList(page);
// All three section headers should be visible
await expect(getSectionHeader(page, "Favourites")).toBeVisible();
await expect(getSectionHeader(page, "Chats")).toBeVisible();
await expect(getSectionHeader(page, "Low Priority")).toBeVisible();
// Ensure all rooms are visible
await expect(roomList.getByRole("row", { name: "Open room favourite room" })).toBeVisible();
await expect(roomList.getByRole("row", { name: "Open room low prio room" })).toBeVisible();
await expect(roomList.getByRole("row", { name: "Open room room0" })).toBeVisible();
await expect(roomList).toMatchScreenshot("room-list-sections.png");
});
test("should only show non-empty sections", async ({ page, app }) => {
// No low priority rooms created, only regular and favourite rooms
const favouriteId = await app.client.createRoom({ name: "favourite room" });
await app.client.evaluate(async (client, roomId) => {
await client.setRoomTag(roomId, "m.favourite");
}, favouriteId);
// Chats and Favourites sections should still be visible
await expect(getSectionHeader(page, "Chats")).toBeVisible();
await expect(getSectionHeader(page, "Favourites")).toBeVisible();
// Low Priority sections should not be visible
await expect(getSectionHeader(page, "Low Priority")).not.toBeVisible();
});
test("should render a flat list when there is only rooms in Chats section", async ({ page, app }) => {
// All sections should not be visible
await expect(getSectionHeader(page, "Chats")).not.toBeVisible();
await expect(getSectionHeader(page, "Favourites")).not.toBeVisible();
await expect(getSectionHeader(page, "Low Priority")).not.toBeVisible();
// It should be a flat list (using listbox a11y role)
await expect(page.getByRole("listbox", { name: "Room list", exact: true })).toBeVisible();
await expect(getRoomList(page).getByRole("option", { name: "Open room room0" })).toBeVisible();
});
});
test.describe("Section collapse and expand", () => {
[
{ section: "Favourites", roomName: "favourite room", tag: "m.favourite" },
{ section: "Low Priority", roomName: "low prio room", tag: "m.lowpriority" },
].forEach(({ section, roomName, tag }) => {
test(`should collapse and expand the ${section} section`, async ({ page, app }) => {
const roomId = await app.client.createRoom({ name: roomName });
if (tag) {
await app.client.evaluate(
async (client, { roomId, tag }) => {
await client.setRoomTag(roomId, tag);
},
{ roomId, tag },
);
}
const roomList = getRoomList(page);
const sectionHeader = getSectionHeader(page, section);
// The room should be visible
await expect(roomList.getByRole("row", { name: `Open room ${roomName}` })).toBeVisible();
// Collapse the section
await sectionHeader.click();
// The room should no longer be visible
await expect(roomList.getByRole("row", { name: `Open room ${roomName}` })).not.toBeVisible();
// The section header should still be visible
await expect(sectionHeader).toBeVisible();
// Expand the section again
await sectionHeader.click();
// The room should be visible again
await expect(roomList.getByRole("row", { name: `Open room ${roomName}` })).toBeVisible();
});
});
test("should render collapsed section", { tag: "@screenshot" }, async ({ page, app }) => {
const favouriteId = await app.client.createRoom({ name: "favourite room" });
await app.client.evaluate(async (client, roomId) => {
await client.setRoomTag(roomId, "m.favourite");
}, favouriteId);
await app.client.createRoom({ name: "regular room" });
const roomList = getRoomList(page);
// Collapse the Favourites section
await getSectionHeader(page, "Favourites").click();
// Verify favourite room is hidden but regular room is still visible
await expect(roomList.getByRole("row", { name: "Open room favourite room" })).not.toBeVisible();
await expect(roomList.getByRole("row", { name: "Open room regular room" })).toBeVisible();
await expect(roomList).toMatchScreenshot("room-list-sections-collapsed.png");
});
});
test.describe("Rooms placement in sections", () => {
test("should move a room between sections when tags change", async ({ page, app }) => {
await app.client.createRoom({ name: "my room" });
const roomList = getRoomList(page);
// Flat list because there is only rooms in the Chats section
let roomItem = roomList.getByRole("option", { name: "Open room my room" });
await expect(roomItem).toBeVisible();
// Favourite the room via context menu
await roomItem.click({ button: "right" });
await page.getByRole("menuitemcheckbox", { name: "Favourited" }).click();
// The Favourites section header should now be visible and the room should be under it
await expect(getSectionHeader(page, "Favourites")).toBeVisible();
roomItem = roomList.getByRole("row", { name: "Open room my room" });
await expect(roomItem).toBeVisible();
// Unfavourite the room
await roomItem.hover();
await roomItem.getByRole("button", { name: "More Options" }).click();
await page.getByRole("menuitemcheckbox", { name: "Favourited" }).click();
// Mark the room as low priority via context menu
roomItem = roomList.getByRole("option", { name: "Open room my room" });
await roomItem.click({ button: "right" });
await page.getByRole("menuitemcheckbox", { name: "Low priority" }).click();
// The Low Priority section header should now be visible and the room should be under it
await expect(getSectionHeader(page, "Low Priority")).toBeVisible();
roomItem = roomList.getByRole("row", { name: "Open room my room" });
await expect(roomItem).toBeVisible();
});
});
test("should show unread indicator on section header", async ({ page, app, bot }) => {
// Create a favourite room
const favouriteId = await app.client.createRoom({ name: "favourite room" });
await app.client.evaluate(async (client, roomId) => {
await client.setRoomTag(roomId, "m.favourite");
}, favouriteId);
const roomList = getRoomList(page);
// Invite the bot and have it send a message to generate an unread
await app.client.inviteUser(favouriteId, bot.credentials.userId);
await bot.joinRoom(favouriteId);
await bot.sendMessage(favouriteId, "Hello from bot!");
let sectionHeader = getSectionHeader(page, "Favourites", true);
await expect(sectionHeader).toBeVisible();
// Open the room to mark it as read
await roomList.getByRole("row", { name: "Open room favourite room" }).click();
// The section should no longer be unread
sectionHeader = getSectionHeader(page, "Favourites", false);
await expect(sectionHeader).toBeVisible();
});
test.describe("Sections and filters interaction", () => {
test("should not show Favourite and Low Priority filters when sections are enabled", async ({ page, app }) => {
const primaryFilters = getPrimaryFilters(page);
// Expand the filter list to see all filters
const expandButton = primaryFilters.getByRole("button", { name: "Expand filter list" });
await expandButton.click();
// Favourite and Low Priority filters should NOT be visible since sections handle them
await expect(primaryFilters.getByRole("option", { name: "Favourite" })).not.toBeVisible();
// Other filters should still be present
await expect(primaryFilters.getByRole("option", { name: "People" })).toBeVisible();
await expect(primaryFilters.getByRole("option", { name: "Rooms" })).toBeVisible();
await expect(primaryFilters.getByRole("option", { name: "Unread" })).toBeVisible();
});
test("should maintain sections when a filter is applied", async ({ page, app, bot }) => {
// Create a favourite room with unread messages
const favouriteId = await app.client.createRoom({ name: "fav with unread" });
await app.client.evaluate(async (client, roomId) => {
await client.setRoomTag(roomId, "m.favourite");
}, favouriteId);
await app.client.inviteUser(favouriteId, bot.credentials.userId);
await bot.joinRoom(favouriteId);
await bot.sendMessage(favouriteId, "Hello from favourite!");
// Create a regular room with unread messages
const regularId = await app.client.createRoom({ name: "regular with unread" });
await app.client.inviteUser(regularId, bot.credentials.userId);
await bot.joinRoom(regularId);
await bot.sendMessage(regularId, "Hello from regular!");
// Create a room without unread
await app.client.createRoom({ name: "no unread room" });
const roomList = getRoomList(page);
const primaryFilters = getPrimaryFilters(page);
// Apply the Unread filter
await primaryFilters.getByRole("option", { name: "Unread" }).click();
// Only rooms with unreads should be visible
await expect(roomList.getByRole("row", { name: "fav with unread" })).toBeVisible();
await expect(roomList.getByRole("row", { name: "regular with unread" })).toBeVisible();
await expect(roomList.getByRole("row", { name: "no unread room" })).not.toBeVisible();
});
});
});
@@ -10,6 +10,7 @@ import { type Page } from "@playwright/test";
import { expect, test } from "../../../element-web-test";
import { type Bot } from "../../../pages/bot";
import { type ElementAppPage } from "../../../pages/ElementAppPage";
import { getRoomList } from "./utils";
test.describe("Room list", () => {
test.use({
@@ -20,14 +21,6 @@ test.describe("Room list", () => {
},
});
/**
* Get the room list
* @param page
*/
function getRoomList(page: Page) {
return page.getByTestId("room-list");
}
test.beforeEach(async ({ page, app, user }) => {
// The notification toast is displayed above the search section
await app.closeNotificationToast();
@@ -328,11 +321,11 @@ test.describe("Room list", () => {
const roomListView = getRoomList(page);
const videoRoom = roomListView.getByRole("option", { name: "video room" });
await expect(videoRoom).toHaveAttribute("aria-selected", "true"); // wait for room list update
// focus the user menu to avoid to have hover decoration
await page.getByRole("button", { name: "User menu" }).focus();
await expect(videoRoom).toBeVisible();
await expect(videoRoom).toMatchScreenshot("room-list-item-video.png");
});
});
@@ -0,0 +1,92 @@
/*
* 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 { type Locator, type Page } from "@playwright/test";
/**
* Get the room list
* @param page
*/
export function getRoomList(page: Page): Locator {
return page.getByTestId("room-list");
}
/**
* Get the room list header
* @param page
*/
export function getRoomListHeader(page: Page): Locator {
return page.getByTestId("room-list-header");
}
/**
* Get a section header toggle button by section name
* @param page
* @param sectionName The display name of the section
* @param isUnread Whether to look for the unread version of the section header
*/
export function getSectionHeader(page: Page, sectionName: string, isUnread = false): Locator {
return getRoomList(page).getByRole("gridcell", {
name: isUnread ? `Toggle ${sectionName} section with unread room(s)` : `Toggle ${sectionName} section`,
});
}
/**
* Get the primary filters container
* @param page
*/
export function getPrimaryFilters(page: Page): Locator {
return page.getByTestId("primary-filters");
}
/**
* Get the room options menu button in the room list header
* @param page
*/
export function getRoomOptionsMenu(page: Page): Locator {
return page.getByRole("button", { name: "Room Options" });
}
/**
* Get the filter list expand button in the room list header
* @param page
*/
export function getFilterExpandButton(page: Page): Locator {
return getPrimaryFilters(page).getByRole("button", { name: "Expand filter list" });
}
/**
* Get the filter list collapse button in the room list header
* @param page
*/
export function getFilterCollapseButton(page: Page): Locator {
return getPrimaryFilters(page).getByRole("button", { name: "Collapse filter list" });
}
/**
* Get the header section of the room list
* @param page
*/
export function getHeaderSection(page: Page) {
return page.getByTestId("room-list-header");
}
/**
* Get the room list view
* @param page
*/
export function getRoomListView(page: Page) {
return page.getByRole("navigation", { name: "Room list" });
}
/**
* Get the search section of the room list
* @param page
*/
export function getSearchSection(page: Page) {
return page.getByRole("search");
}
@@ -14,7 +14,7 @@ test.describe("Message links", () => {
await use({ roomId });
},
});
for (const link of ["https://example.org", "example.org", "ftp://example.org"]) {
for (const link of ["https://example.org", "ftp://example.org"]) {
test(`should linkify a regular link '${link}'`, async ({ page, user, app, room }) => {
await page.goto(`#/room/${room.roomId}`);
// Needs to be unformatted so we test linkifing
@@ -24,6 +24,13 @@ test.describe("Message links", () => {
await expect(linkElement).toBeVisible();
});
}
test("should NOT linkify a bare domain", async ({ page, user, app, room }) => {
await page.goto(`#/room/${room.roomId}`);
// Needs to be unformatted so we test linkifing
await app.client.sendMessage(room.roomId, `Check out example.org`);
const linkElement = page.locator(".mx_EventTile_last").getByRole("link", { name: "example.org" });
await expect(linkElement).not.toBeVisible();
});
test("should linkify a User ID", async ({ page, user, app, room }) => {
await page.goto(`#/room/${room.roomId}`);
// Needs to be unformatted so we test linkifing
+1 -7
View File
@@ -14,13 +14,7 @@ test.describe("Topic links", () => {
await use({ roomId });
},
});
for (const link of [
"https://example.org",
"example.org",
"ftp://example.org",
"#aroom:example.org",
"@alice:example.org",
]) {
for (const link of ["https://example.org", "ftp://example.org", "#aroom:example.org", "@alice:example.org"]) {
// Playwright treats '@' as a tag, so replace it to be safe
test(`should linkify plaintext '${link.replace("@", "_@")}'`, async ({ page, user, app, room }) => {
await app.client.sendStateEvent(
@@ -126,7 +126,7 @@ test.describe("Login", () => {
await page.goto("/");
// Should give us the welcome page initially
await expect(page.getByRole("heading", { name: "Welcome to Element!" })).toBeVisible();
await expect(page.getByRole("heading", { name: "Be in your element" })).toBeVisible();
// Start the login process
await expect(axe).toHaveNoViolations();
@@ -252,6 +252,7 @@ test.describe("Message url previews", () => {
"og:title": "A simple site",
"og:description": "And with a brief description",
"og:image": mxc,
"og:image:alt": "The riot logo",
},
});
});
@@ -148,7 +148,8 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
const userId = `alice_${testInfo.testId}`;
await registerAccountMas(page, mailpitClient, userId, `${userId}@email.com`, "Pa$sW0rD!");
await expect(page.getByText("Welcome")).toBeVisible();
// richvdh: This takes several seconds to happen on a dev instance
await expect(page.getByText("Welcome")).toBeVisible({ timeout: 10000 });
// Log out
await page.getByRole("button", { name: "User menu" }).click();
@@ -162,11 +163,14 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
// Log in again
await page.goto("/#/login");
await expect(page.getByText("Sign in")).toBeVisible();
await page.getByRole("button", { name: "Continue" }).click();
await expect(page.getByText("Continue to Element?")).toBeVisible();
await page.getByRole("button", { name: "Continue" }).click();
// We should be being warned that we need to verify (but we can't)
await expect(page.getByText("Confirm your digital identity")).toBeVisible();
// richvdh: Again, Element takes several seconds to load on a dev instance
await expect(page.getByText("Confirm your digital identity")).toBeVisible({ timeout: 10000 });
// And there should be no way to close this prompt
await expect(page.getByRole("button", { name: "Skip verification for now" })).not.toBeVisible();
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/
import type { JSHandle } from "@playwright/test";
import type { MatrixEvent, ISendEventResponse, ReceiptType } from "matrix-js-sdk/src/matrix";
import type { MatrixEvent, ISendEventResponse, ReceiptType, RelationType } from "matrix-js-sdk/src/matrix";
import { expect } from "../../element-web-test";
import { type ElementAppPage } from "../../pages/ElementAppPage";
import { type Bot } from "../../pages/bot";
@@ -47,7 +47,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
getId: () => eventResponse.event_id,
threadRootId,
getTs: () => 1,
isRelation: (relType) => {
isRelation: (relType: RelationType) => {
return !relType || relType === "m.thread";
},
} as any as MatrixEvent;
@@ -48,9 +48,9 @@ test.describe("Room Directory", () => {
await app.closeDialog();
const resp = await bot.publicRooms({});
expect(resp.total_room_count_estimate).toEqual(1);
expect(resp.chunk).toHaveLength(1);
expect(resp.chunk[0].room_id).toEqual(roomId);
expect(resp.total_room_count_estimate).toBeGreaterThanOrEqual(1);
expect(resp.chunk).toHaveLength(resp.total_room_count_estimate);
expect(resp.chunk.find((r) => r.room_id === roomId)).toBeTruthy();
},
);
@@ -57,6 +57,9 @@ test.describe("Create Room", () => {
await page.getByRole("button", { name: "Go" }).click();
await expect(page.getByRole("heading", { name: "Start a chat with this new contact?" })).toBeVisible();
await page.getByRole("button", { name: "Continue" }).click();
await expect(page.getByText("Encryption enabled")).toBeVisible();
await expect(page.getByText("Send your first message to")).toBeVisible();
@@ -163,6 +163,10 @@ test.describe("Room Status Bar", () => {
).toBeVisible();
await other.getByRole("option", { name: "Alice" }).click();
await other.getByRole("button", { name: "Go" }).click();
await expect(page.getByRole("heading", { name: "Start a chat with this new contact?" })).toBeVisible();
await page.getByRole("button", { name: "Continue" }).click();
// Send a message to invite the bots
const composer = app.getComposerField();
await composer.fill("Hello");
@@ -24,7 +24,7 @@ test.describe("Account user settings tab", () => {
},
});
test("should be rendered properly", { tag: "@screenshot" }, async ({ uut, user }) => {
test("should be rendered properly", { tag: "@screenshot" }, async ({ uut, user, axe }) => {
await expect(uut).toMatchScreenshot("account.png");
// Assert that the top heading is rendered
@@ -70,6 +70,8 @@ test.describe("Account user settings tab", () => {
await expect(accountManagementSection.getByRole("button", { name: "Deactivate Account" })).toHaveClass(
/mx_AccessibleButton_kind_danger/,
);
await expect(axe).toHaveNoViolations();
});
test("should respond to small screen sizes", { tag: "@screenshot" }, async ({ page, uut }) => {
@@ -13,7 +13,7 @@ test.describe("Appearance user settings tab", () => {
displayName: "Hanako",
});
test("should be rendered properly", { tag: "@screenshot" }, async ({ page, user, app }) => {
test("should be rendered properly", { tag: "@screenshot" }, async ({ page, user, app, axe }) => {
const tab = await app.settings.openUserSettings("Appearance");
// Click "Show advanced" link button
@@ -23,6 +23,8 @@ test.describe("Appearance user settings tab", () => {
await expect(tab.getByRole("button", { name: "Hide advanced" })).toBeVisible();
await expect(tab).toMatchScreenshot("appearance-tab.png");
await expect(axe).toHaveNoViolations();
});
test(
@@ -23,7 +23,7 @@ test.describe("Appearance user settings tab", () => {
test(
"should be rendered with the light theme selected",
{ tag: "@screenshot" },
async ({ page, app, util }) => {
async ({ page, app, util, axe }) => {
// Assert that 'Match system theme' is not checked
await expect(util.getMatchSystemThemeSwitch()).not.toBeChecked();
@@ -34,6 +34,8 @@ test.describe("Appearance user settings tab", () => {
await expect(util.getHighContrastTheme()).not.toBeChecked();
await expect(util.getThemePanel()).toMatchScreenshot("theme-panel-light.png");
await expect(axe).toHaveNoViolations();
},
);
@@ -23,7 +23,7 @@ test.describe("Device manager", () => {
}
});
test("should display sessions", async ({ page, app }) => {
test("should display sessions", async ({ page, app, axe }) => {
await app.settings.openUserSettings("Sessions");
const tab = page.locator(".mx_SettingsTab");
@@ -85,7 +85,7 @@ test.describe("Device manager", () => {
// session name updated in details
await expect(firstSession.locator(".mx_DeviceDetailHeading h4").getByText(sessionName)).toBeVisible();
// and main list item
await expect(firstSession.locator(".mx_DeviceTile h4").getByText(sessionName)).toBeVisible();
await expect(firstSession.locator(".mx_DeviceTile h3").getByText(sessionName)).toBeVisible();
// sign out using the device details sign out
await firstSession.getByRole("button", { name: "Remove this session" }).click();
@@ -96,5 +96,7 @@ test.describe("Device manager", () => {
// no other sessions or security recommendations sections when only one session
await expect(tab.getByText("Other sessions")).not.toBeVisible();
await expect(tab.getByTestId("security-recommendations-section")).not.toBeVisible();
await expect(axe).toHaveNoViolations();
});
});
@@ -16,7 +16,7 @@ test.describe("Advanced section in Encryption tab", () => {
await bootstrapCrossSigningForClient(clientHandle, credentials, true);
});
test("should show the encryption details", { tag: "@screenshot" }, async ({ page, app, util }) => {
test("should show the encryption details", { tag: "@screenshot" }, async ({ page, app, util, axe }) => {
await util.openEncryptionTab();
const section = util.getEncryptionDetailsSection();
@@ -26,6 +26,8 @@ test.describe("Advanced section in Encryption tab", () => {
await expect(section).toMatchScreenshot("encryption-details.png", {
mask: [section.getByTestId("deviceId"), section.getByTestId("sessionKey")],
});
await expect(axe).toHaveNoViolations();
});
test("should show the import room keys dialog", async ({ page, app, util }) => {
@@ -33,7 +33,7 @@ test.describe("Other people's devices section in Encryption tab", () => {
// Create the room and invite bob
await createRoom(alicePage, "TestRoom", true);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId, { confirmUnknownUser: true });
// Bob accepts the invite
await bobPage.getByRole("option", { name: "TestRoom" }).click();
@@ -72,7 +72,7 @@ test.describe("Other people's devices section in Encryption tab", () => {
// Create the room and invite bob
await createRoom(alicePage, "TestRoom", true);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId, { confirmUnknownUser: true });
// Bob accepts the invite
await bobPage.getByRole("option", { name: "TestRoom" }).click();
@@ -115,7 +115,7 @@ test.describe("Other people's devices section in Encryption tab", () => {
// Create the room and invite bob
await createRoom(alicePage, "TestRoom", true);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId, { confirmUnknownUser: true });
// Bob accepts the invite and dismisses the warnings.
await bobPage.getByRole("option", { name: "TestRoom" }).click();
@@ -149,7 +149,7 @@ test.describe("Other people's devices section in Encryption tab", () => {
// Alice creates the room and invite Bob.
await createRoom(alicePage, "TestRoom", true);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId, { confirmUnknownUser: true });
// Bob accepts the invite.
await bobPage.getByRole("option", { name: "TestRoom" }).click();
@@ -214,7 +214,7 @@ test.describe("Other people's devices section in Encryption tab", () => {
// Alice creates the room and invite Bob.
await createRoom(alicePage, "TestRoom", true);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId);
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId, { confirmUnknownUser: true });
// Bob accepts the invite.
await bobPage.getByRole("option", { name: "TestRoom" }).click();
@@ -20,7 +20,7 @@ test.describe("General room settings tab", () => {
await app.viewRoomByName(roomName);
});
test("should be rendered properly", { tag: "@screenshot" }, async ({ page, app }) => {
test("should be rendered properly", { tag: "@screenshot" }, async ({ page, app, axe }) => {
const settings = await app.settings.openRoomSettings("General");
// Assert that "Show less" details element is rendered
@@ -34,6 +34,9 @@ test.describe("General room settings tab", () => {
// Assert that "Show more" details element is rendered instead of "Show more"
await expect(settings.getByText("Show less")).not.toBeVisible();
await expect(settings.getByText("Show more")).toBeVisible();
axe.disableRules("color-contrast"); // XXX: We have some known contrast issues here
await expect(axe).toHaveNoViolations();
});
test("long address should not cause dialog to overflow", { tag: "@no-webkit" }, async ({ page, app, user }) => {
@@ -25,7 +25,7 @@ test.describe("Preferences user settings tab", () => {
labsFlags: ["feature_new_room_list"],
});
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user }) => {
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user, axe }) => {
await page.setViewportSize({ width: 1024, height: 4000 });
const tab = await app.settings.openUserSettings("Preferences");
// Assert that the top heading is rendered
@@ -39,6 +39,8 @@ test.describe("Preferences user settings tab", () => {
}
`,
});
await expect(axe).toHaveNoViolations();
});
test("should be able to change the app language", { tag: ["@no-firefox", "@no-webkit"] }, async ({ uut, user }) => {
@@ -8,11 +8,13 @@ Please see LICENSE files in the repository root for full details.
import { test, expect } from "../../element-web-test";
test.describe("Quick settings menu", () => {
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user }) => {
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user, axe }) => {
await page.getByRole("button", { name: "Quick settings" }).click();
// Assert that the top heading is renderedc
const settings = page.getByTestId("quick-settings-menu");
await expect(settings).toBeVisible();
await expect(settings).toMatchScreenshot("quick-settings.png");
await expect(axe).toHaveNoViolations();
});
});
@@ -25,7 +25,7 @@ test.describe("Roles & Permissions room settings tab", () => {
settings = await app.settings.openRoomSettings("Roles & Permissions");
});
test("should be able to change the role of a user", async ({ page, app, user }) => {
test("should be able to change the role of a user", async ({ page, app, user, axe }) => {
const privilegedUserSection = settings.locator(".mx_SettingsFieldset").first();
const applyButton = privilegedUserSection.getByRole("button", { name: "Apply" });
@@ -55,5 +55,7 @@ test.describe("Roles & Permissions room settings tab", () => {
settings = await app.settings.openRoomSettings("Roles & Permissions");
combobox = privilegedUserSection.getByRole("combobox", { name: user.userId });
await expect(combobox).toHaveValue("50");
await expect(axe).toHaveNoViolations();
});
});
@@ -32,12 +32,14 @@ test.describe("Security user settings tab", () => {
});
test.describe("AnalyticsLearnMoreDialog", () => {
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user }) => {
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user, axe }) => {
const tab = await app.settings.openUserSettings("Security");
await tab.getByRole("button", { name: "Learn more" }).click();
await expect(page.locator(".mx_AnalyticsLearnMoreDialog_wrapper .mx_Dialog")).toMatchScreenshot(
"Security-user-settings-tab-with-posthog-enable-b5d89-csLearnMoreDialog-should-be-rendered-properly-1.png",
);
await expect(axe).toHaveNoViolations();
});
});
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/
import type { Locator, Page } from "@playwright/test";
import type { ISendEventResponse, EventType, MsgType } from "matrix-js-sdk/src/matrix";
import type { ISendEventResponse, EventType, MsgType, IContent } from "matrix-js-sdk/src/matrix";
import { test, expect } from "../../element-web-test";
import { SettingLevel } from "../../../src/settings/SettingLevel";
import { Layout } from "../../../src/settings/enums/Layout";
@@ -50,11 +50,9 @@ const expectAvatar = async (cli: Client, e: Locator, avatarUrl: string): Promise
};
const sendEvent = async (client: Client, roomId: string, html = false): Promise<ISendEventResponse> => {
const content = {
const content: IContent = {
msgtype: "m.text" as MsgType,
body: "Message",
format: undefined,
formatted_body: undefined,
};
if (html) {
content.format = "org.matrix.custom.html";
+2 -2
View File
@@ -42,7 +42,7 @@ export async function waitForRoom(
return new Promise<Room>((resolve) => {
const room = matrixClient.getRoom(roomId);
if (window[predicateId](room)) {
if ((<any>window)[predicateId](room)) {
resolve(room);
return;
}
@@ -50,7 +50,7 @@ export async function waitForRoom(
function onEvent(ev: MatrixEvent) {
if (ev.getRoomId() !== roomId) return;
if (window[predicateId](room)) {
if ((<any>window)[predicateId](room)) {
matrixClient.removeListener("event" as ClientEvent, onEvent);
resolve(room);
}
+1 -6
View File
@@ -24,7 +24,6 @@ import type { IConfigOptions } from "../src/IConfigOptions";
import { type Credentials } from "./plugins/homeserver";
import { ElementAppPage } from "./pages/ElementAppPage";
import { Crypto } from "./pages/crypto";
import { Toasts } from "./pages/toasts";
import { Bot, type CreateBotOpts } from "./pages/bot";
import { Webserver } from "./plugins/webserver";
import { type WorkerOptions, type Services, test as base } from "./services";
@@ -52,7 +51,6 @@ export interface TestFixtures extends BaseTestFixtures {
crypto: Crypto;
room?: { roomId: string };
toasts: Toasts;
uut?: Locator; // Unit Under Test, useful place to refer a prepared locator
botCreateOpts: CreateBotOpts;
bot: Bot;
@@ -92,9 +90,6 @@ export const test = base.extend<TestFixtures>({
crypto: async ({ page, homeserver, request }, use) => {
await use(new Crypto(page, homeserver, request));
},
toasts: async ({ page }, use) => {
await use(new Toasts(page));
},
botCreateOpts: {},
bot: async ({ page, homeserver, botCreateOpts, user }, use, testInfo) => {
@@ -112,7 +107,7 @@ export const test = base.extend<TestFixtures>({
},
});
interface ExtendedToMatchScreenshotOptions extends ToMatchScreenshotOptions {
export interface ExtendedToMatchScreenshotOptions extends ToMatchScreenshotOptions {
includeDialogBackground?: boolean;
showTooltips?: boolean;
timeout?: number;
+18 -3
View File
@@ -233,15 +233,30 @@ export class ElementAppPage {
* Open the room info panel, and use it to send an invite to the given user.
*
* @param userId - The user to invite to the room.
* @param options - Options object
*/
public async inviteUserToCurrentRoom(userId: string): Promise<void> {
public async inviteUserToCurrentRoom(
userId: string,
options?: {
/** If true, expect and acknowledge "Confirm inviting new users" page */
confirmUnknownUser?: boolean;
},
): Promise<void> {
const rightPanel = await this.openRoomInfoPanel();
await rightPanel.getByRole("menuitem", { name: "Invite" }).click();
const input = this.page.getByRole("dialog").getByTestId("invite-dialog-input");
const dialogLocator = this.page.getByRole("dialog");
const input = dialogLocator.getByTestId("invite-dialog-input");
await input.fill(userId);
await input.press("Enter");
await this.page.getByRole("dialog").getByRole("button", { name: "Invite" }).click();
await dialogLocator.getByRole("button", { name: "Invite" }).click();
if (options?.confirmUnknownUser) {
await expect(
dialogLocator.getByRole("heading", { name: "Invite new contacts to this room?" }),
).toBeVisible();
await dialogLocator.getByRole("button", { name: "Invite" }).click();
}
}
/**
+29 -1
View File
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/
import { type JSHandle, type Page } from "@playwright/test";
import { type PageFunctionOn } from "playwright-core/types/structs";
import { type ElementHandle } from "playwright-core";
import { Network } from "./network";
import type {
@@ -30,6 +30,34 @@ import type {
import type { RoomMessageEventContent } from "matrix-js-sdk/src/types";
import { type CredentialsOptionalAccessToken } from "./bot";
/** Types cribbed from playwright-core/types/structs as they are not importable */
export type NoHandles<Arg> = Arg extends JSHandle
? never
: Arg extends object
? { [Key in keyof Arg]: NoHandles<Arg[Key]> }
: Arg;
export type Unboxed<Arg> =
Arg extends ElementHandle<infer T>
? T
: Arg extends JSHandle<infer T>
? T
: Arg extends NoHandles<Arg>
? Arg
: Arg extends [infer A0]
? [Unboxed<A0>]
: Arg extends [infer A0, infer A1]
? [Unboxed<A0>, Unboxed<A1>]
: Arg extends [infer A0, infer A1, infer A2]
? [Unboxed<A0>, Unboxed<A1>, Unboxed<A2>]
: Arg extends [infer A0, infer A1, infer A2, infer A3]
? [Unboxed<A0>, Unboxed<A1>, Unboxed<A2>, Unboxed<A3>]
: Arg extends Array<infer T>
? Array<Unboxed<T>>
: Arg extends object
? { [Key in keyof Arg]: Unboxed<Arg[Key]> }
: Arg;
export type PageFunctionOn<On, Arg2, R> = string | ((on: On, arg2: Unboxed<Arg2>) => R | Promise<R>);
export class Client {
public network: Network;
protected client: JSHandle<MatrixClient>;

Some files were not shown because too many files have changed in this diff Show More