Merge branch 'develop' into florianduros/encryption-tab
commit
4b365bae2c
|
@ -5,6 +5,9 @@ on:
|
|||
branches: [develop, master]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.sha }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
# develop pushes and repository_dispatch handled in build_develop.yaml
|
||||
env:
|
||||
# These must be set for fetchdep.sh to get the right branch
|
||||
|
@ -37,14 +40,38 @@ jobs:
|
|||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
# Disable cache on Windows as it is slower than not caching
|
||||
# https://github.com/actions/setup-node/issues/975
|
||||
cache: ${{ runner.os != 'Windows' && 'yarn' || '' }}
|
||||
node-version: "lts/*"
|
||||
|
||||
# Workaround for yarn install timeouts, especially on Windows
|
||||
- run: yarn config set network-timeout 300000
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
- name: Fetch layered build
|
||||
id: layered_build
|
||||
env:
|
||||
# tell layered.sh to check out the right sha of the JS-SDK & EW, if they were given one
|
||||
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
|
||||
run: |
|
||||
scripts/layered.sh
|
||||
JSSDK_SHA=$(git -C matrix-js-sdk rev-parse --short=12 HEAD)
|
||||
VECTOR_SHA=$(git rev-parse --short=12 HEAD)
|
||||
echo "VERSION=$VECTOR_SHA--js-$JSSDK_SHA" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Copy config
|
||||
run: cp element.io/develop/config.json config.json
|
||||
|
||||
- name: Build
|
||||
run: "yarn build"
|
||||
env:
|
||||
CI_PACKAGE: true
|
||||
VERSION: "${{ steps.layered_build.outputs.VERSION }}"
|
||||
run: |
|
||||
yarn build
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: webapp-${{ matrix.image }}
|
||||
path: webapp
|
||||
retention-days: 1
|
||||
|
|
|
@ -27,7 +27,7 @@ jobs:
|
|||
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3
|
||||
with:
|
||||
install: true
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
name: Upload Preview Build to Netlify
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["End to End Tests"]
|
||||
workflows: ["Build"]
|
||||
types:
|
||||
- completed
|
||||
jobs:
|
||||
|
@ -32,7 +32,7 @@ jobs:
|
|||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
name: webapp
|
||||
name: webapp-ubuntu-24.04
|
||||
path: webapp
|
||||
|
||||
- name: 📤 Deploy to Netlify
|
||||
|
|
|
@ -23,7 +23,7 @@ jobs:
|
|||
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7
|
||||
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7
|
||||
with:
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
branch: actions/playwright-image-updates
|
||||
|
|
|
@ -104,7 +104,7 @@ jobs:
|
|||
|
||||
- name: Skip SonarCloud in merge queue
|
||||
if: github.event_name == 'merge_group' || inputs.disable_coverage == 'true'
|
||||
uses: guibranco/github-status-action-v2@d469d49426f5a7b8a1fbcac20ad274d3e4892321
|
||||
uses: guibranco/github-status-action-v2@56cd38caf0615dd03f49d42ed301f1469911ac61
|
||||
with:
|
||||
authToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
state: success
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
name: Close stale flaky issues
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
permissions: {}
|
||||
|
@ -17,3 +18,4 @@ jobs:
|
|||
days-before-close: 0
|
||||
close-issue-message: "This flaky test issue has not been updated in 14 days. It is being closed as presumed resolved."
|
||||
exempt-issue-labels: "Z-Flaky-Test-Disabled"
|
||||
operations-per-run: 100
|
||||
|
|
|
@ -23,7 +23,7 @@ jobs:
|
|||
run: "yarn update:jitsi"
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7
|
||||
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7
|
||||
with:
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
branch: actions/jitsi-update
|
||||
|
|
27
Dockerfile
27
Dockerfile
|
@ -1,20 +1,17 @@
|
|||
# Builder
|
||||
FROM --platform=$BUILDPLATFORM node:22-bullseye as builder
|
||||
FROM --platform=$BUILDPLATFORM node:22-bullseye AS builder
|
||||
|
||||
# Support custom branch of the js-sdk. This also helps us build images of element-web develop.
|
||||
ARG USE_CUSTOM_SDKS=false
|
||||
ARG JS_SDK_REPO="https://github.com/matrix-org/matrix-js-sdk.git"
|
||||
ARG JS_SDK_BRANCH="master"
|
||||
|
||||
RUN apt-get update && apt-get install -y git dos2unix
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
COPY . /src
|
||||
RUN dos2unix /src/scripts/docker-link-repos.sh && bash /src/scripts/docker-link-repos.sh
|
||||
RUN /src/scripts/docker-link-repos.sh
|
||||
RUN yarn --network-timeout=200000 install
|
||||
|
||||
RUN dos2unix /src/scripts/docker-package.sh /src/scripts/get-version-from-git.sh /src/scripts/normalize-version.sh && bash /src/scripts/docker-package.sh
|
||||
RUN /src/scripts/docker-package.sh
|
||||
|
||||
# Copy the config now so that we don't create another layer in the app image
|
||||
RUN cp /src/config.sample.json /src/webapp/config.json
|
||||
|
@ -24,8 +21,22 @@ FROM nginx:alpine-slim
|
|||
|
||||
COPY --from=builder /src/webapp /app
|
||||
|
||||
# Override default nginx config
|
||||
COPY /nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
|
||||
# Override default nginx config. Templates in `/etc/nginx/templates` are passed
|
||||
# through `envsubst` by the nginx docker image entry point.
|
||||
COPY /docker/nginx-templates/* /etc/nginx/templates/
|
||||
|
||||
# Tell nginx to put its pidfile elsewhere, so it can run as non-root
|
||||
RUN sed -i -e 's,/var/run/nginx.pid,/tmp/nginx.pid,' /etc/nginx/nginx.conf
|
||||
|
||||
# nginx user must own the cache and etc directory to write cache and tweak the nginx config
|
||||
RUN chown -R nginx:0 /var/cache/nginx /etc/nginx
|
||||
RUN chmod -R g+w /var/cache/nginx /etc/nginx
|
||||
|
||||
RUN rm -rf /usr/share/nginx/html \
|
||||
&& ln -s /app /usr/share/nginx/html
|
||||
|
||||
# Run as nginx user by default
|
||||
USER nginx
|
||||
|
||||
# HTTP listen port
|
||||
ENV ELEMENT_WEB_PORT=80
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
Licensees holding a valid commercial license with Element may use this
|
||||
software in accordance with the terms contained in a written agreement
|
||||
between you and Element.
|
||||
|
||||
To purchase a commercial license please contact our sales team at
|
||||
licensing@element.io
|
15
README.md
15
README.md
|
@ -311,3 +311,18 @@ For a developer guide, see the [translating dev doc](docs/translating-dev.md).
|
|||
Issues are triaged by community members and the Web App Team, following the [triage process](https://github.com/element-hq/element-meta/wiki/Triage-process).
|
||||
|
||||
We use [issue labels](https://github.com/element-hq/element-meta/wiki/Issue-labelling) to sort all incoming issues.
|
||||
|
||||
## Copyright & License
|
||||
|
||||
Copyright (c) 2014-2017 OpenMarket Ltd
|
||||
Copyright (c) 2017 Vector Creations Ltd
|
||||
Copyright (c) 2017-2025 New Vector Ltd
|
||||
|
||||
This software is multi licensed by New Vector Ltd (Element). It can be used either:
|
||||
|
||||
(1) for free under the terms of the GNU Affero General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version); OR
|
||||
|
||||
(2) for free under the terms of the GNU General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version); OR
|
||||
|
||||
(3) under the terms of a paid-for Element Commercial License agreement between you and Element (the terms of which may vary depending on what you and Element have agreed to).
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the Licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licenses for the specific language governing permissions and limitations under the Licenses.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"description": "A glossy Matrix collaboration client for the web.",
|
||||
"repository": {
|
||||
"url": "https://github.com/element-hq/element-web",
|
||||
"license": "AGPL-3.0-only OR GPL-3.0-only"
|
||||
"license": "AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial"
|
||||
},
|
||||
"bugs": {
|
||||
"list": "https://github.com/element-hq/element-web/issues",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
listen ${ELEMENT_WEB_PORT};
|
||||
listen [::]:${ELEMENT_WEB_PORT};
|
||||
server_name localhost;
|
||||
|
||||
root /usr/share/nginx/html;
|
|
@ -60,6 +60,22 @@ would be:
|
|||
docker run --rm -p 127.0.0.1:80:80 -v /etc/element-web/config.json:/app/config.json vectorim/element-web
|
||||
```
|
||||
|
||||
The Docker image is configured to run as an unprivileged (non-root) user by
|
||||
default. This should be fine on modern Docker runtimes, but binding to port 80
|
||||
on other runtimes may require root privileges. To resolve this, either run the
|
||||
image as root (`docker run --user 0`) or, better, change the port that nginx
|
||||
listens on via the `ELEMENT_WEB_PORT` environment variable.
|
||||
|
||||
The behaviour of the docker image can be customised via the following
|
||||
environment variables:
|
||||
|
||||
- `ELEMENT_WEB_PORT`
|
||||
|
||||
The port to listen on (within the docker container) for HTTP
|
||||
traffic. Defaults to `80`.
|
||||
|
||||
### Building the docker image
|
||||
|
||||
To build the image yourself:
|
||||
|
||||
```bash
|
||||
|
|
22
docs/oidc.md
22
docs/oidc.md
|
@ -1,29 +1,9 @@
|
|||
# OIDC and delegated authentication
|
||||
|
||||
## Compatibility/OIDC-aware mode
|
||||
|
||||
[MSC2965: OIDC provider discovery](https://github.com/matrix-org/matrix-spec-proposals/pull/2965)
|
||||
[MSC3824: OIDC aware clients](https://github.com/matrix-org/matrix-spec-proposals/pull/3824)
|
||||
This mode uses an SSO flow to gain a `loginToken` from the authentication provider, then continues with SSO login.
|
||||
Element Web uses [MSC2965: OIDC provider discovery](https://github.com/matrix-org/matrix-spec-proposals/pull/2965) to discover the configured provider.
|
||||
Wherever valid MSC2965 configuration is discovered, OIDC-aware login flow will be the only option offered.
|
||||
|
||||
## (🧪Experimental) OIDC-native flow
|
||||
|
||||
Can be enabled by a config-level-only setting in `config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"feature_oidc_native_flow": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See https://areweoidcyet.com/client-implementation-guide/ for implementation details.
|
||||
|
||||
Element Web uses [MSC2965: OIDC provider discovery](https://github.com/matrix-org/matrix-spec-proposals/pull/2965) to discover the configured provider.
|
||||
Where OIDC native login flow is enabled and valid MSC2965 configuration is discovered, OIDC native login flow will be the only login option offered.
|
||||
Where a valid MSC2965 configuration is discovered, OIDC native login flow will be the only login option offered.
|
||||
Element Web will attempt to [dynamically register](https://openid.net/specs/openid-connect-registration-1_0.html) with the configured OP.
|
||||
Then, authentication will be completed [as described here](https://areweoidcyet.com/client-implementation-guide/).
|
||||
|
||||
|
|
|
@ -227,7 +227,11 @@ has to be disabled in Playwright on Firefox & Webkit to retain routing functiona
|
|||
Anything testing VoIP/microphone will need to have `@no-webkit` as fake microphone functionality is not available
|
||||
there at this time.
|
||||
|
||||
## Colima
|
||||
## Supporter container runtimes
|
||||
|
||||
We use testcontainers to spin up various instances of Synapse, Matrix Authentication Service, and more.
|
||||
It supports Docker out of the box but also has support for Podman, Colima, Rancher, you just need to follow some instructions to achieve it:
|
||||
https://node.testcontainers.org/supported-container-runtimes/
|
||||
|
||||
If you are running under Colima, you may need to set the environment variable `TMPDIR` to `/tmp/colima` or a path
|
||||
within `$HOME` to allow bind mounting temporary directories into the Docker containers.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -14,6 +14,8 @@ const config: Config = {
|
|||
testEnvironment: "jsdom",
|
||||
testEnvironmentOptions: {
|
||||
url: "http://localhost/",
|
||||
// This is needed to be able to load dual CJS/ESM WASM packages e.g. rust crypto & matrix-wywiwyg
|
||||
customExportConditions: ["browser", "node"],
|
||||
},
|
||||
testMatch: ["<rootDir>/test/**/*-test.[tj]s?(x)"],
|
||||
globalSetup: "<rootDir>/test/globalSetup.ts",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright 2022-2024 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright 2022-2024 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright 2022-2024 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
30
package.json
30
package.json
|
@ -7,7 +7,7 @@
|
|||
"type": "git",
|
||||
"url": "https://github.com/element-hq/element-web"
|
||||
},
|
||||
"license": "AGPL-3.0-only OR GPL-3.0-only",
|
||||
"license": "SEE LICENSE IN README.md",
|
||||
"files": [
|
||||
"lib",
|
||||
"res",
|
||||
|
@ -71,9 +71,11 @@
|
|||
"update:jitsi": "curl -s https://meet.element.io/libs/external_api.min.js > ./res/jitsi_external_api.min.js"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "18.3.18",
|
||||
"@types/react-dom": "18.3.5",
|
||||
"oidc-client-ts": "3.1.0",
|
||||
"jwt-decode": "4.0.0",
|
||||
"caniuse-lite": "1.0.30001684",
|
||||
"caniuse-lite": "1.0.30001690",
|
||||
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0",
|
||||
"wrap-ansi": "npm:wrap-ansi@^7.0.0"
|
||||
},
|
||||
|
@ -87,9 +89,10 @@
|
|||
"@matrix-org/react-sdk-module-api": "^2.4.0",
|
||||
"@matrix-org/spec": "^1.7.0",
|
||||
"@sentry/browser": "^8.0.0",
|
||||
"@types/png-chunks-extract": "^1.0.2",
|
||||
"@vector-im/compound-design-tokens": "^2.0.1",
|
||||
"@vector-im/compound-web": "^7.5.0",
|
||||
"@vector-im/matrix-wysiwyg": "2.37.13",
|
||||
"@vector-im/matrix-wysiwyg": "2.38.0",
|
||||
"@zxcvbn-ts/core": "^3.0.4",
|
||||
"@zxcvbn-ts/language-common": "^3.0.4",
|
||||
"@zxcvbn-ts/language-en": "^3.0.2",
|
||||
|
@ -121,7 +124,7 @@
|
|||
"linkify-string": "4.2.0",
|
||||
"linkifyjs": "4.2.0",
|
||||
"lodash": "^4.17.21",
|
||||
"maplibre-gl": "^4.0.0",
|
||||
"maplibre-gl": "^5.0.0",
|
||||
"matrix-encrypt-attachment": "^1.0.3",
|
||||
"matrix-events-sdk": "0.0.1",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||
|
@ -134,7 +137,7 @@
|
|||
"png-chunks-extract": "^1.0.0",
|
||||
"posthog-js": "1.157.2",
|
||||
"qrcode": "1.5.4",
|
||||
"re-resizable": "6.10.1",
|
||||
"re-resizable": "6.10.3",
|
||||
"react": "^18.3.1",
|
||||
"react-beautiful-dnd": "^13.1.0",
|
||||
"react-blurhash": "^0.3.0",
|
||||
|
@ -143,7 +146,7 @@
|
|||
"react-transition-group": "^4.4.1",
|
||||
"rfc4648": "^1.4.0",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"sanitize-html": "2.13.1",
|
||||
"sanitize-html": "2.14.0",
|
||||
"tar-js": "^0.3.0",
|
||||
"temporal-polyfill": "^0.2.5",
|
||||
"ua-parser-js": "^1.0.2",
|
||||
|
@ -177,6 +180,7 @@
|
|||
"@sentry/webpack-plugin": "^2.7.1",
|
||||
"@stylistic/eslint-plugin": "^2.9.0",
|
||||
"@svgr/webpack": "^8.0.0",
|
||||
"@testcontainers/postgresql": "^10.16.0",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-dom": "^6.4.8",
|
||||
"@testing-library/react": "^16.0.0",
|
||||
|
@ -188,7 +192,6 @@
|
|||
"@types/escape-html": "^1.0.1",
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/file-saver": "^2.0.3",
|
||||
"@types/fs-extra": "^11.0.0",
|
||||
"@types/glob-to-regexp": "^0.4.1",
|
||||
"@types/jest": "29.5.12",
|
||||
"@types/jitsi-meet": "^2.0.2",
|
||||
|
@ -201,17 +204,17 @@
|
|||
"@types/node-fetch": "^2.6.2",
|
||||
"@types/pako": "^2.0.0",
|
||||
"@types/qrcode": "^1.3.5",
|
||||
"@types/react": "18.3.3",
|
||||
"@types/react": "18.3.18",
|
||||
"@types/react-beautiful-dnd": "^13.0.0",
|
||||
"@types/react-dom": "18.3.1",
|
||||
"@types/react-dom": "18.3.5",
|
||||
"@types/react-transition-group": "^4.4.0",
|
||||
"@types/sanitize-html": "2.13.0",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@types/tar-js": "^0.3.5",
|
||||
"@types/ua-parser-js": "^0.7.36",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||
"@typescript-eslint/parser": "^8.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.19.0",
|
||||
"@typescript-eslint/parser": "^8.19.0",
|
||||
"babel-jest": "^29.0.0",
|
||||
"babel-loader": "^9.0.0",
|
||||
"babel-plugin-jsx-remove-data-test-id": "^3.0.0",
|
||||
|
@ -240,7 +243,6 @@
|
|||
"fetch-mock": "9.11.0",
|
||||
"fetch-mock-jest": "^1.5.1",
|
||||
"file-loader": "^6.0.0",
|
||||
"fs-extra": "^11.0.0",
|
||||
"glob": "^11.0.0",
|
||||
"html-webpack-plugin": "^5.5.3",
|
||||
"husky": "^9.0.0",
|
||||
|
@ -275,11 +277,13 @@
|
|||
"rimraf": "^6.0.0",
|
||||
"semver": "^7.5.2",
|
||||
"source-map-loader": "^5.0.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"stylelint": "^16.1.0",
|
||||
"stylelint-config-standard": "^36.0.0",
|
||||
"stylelint-scss": "^6.0.0",
|
||||
"stylelint-value-no-unknown-custom-properties": "^6.0.1",
|
||||
"terser-webpack-plugin": "^5.3.9",
|
||||
"testcontainers": "^10.16.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"ts-prune": "^0.10.3",
|
||||
"typescript": "5.7.2",
|
||||
|
@ -287,7 +291,7 @@
|
|||
"web-streams-polyfill": "^4.0.0",
|
||||
"webpack": "^5.89.0",
|
||||
"webpack-bundle-analyzer": "^4.8.0",
|
||||
"webpack-cli": "^5.0.0",
|
||||
"webpack-cli": "^6.0.0",
|
||||
"webpack-dev-server": "^5.0.0",
|
||||
"webpack-version-file-plugin": "^0.5.0",
|
||||
"yaml": "^2.3.3"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -13,13 +13,8 @@ Please see LICENSE files in the repository root for full details.
|
|||
import { expect, test } from "../../element-web-test";
|
||||
|
||||
test.use({
|
||||
startHomeserverOpts: "guest-enabled",
|
||||
config: async ({ homeserver }, use) => {
|
||||
await use({
|
||||
default_server_config: {
|
||||
"m.homeserver": { base_url: homeserver.config.baseUrl },
|
||||
},
|
||||
});
|
||||
synapseConfigOptions: {
|
||||
allow_guest_access: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ Copyright 2024 New Vector Ltd.
|
|||
Copyright 2023 Suguru Hirahara
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -253,7 +253,6 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
|||
|
||||
// Find and click "Reply" button
|
||||
const clickButtonReply = async () => {
|
||||
await tile.scrollIntoViewIfNeeded();
|
||||
await tile.hover();
|
||||
await tile.getByRole("button", { name: "Reply", exact: true }).click();
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -79,9 +79,8 @@ test.describe("Composer", () => {
|
|||
// Enter some more text, then send the message
|
||||
await page.getByRole("textbox").pressSequentially("this is the spoiler text ");
|
||||
await page.getByRole("button", { name: "Send message" }).click();
|
||||
// Check that a spoiler item has appeared in the timeline and locator the spoiler command text
|
||||
await expect(page.locator("button.mx_EventTile_spoiler")).toBeVisible();
|
||||
await expect(page.getByText("this is the spoiler text")).toBeVisible();
|
||||
// Check that a spoiler item has appeared in the timeline and contains the spoiler text
|
||||
await expect(page.locator("button.mx_EventTile_spoiler")).toHaveText("this is the spoiler text");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,15 +2,17 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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 { test, expect } from "../../element-web-test";
|
||||
import { test as masTest, registerAccountMas } from "../oidc";
|
||||
import { registerAccountMas } from "../oidc";
|
||||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||
import { TestClientServerAPI } from "../csAPI";
|
||||
import { masHomeserver } from "../../plugins/homeserver/synapse/masHomeserver.ts";
|
||||
|
||||
async function expectBackupVersionToBe(page: Page, version: string) {
|
||||
await expect(page.locator(".mx_SecureBackupPanel_statusList tr:nth-child(5) td")).toHaveText(
|
||||
|
@ -20,22 +22,26 @@ async function expectBackupVersionToBe(page: Page, version: string) {
|
|||
await expect(page.locator(".mx_SecureBackupPanel_statusList tr:nth-child(6) td")).toHaveText(version);
|
||||
}
|
||||
|
||||
masTest.describe("Encryption state after registration", () => {
|
||||
masTest.skip(isDendrite, "does not yet support MAS");
|
||||
// These tests register an account with MAS because then we go through the "normal" registration flow
|
||||
// and crypto gets set up. Using the 'user' fixture create a a user an synthesizes an existing login,
|
||||
// which is faster but leaves us without crypto set up.
|
||||
test.describe("Encryption state after registration", () => {
|
||||
test.use(masHomeserver);
|
||||
test.skip(isDendrite, "does not yet support MAS");
|
||||
|
||||
masTest("Key backup is enabled by default", async ({ page, mailhog, app }) => {
|
||||
test("Key backup is enabled by default", async ({ page, mailhogClient, app }) => {
|
||||
await page.goto("/#/login");
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await registerAccountMas(page, mailhog.api, "alice", "alice@email.com", "Pa$sW0rD!");
|
||||
await registerAccountMas(page, mailhogClient, "alice", "alice@email.com", "Pa$sW0rD!");
|
||||
|
||||
await app.settings.openUserSettings("Security & Privacy");
|
||||
expect(page.getByText("This session is backing up your keys.")).toBeVisible();
|
||||
await expect(page.getByText("This session is backing up your keys.")).toBeVisible();
|
||||
});
|
||||
|
||||
masTest("user is prompted to set up recovery", async ({ page, mailhog, app }) => {
|
||||
test("user is prompted to set up recovery", async ({ page, mailhogClient, app }) => {
|
||||
await page.goto("/#/login");
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await registerAccountMas(page, mailhog.api, "alice", "alice@email.com", "Pa$sW0rD!");
|
||||
await registerAccountMas(page, mailhogClient, "alice", "alice@email.com", "Pa$sW0rD!");
|
||||
|
||||
await page.getByRole("button", { name: "Add room" }).click();
|
||||
await page.getByRole("menuitem", { name: "New room" }).click();
|
||||
|
@ -46,6 +52,55 @@ masTest.describe("Encryption state after registration", () => {
|
|||
});
|
||||
});
|
||||
|
||||
test.describe("Key backup reset from elsewhere", () => {
|
||||
test.use(masHomeserver);
|
||||
test.skip(isDendrite, "does not yet support MAS");
|
||||
|
||||
test("Key backup is disabled when reset from elsewhere", async ({ page, mailhogClient, request, homeserver }) => {
|
||||
const testUsername = "alice";
|
||||
const testPassword = "Pa$sW0rD!";
|
||||
|
||||
// there's a delay before keys are uploaded so the error doesn't appear immediately: use a fake
|
||||
// clock so we can skip the delay
|
||||
await page.clock.install();
|
||||
|
||||
await page.goto("/#/login");
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await registerAccountMas(page, mailhogClient, testUsername, "alice@email.com", testPassword);
|
||||
|
||||
await page.getByRole("button", { name: "Add room" }).click();
|
||||
await page.getByRole("menuitem", { name: "New room" }).click();
|
||||
await page.getByRole("textbox", { name: "Name" }).fill("test room");
|
||||
await page.getByRole("button", { name: "Create room" }).click();
|
||||
|
||||
// @ts-ignore - this runs in the browser scope where mxMatrixClientPeg is a thing. Here, it is not.
|
||||
const accessToken = await page.evaluate(() => mxMatrixClientPeg.get().getAccessToken());
|
||||
|
||||
const csAPI = new TestClientServerAPI(request, homeserver, accessToken);
|
||||
|
||||
const backupInfo = await csAPI.getCurrentBackupInfo();
|
||||
|
||||
await csAPI.deleteBackupVersion(backupInfo.version);
|
||||
|
||||
await page.getByRole("textbox", { name: "Send an encrypted message…" }).fill("/discardsession");
|
||||
await page.getByRole("button", { name: "Send message" }).click();
|
||||
|
||||
await page.getByRole("textbox", { name: "Send an encrypted message…" }).fill("Message with broken key backup");
|
||||
await page.getByRole("button", { name: "Send message" }).click();
|
||||
|
||||
// Should be the message we sent plus the room creation event
|
||||
await expect(page.locator(".mx_EventTile")).toHaveCount(2);
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_MessageList > .mx_EventTile_last .mx_EventTile_receiptSent"),
|
||||
).toBeVisible();
|
||||
|
||||
// Wait for it to try uploading the key
|
||||
await page.clock.fastForward(20000);
|
||||
|
||||
await expect(page.getByRole("heading", { level: 1, name: "New Recovery Method" })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Backups", () => {
|
||||
test.use({
|
||||
displayName: "Hanako",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -19,9 +19,9 @@ test.describe("Complete security", () => {
|
|||
homeserver,
|
||||
credentials,
|
||||
}) => {
|
||||
await logIntoElement(page, homeserver, credentials);
|
||||
await logIntoElement(page, credentials);
|
||||
await expect(page.getByText("Welcome Jeff", { exact: true })).toBeVisible();
|
||||
});
|
||||
|
||||
// see also "Verify device during login with SAS" in `verifiction.spec.ts`.
|
||||
// see also "Verify device during login with SAS" in `verification.spec.ts`.
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -45,7 +45,7 @@ test.describe("Cryptography", function () {
|
|||
await logOutOfElement(page, true);
|
||||
|
||||
// Log in again, and see how the message looks.
|
||||
await logIntoElement(page, homeserver, credentials);
|
||||
await logIntoElement(page, credentials);
|
||||
await app.viewRoomByName("Test room");
|
||||
const lastTile = page.locator(".mx_EventTile").last();
|
||||
await expect(lastTile).toContainText("Historical messages are not available on this device");
|
||||
|
@ -62,7 +62,7 @@ test.describe("Cryptography", function () {
|
|||
|
||||
// Finally, log out again, and back in, skipping verification for now, and see what we see.
|
||||
await logOutOfElement(page);
|
||||
await logIntoElement(page, homeserver, credentials);
|
||||
await logIntoElement(page, credentials);
|
||||
await page.locator(".mx_AuthPage").getByRole("button", { name: "Skip verification for now" }).click();
|
||||
await page.locator(".mx_AuthPage").getByRole("button", { name: "I'll verify later" }).click();
|
||||
await app.viewRoomByName("Test room");
|
||||
|
|
|
@ -2,39 +2,16 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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 { Locator, type Page } from "@playwright/test";
|
||||
|
||||
import { test as base, expect, Fixtures } from "../../element-web-test";
|
||||
import { test, expect } from "../../element-web-test";
|
||||
import { viewRoomSummaryByName } from "../right-panel/utils";
|
||||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||
|
||||
const test = base.extend<Fixtures>({
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
startHomeserverOpts: async ({}, use) => {
|
||||
await use("dehydration");
|
||||
},
|
||||
config: async ({ homeserver, context }, use) => {
|
||||
const wellKnown = {
|
||||
"m.homeserver": {
|
||||
base_url: homeserver.config.baseUrl,
|
||||
},
|
||||
"org.matrix.msc3814": true,
|
||||
};
|
||||
|
||||
await context.route("https://localhost/.well-known/matrix/client", async (route) => {
|
||||
await route.fulfill({ json: wellKnown });
|
||||
});
|
||||
|
||||
await use({
|
||||
default_server_config: wellKnown,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const ROOM_NAME = "Test room";
|
||||
const NAME = "Alice";
|
||||
|
||||
|
@ -47,6 +24,24 @@ test.describe("Dehydration", () => {
|
|||
|
||||
test.use({
|
||||
displayName: NAME,
|
||||
synapseConfigOptions: {
|
||||
experimental_features: {
|
||||
msc2697_enabled: false,
|
||||
msc3814_enabled: true,
|
||||
},
|
||||
},
|
||||
config: async ({ config, context }, use) => {
|
||||
const wellKnown = {
|
||||
...config.default_server_config,
|
||||
"org.matrix.msc3814": true,
|
||||
};
|
||||
|
||||
await context.route("https://localhost/.well-known/matrix/client", async (route) => {
|
||||
await route.fulfill({ json: wellKnown });
|
||||
});
|
||||
|
||||
await use(config);
|
||||
},
|
||||
});
|
||||
|
||||
test("Create dehydrated device", async ({ page, user, app }, workerInfo) => {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -47,7 +47,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
|||
}
|
||||
|
||||
test("Verify device with SAS during login", async ({ page, app, credentials, homeserver }) => {
|
||||
await logIntoElement(page, homeserver, credentials);
|
||||
await logIntoElement(page, credentials);
|
||||
|
||||
// Launch the verification request between alice and the bot
|
||||
const verificationRequest = await initiateAliceVerificationRequest(page);
|
||||
|
@ -74,7 +74,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
|||
|
||||
test("Verify device with QR code during login", async ({ page, app, credentials, homeserver }) => {
|
||||
// A mode 0x02 verification: "self-verifying in which the current device does not yet trust the master key"
|
||||
await logIntoElement(page, homeserver, credentials);
|
||||
await logIntoElement(page, credentials);
|
||||
|
||||
// Launch the verification request between alice and the bot
|
||||
const verificationRequest = await initiateAliceVerificationRequest(page);
|
||||
|
@ -118,7 +118,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
|||
});
|
||||
|
||||
test("Verify device with Security Phrase during login", async ({ page, app, credentials, homeserver }) => {
|
||||
await logIntoElement(page, homeserver, credentials);
|
||||
await logIntoElement(page, credentials);
|
||||
|
||||
// Select the security phrase
|
||||
await page.locator(".mx_AuthPage").getByRole("button", { name: "Verify with Security Key or Phrase" }).click();
|
||||
|
@ -139,7 +139,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
|||
});
|
||||
|
||||
test("Verify device with Security Key during login", async ({ page, app, credentials, homeserver }) => {
|
||||
await logIntoElement(page, homeserver, credentials);
|
||||
await logIntoElement(page, credentials);
|
||||
|
||||
// Select the security phrase
|
||||
await page.locator(".mx_AuthPage").getByRole("button", { name: "Verify with Security Key or Phrase" }).click();
|
||||
|
@ -162,7 +162,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
|||
});
|
||||
|
||||
test("Handle incoming verification request with SAS", async ({ page, credentials, homeserver, toasts }) => {
|
||||
await logIntoElement(page, homeserver, credentials);
|
||||
await logIntoElement(page, credentials);
|
||||
|
||||
/* Dismiss "Verify this device" */
|
||||
const authPage = page.locator(".mx_AuthPage");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -53,6 +53,8 @@ test.describe("Cryptography", function () {
|
|||
|
||||
// Even though Alice has seen Bob's join event, Bob may not have done so yet. Wait for the sync to arrive.
|
||||
await bob.awaitRoomMembership(testRoomId);
|
||||
|
||||
await app.client.network.setupRoute();
|
||||
});
|
||||
|
||||
test("should show the correct shield on e2e events", async ({
|
||||
|
@ -205,7 +207,7 @@ test.describe("Cryptography", function () {
|
|||
window.localStorage.clear();
|
||||
});
|
||||
await page.reload();
|
||||
await logIntoElement(page, homeserver, aliceCredentials, securityKey);
|
||||
await logIntoElement(page, aliceCredentials, securityKey);
|
||||
|
||||
/* go back to the test room and find Bob's message again */
|
||||
await app.viewRoomById(testRoomId);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -11,7 +11,7 @@ import { createRoom, enableKeyBackup, logIntoElement, sendMessageInCurrentRoom }
|
|||
|
||||
test.describe("Logout tests", () => {
|
||||
test.beforeEach(async ({ page, homeserver, credentials }) => {
|
||||
await logIntoElement(page, homeserver, credentials);
|
||||
await logIntoElement(page, credentials);
|
||||
});
|
||||
|
||||
test("Ask to set up recovery on logout if not setup", async ({ page, app }) => {
|
||||
|
|
|
@ -2,31 +2,31 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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 path from "path";
|
||||
import { readFile } from "node:fs/promises";
|
||||
|
||||
import { expect, Fixtures, test as base } from "../../element-web-test";
|
||||
|
||||
const test = base.extend<Fixtures>({
|
||||
// Replace the `user` fixture with one which populates the indexeddb data before starting the app.
|
||||
user: async ({ context, pageWithCredentials: page, credentials }, use) => {
|
||||
await page.route(`/test_indexeddb_cryptostore_dump/*`, async (route, request) => {
|
||||
const resourcePath = path.join(__dirname, new URL(request.url()).pathname);
|
||||
const body = await readFile(resourcePath, { encoding: "utf-8" });
|
||||
await route.fulfill({ body });
|
||||
});
|
||||
await page.goto("/test_indexeddb_cryptostore_dump/index.html");
|
||||
|
||||
await use(credentials);
|
||||
},
|
||||
});
|
||||
import { expect, test } from "../../element-web-test";
|
||||
|
||||
test.describe("migration", { tag: "@no-webkit" }, function () {
|
||||
test.use({ displayName: "Alice" });
|
||||
test.use({
|
||||
displayName: "Alice",
|
||||
|
||||
// Replace the `user` fixture with one which populates the indexeddb data before starting the app.
|
||||
user: async ({ context, pageWithCredentials: page, credentials }, use) => {
|
||||
await page.route(`/test_indexeddb_cryptostore_dump/*`, async (route, request) => {
|
||||
const resourcePath = path.join(__dirname, new URL(request.url()).pathname);
|
||||
const body = await readFile(resourcePath, { encoding: "utf-8" });
|
||||
await route.fulfill({ body });
|
||||
});
|
||||
await page.goto("/test_indexeddb_cryptostore_dump/index.html");
|
||||
|
||||
await use(credentials);
|
||||
},
|
||||
});
|
||||
|
||||
test("Should support migration from legacy crypto", async ({ context, user, page }, workerInfo) => {
|
||||
test.slow();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -180,22 +180,9 @@ export async function checkDeviceIsConnectedKeyBackup(
|
|||
*
|
||||
* If a `securityKey` is given, verifies the new device using the key.
|
||||
*/
|
||||
export async function logIntoElement(
|
||||
page: Page,
|
||||
homeserver: HomeserverInstance,
|
||||
credentials: Credentials,
|
||||
securityKey?: string,
|
||||
) {
|
||||
export async function logIntoElement(page: Page, credentials: Credentials, securityKey?: string) {
|
||||
await page.goto("/#/login");
|
||||
|
||||
// select homeserver
|
||||
await page.getByRole("button", { name: "Edit" }).click();
|
||||
await page.getByRole("textbox", { name: "Other homeserver" }).fill(homeserver.config.baseUrl);
|
||||
await page.getByRole("button", { name: "Continue", exact: true }).click();
|
||||
|
||||
// wait for the dialog to go away
|
||||
await expect(page.locator(".mx_ServerPickerDialog")).not.toBeVisible();
|
||||
|
||||
await page.getByRole("textbox", { name: "Username" }).fill(credentials.userId);
|
||||
await page.getByPlaceholder("Password").fill(credentials.password);
|
||||
await page.getByRole("button", { name: "Sign in" }).click();
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { APIRequestContext } from "playwright-core";
|
||||
import { KeyBackupInfo } from "matrix-js-sdk/src/crypto-api";
|
||||
|
||||
import { HomeserverInstance } from "../plugins/homeserver";
|
||||
|
||||
/**
|
||||
* A small subset of the Client-Server API used to manipulate the state of the
|
||||
* account on the homeserver independently of the client under test.
|
||||
*/
|
||||
export class TestClientServerAPI {
|
||||
public constructor(
|
||||
private request: APIRequestContext,
|
||||
private homeserver: HomeserverInstance,
|
||||
private accessToken: string,
|
||||
) {}
|
||||
|
||||
public async getCurrentBackupInfo(): Promise<KeyBackupInfo | null> {
|
||||
const res = await this.request.get(`${this.homeserver.baseUrl}/_matrix/client/v3/room_keys/version`, {
|
||||
headers: { Authorization: `Bearer ${this.accessToken}` },
|
||||
});
|
||||
|
||||
return await res.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the API directly to delete the given backup version
|
||||
* @param version The version to delete
|
||||
*/
|
||||
public async deleteBackupVersion(version: string): Promise<void> {
|
||||
const res = await this.request.delete(
|
||||
`${this.homeserver.baseUrl}/_matrix/client/v3/room_keys/version/${version}`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${this.accessToken}` },
|
||||
},
|
||||
);
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`Failed to delete backup version: ${res.status}`);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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 { selectHomeserver } from "../utils";
|
||||
import { emailHomeserver } from "../../plugins/homeserver/synapse/emailHomeserver.ts";
|
||||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||
|
||||
const username = "user1234";
|
||||
// this has to be password-like enough to please zxcvbn. Needless to say it's just from pwgen.
|
||||
|
@ -15,15 +17,18 @@ const password = "oETo7MPf0o";
|
|||
const email = "user@nowhere.dummy";
|
||||
|
||||
test.describe("Forgot Password", () => {
|
||||
test.skip(isDendrite, "not yet wired up");
|
||||
test.use(emailHomeserver);
|
||||
test.use({
|
||||
startHomeserverOpts: ({ mailhog }, use) =>
|
||||
use({
|
||||
template: "email",
|
||||
variables: {
|
||||
SMTP_HOST: "host.containers.internal",
|
||||
SMTP_PORT: mailhog.instance.smtpPort,
|
||||
config: {
|
||||
// The only thing that we really *need* (otherwise Element refuses to load) is a default homeserver.
|
||||
// We point that to a guaranteed-invalid domain.
|
||||
default_server_config: {
|
||||
"m.homeserver": {
|
||||
base_url: "https://server.invalid",
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
test("renders properly", { tag: "@screenshot" }, async ({ page, homeserver }) => {
|
||||
|
@ -32,7 +37,7 @@ test.describe("Forgot Password", () => {
|
|||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
|
||||
// need to select a homeserver at this stage, before entering the forgot password flow
|
||||
await selectHomeserver(page, homeserver.config.baseUrl);
|
||||
await selectHomeserver(page, homeserver.baseUrl);
|
||||
|
||||
await page.getByRole("button", { name: "Forgot password?" }).click();
|
||||
|
||||
|
@ -47,7 +52,7 @@ test.describe("Forgot Password", () => {
|
|||
await page.goto("/");
|
||||
|
||||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
await selectHomeserver(page, homeserver.config.baseUrl);
|
||||
await selectHomeserver(page, homeserver.baseUrl);
|
||||
|
||||
await page.getByRole("button", { name: "Forgot password?" }).click();
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ Copyright 2024 New Vector Ltd.
|
|||
Copyright 2023 Suguru Hirahara
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ Copyright 2023 Mikhail Aheichyk
|
|||
Copyright 2023 Nordeck IT + Consulting GmbH.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ Copyright 2023 Mikhail Aheichyk
|
|||
Copyright 2023 Nordeck IT + Consulting GmbH.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -25,12 +25,13 @@ test.describe("Lazy Loading", () => {
|
|||
});
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page, homeserver, user, bot }) => {
|
||||
test.beforeEach(async ({ page, homeserver, user, bot, app }) => {
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
const displayName = `Charly #${i}`;
|
||||
const bot = new Bot(page, homeserver, { displayName, startClient: false, autoAcceptInvites: false });
|
||||
charlies.push(bot);
|
||||
}
|
||||
await app.client.network.setupRoute();
|
||||
});
|
||||
|
||||
const name = "Lazy Loading Test";
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 Suguru Hirahara
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,15 +2,16 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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 { consentHomeserver } from "../../plugins/homeserver/synapse/consentHomeserver.ts";
|
||||
|
||||
test.describe("Consent", () => {
|
||||
test.use(consentHomeserver);
|
||||
test.use({
|
||||
startHomeserverOpts: "consent",
|
||||
displayName: "Bob",
|
||||
});
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -13,6 +13,8 @@ import { doTokenRegistration } from "./utils";
|
|||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||
import { selectHomeserver } from "../utils";
|
||||
import { Credentials, HomeserverInstance } from "../../plugins/homeserver";
|
||||
import { consentHomeserver } from "../../plugins/homeserver/synapse/consentHomeserver.ts";
|
||||
import { legacyOAuthHomeserver } from "../../plugins/homeserver/synapse/legacyOAuthHomeserver.ts";
|
||||
|
||||
const username = "user1234";
|
||||
const password = "p4s5W0rD";
|
||||
|
@ -70,7 +72,7 @@ const DEVICE_SIGNING_KEYS_BODY = {
|
|||
|
||||
async function login(page: Page, homeserver: HomeserverInstance) {
|
||||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
await selectHomeserver(page, homeserver.config.baseUrl);
|
||||
await selectHomeserver(page, homeserver.baseUrl);
|
||||
|
||||
await page.getByRole("textbox", { name: "Username" }).fill(username);
|
||||
await page.getByPlaceholder("Password").fill(password);
|
||||
|
@ -78,8 +80,20 @@ async function login(page: Page, homeserver: HomeserverInstance) {
|
|||
}
|
||||
|
||||
test.describe("Login", () => {
|
||||
test.use({
|
||||
config: {
|
||||
// The only thing that we really *need* (otherwise Element refuses to load) is a default homeserver.
|
||||
// We point that to a guaranteed-invalid domain.
|
||||
default_server_config: {
|
||||
"m.homeserver": {
|
||||
base_url: "https://server.invalid",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
test.describe("Password login", () => {
|
||||
test.use({ startHomeserverOpts: "consent" });
|
||||
test.use(consentHomeserver);
|
||||
|
||||
let creds: Credentials;
|
||||
|
||||
|
@ -101,7 +115,7 @@ test.describe("Login", () => {
|
|||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
|
||||
// first pick the homeserver, as otherwise the user picker won't be visible
|
||||
await selectHomeserver(page, homeserver.config.baseUrl);
|
||||
await selectHomeserver(page, homeserver.baseUrl);
|
||||
|
||||
await page.getByRole("button", { name: "Edit" }).click();
|
||||
|
||||
|
@ -114,7 +128,7 @@ test.describe("Login", () => {
|
|||
await expect(page.locator(".mx_ServerPicker_server")).toHaveText("server.invalid");
|
||||
|
||||
// switch back to the custom homeserver
|
||||
await selectHomeserver(page, homeserver.config.baseUrl);
|
||||
await selectHomeserver(page, homeserver.baseUrl);
|
||||
|
||||
await expect(page.getByRole("textbox", { name: "Username" })).toBeVisible();
|
||||
// Disabled because flaky - see https://github.com/vector-im/element-web/issues/24688
|
||||
|
@ -142,10 +156,10 @@ test.describe("Login", () => {
|
|||
homeserver,
|
||||
request,
|
||||
}) => {
|
||||
const res = await request.post(
|
||||
`${homeserver.config.baseUrl}/_matrix/client/v3/keys/device_signing/upload`,
|
||||
{ headers: { Authorization: `Bearer ${creds.accessToken}` }, data: DEVICE_SIGNING_KEYS_BODY },
|
||||
);
|
||||
const res = await request.post(`${homeserver.baseUrl}/_matrix/client/v3/keys/device_signing/upload`, {
|
||||
headers: { Authorization: `Bearer ${creds.accessToken}` },
|
||||
data: DEVICE_SIGNING_KEYS_BODY,
|
||||
});
|
||||
if (res.status() / 100 !== 2) {
|
||||
console.log("Uploading dummy keys failed", await res.json());
|
||||
}
|
||||
|
@ -172,7 +186,7 @@ test.describe("Login", () => {
|
|||
request,
|
||||
}) => {
|
||||
const res = await request.post(
|
||||
`${homeserver.config.baseUrl}/_matrix/client/v3/keys/device_signing/upload`,
|
||||
`${homeserver.baseUrl}/_matrix/client/v3/keys/device_signing/upload`,
|
||||
{ headers: { Authorization: `Bearer ${creds.accessToken}` }, data: DEVICE_SIGNING_KEYS_BODY },
|
||||
);
|
||||
if (res.status() / 100 !== 2) {
|
||||
|
@ -203,7 +217,7 @@ test.describe("Login", () => {
|
|||
}) => {
|
||||
console.log(`uid ${creds.userId} body`, DEVICE_SIGNING_KEYS_BODY);
|
||||
const res = await request.post(
|
||||
`${homeserver.config.baseUrl}/_matrix/client/v3/keys/device_signing/upload`,
|
||||
`${homeserver.baseUrl}/_matrix/client/v3/keys/device_signing/upload`,
|
||||
{ headers: { Authorization: `Bearer ${creds.accessToken}` }, data: DEVICE_SIGNING_KEYS_BODY },
|
||||
);
|
||||
if (res.status() / 100 !== 2) {
|
||||
|
@ -226,14 +240,7 @@ test.describe("Login", () => {
|
|||
// tests for old-style SSO login, in which we exchange tokens with Synapse, and Synapse talks to an auth server
|
||||
test.describe("SSO login", () => {
|
||||
test.skip(isDendrite, "does not yet support SSO");
|
||||
|
||||
test.use({
|
||||
startHomeserverOpts: ({ oAuthServer }, use) =>
|
||||
use({
|
||||
template: "default",
|
||||
oAuthServerPort: oAuthServer.port,
|
||||
}),
|
||||
});
|
||||
test.use(legacyOAuthHomeserver);
|
||||
|
||||
test("logs in with SSO and lands on the home screen", async ({ page, homeserver }) => {
|
||||
// If this test fails with a screen showing "Timeout connecting to remote server", it is most likely due to
|
||||
|
@ -247,7 +254,7 @@ test.describe("Login", () => {
|
|||
});
|
||||
|
||||
test.describe("logout", () => {
|
||||
test.use({ startHomeserverOpts: "consent" });
|
||||
test.use(consentHomeserver);
|
||||
|
||||
test("should go to login page on logout", async ({ page, user }) => {
|
||||
await page.getByRole("button", { name: "User menu" }).click();
|
||||
|
@ -262,8 +269,8 @@ test.describe("Login", () => {
|
|||
});
|
||||
|
||||
test.describe("logout with logout_redirect_url", () => {
|
||||
test.use(consentHomeserver);
|
||||
test.use({
|
||||
startHomeserverOpts: "consent",
|
||||
config: {
|
||||
// We redirect to decoder-ring because it's a predictable page that isn't Element itself.
|
||||
// We could use example.org, matrix.org, or something else, however this puts dependency of external
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -13,7 +13,7 @@ test.describe("Overwrite login action", () => {
|
|||
// This seems terminally flakey: https://github.com/element-hq/element-web/issues/27363
|
||||
// I tried verious things to try & deflake it, to no avail: https://github.com/matrix-org/matrix-react-sdk/pull/12506
|
||||
test.skip("Try replace existing login with new one", async ({ page, app, credentials, homeserver }) => {
|
||||
await logIntoElement(page, homeserver, credentials);
|
||||
await logIntoElement(page, credentials);
|
||||
|
||||
const userMenu = await app.openUserMenu();
|
||||
await expect(userMenu.getByText(credentials.userId)).toBeVisible();
|
||||
|
@ -24,7 +24,7 @@ test.describe("Overwrite login action", () => {
|
|||
expect(credentials.userId).not.toBe(bobRegister.userId);
|
||||
|
||||
const clientCredentials /* IMatrixClientCreds */ = {
|
||||
homeserverUrl: homeserver.config.baseUrl,
|
||||
homeserverUrl: homeserver.baseUrl,
|
||||
...bobRegister,
|
||||
};
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -11,16 +11,20 @@ import { Page } from "@playwright/test";
|
|||
import { test, expect } from "../../element-web-test";
|
||||
import { doTokenRegistration } from "./utils";
|
||||
import { Credentials } from "../../plugins/homeserver";
|
||||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||
import { legacyOAuthHomeserver } from "../../plugins/homeserver/synapse/legacyOAuthHomeserver.ts";
|
||||
|
||||
test.describe("Soft logout", () => {
|
||||
test.use({
|
||||
displayName: "Alice",
|
||||
startHomeserverOpts: ({ oAuthServer }, use) =>
|
||||
use({
|
||||
template: "default",
|
||||
oAuthServerPort: oAuthServer.port,
|
||||
}),
|
||||
config: {
|
||||
// The only thing that we really *need* (otherwise Element refuses to load) is a default homeserver.
|
||||
// We point that to a guaranteed-invalid domain.
|
||||
default_server_config: {
|
||||
"m.homeserver": {
|
||||
base_url: "https://server.invalid",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
test.describe("with password user", () => {
|
||||
|
@ -32,7 +36,9 @@ test.describe("Soft logout", () => {
|
|||
|
||||
// back to the welcome page
|
||||
await expect(page).toHaveURL(/\/#\/home/);
|
||||
await expect(page.getByRole("heading", { name: `Welcome ${user.userId}`, exact: true })).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("heading", { name: "Now, let's help you get started", exact: true }),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("still shows the soft-logout page when the page is reloaded after a soft-logout", async ({
|
||||
|
@ -47,8 +53,7 @@ test.describe("Soft logout", () => {
|
|||
});
|
||||
|
||||
test.describe("with SSO user", () => {
|
||||
test.skip(isDendrite, "does not yet support SSO");
|
||||
|
||||
test.use(legacyOAuthHomeserver);
|
||||
test.use({
|
||||
user: async ({ page, homeserver }, use) => {
|
||||
const user = await doTokenRegistration(page, homeserver);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -19,7 +19,7 @@ export async function doTokenRegistration(
|
|||
await page.goto("/#/login");
|
||||
|
||||
await page.getByRole("button", { name: "Edit" }).click();
|
||||
await page.getByRole("textbox", { name: "Other homeserver" }).fill(homeserver.config.baseUrl);
|
||||
await page.getByRole("textbox", { name: "Other homeserver" }).fill(homeserver.baseUrl);
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
// wait for the dialog to go away
|
||||
await expect(page.locator(".mx_ServerPickerDialog")).toHaveCount(0);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,68 +2,14 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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 { API, Messages } from "mailhog";
|
||||
import { Page } from "@playwright/test";
|
||||
|
||||
import { test as base, expect } from "../../element-web-test";
|
||||
import { MatrixAuthenticationService } from "../../plugins/matrix-authentication-service";
|
||||
import { StartHomeserverOpts } from "../../plugins/homeserver";
|
||||
|
||||
export const test = base.extend<{
|
||||
masPrepare: MatrixAuthenticationService;
|
||||
mas: MatrixAuthenticationService;
|
||||
}>({
|
||||
// There's a bit of a chicken and egg problem between MAS & Synapse where they each need to know how to reach each other
|
||||
// so spinning up a MAS is split into the prepare & start stage: prepare mas -> homeserver -> start mas to disentangle this.
|
||||
masPrepare: async ({ context }, use) => {
|
||||
const mas = new MatrixAuthenticationService(context);
|
||||
await mas.prepare();
|
||||
await use(mas);
|
||||
},
|
||||
mas: [
|
||||
async ({ masPrepare: mas, homeserver, mailhog }, use, testInfo) => {
|
||||
await mas.start(homeserver, mailhog.instance);
|
||||
await use(mas);
|
||||
await mas.stop(testInfo);
|
||||
},
|
||||
{ auto: true },
|
||||
],
|
||||
startHomeserverOpts: async ({ masPrepare }, use) => {
|
||||
await use({
|
||||
template: "mas-oidc",
|
||||
variables: {
|
||||
MAS_PORT: masPrepare.port,
|
||||
},
|
||||
});
|
||||
},
|
||||
config: async ({ homeserver, startHomeserverOpts, context }, use) => {
|
||||
const issuer = `http://localhost:${(startHomeserverOpts as StartHomeserverOpts).variables["MAS_PORT"]}/`;
|
||||
const wellKnown = {
|
||||
"m.homeserver": {
|
||||
base_url: homeserver.config.baseUrl,
|
||||
},
|
||||
"org.matrix.msc2965.authentication": {
|
||||
issuer,
|
||||
account: `${issuer}account`,
|
||||
},
|
||||
};
|
||||
|
||||
// Ensure org.matrix.msc2965.authentication is in well-known
|
||||
await context.route("https://localhost/.well-known/matrix/client", async (route) => {
|
||||
await route.fulfill({ json: wellKnown });
|
||||
});
|
||||
|
||||
await use({
|
||||
default_server_config: wellKnown,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export { expect };
|
||||
import { expect } from "../../element-web-test";
|
||||
|
||||
export async function registerAccountMas(
|
||||
page: Page,
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { test, expect, registerAccountMas } from ".";
|
||||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||
|
||||
test.describe("OIDC Aware", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
test.skip(isDendrite, "does not yet support MAS");
|
||||
test.slow(); // trace recording takes a while here
|
||||
|
||||
test("can register an account and manage it", async ({ context, page, homeserver, mailhog, app }) => {
|
||||
await page.goto("/#/login");
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await registerAccountMas(page, mailhog.api, "alice", "alice@email.com", "Pa$sW0rD!");
|
||||
|
||||
// Eventually, we should end up at the home screen.
|
||||
await expect(page).toHaveURL(/\/#\/home$/, { timeout: 10000 });
|
||||
await expect(page.getByRole("heading", { name: "Welcome alice", exact: true })).toBeVisible();
|
||||
|
||||
// Open settings and navigate to account management
|
||||
await app.settings.openUserSettings("Account");
|
||||
const newPagePromise = context.waitForEvent("page");
|
||||
await page.getByRole("button", { name: "Manage account" }).click();
|
||||
|
||||
// Assert new tab opened
|
||||
const newPage = await newPagePromise;
|
||||
await expect(newPage.getByText("Primary email")).toBeVisible();
|
||||
});
|
||||
});
|
|
@ -2,31 +2,30 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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, registerAccountMas } from ".";
|
||||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||
import { test, expect } from "../../element-web-test.ts";
|
||||
import { registerAccountMas } from ".";
|
||||
import { ElementAppPage } from "../../pages/ElementAppPage.ts";
|
||||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||
import { masHomeserver } from "../../plugins/homeserver/synapse/masHomeserver.ts";
|
||||
|
||||
test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
test.use(masHomeserver);
|
||||
test.skip(isDendrite, "does not yet support MAS");
|
||||
test.slow(); // trace recording takes a while here
|
||||
|
||||
test.use({
|
||||
labsFlags: ["feature_oidc_native_flow"],
|
||||
});
|
||||
|
||||
test("can register the oauth2 client and an account", async ({ context, page, homeserver, mailhog, mas }) => {
|
||||
const tokenUri = `http://localhost:${mas.port}/oauth2/token`;
|
||||
test("can register the oauth2 client and an account", async ({ context, page, homeserver, mailhogClient, mas }) => {
|
||||
const tokenUri = `${mas.baseUrl}/oauth2/token`;
|
||||
const tokenApiPromise = page.waitForRequest(
|
||||
(request) => request.url() === tokenUri && request.postDataJSON()["grant_type"] === "authorization_code",
|
||||
);
|
||||
|
||||
await page.goto("/#/login");
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await registerAccountMas(page, mailhog.api, "alice", "alice@email.com", "Pa$sW0rD!");
|
||||
await registerAccountMas(page, mailhogClient, "alice", "alice@email.com", "Pa$sW0rD!");
|
||||
|
||||
// Eventually, we should end up at the home screen.
|
||||
await expect(page).toHaveURL(/\/#\/home$/, { timeout: 10000 });
|
||||
|
@ -45,15 +44,15 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
|||
|
||||
// Assert MAS sees the session as OIDC Native
|
||||
const newPage = await newPagePromise;
|
||||
await newPage.getByText("Sessions").click();
|
||||
await newPage.getByText("Devices").click();
|
||||
await newPage.getByText(deviceId).click();
|
||||
await expect(newPage.getByText("Element")).toBeVisible();
|
||||
await expect(newPage.getByText("oauth2_session:")).toBeVisible();
|
||||
await expect(newPage.getByText("http://localhost:8080/")).toBeVisible();
|
||||
await expect(newPage).toHaveURL(/\/oauth2_session/);
|
||||
await newPage.close();
|
||||
|
||||
// Assert logging out revokes both tokens
|
||||
const revokeUri = `http://localhost:${mas.port}/oauth2/revoke`;
|
||||
const revokeUri = `${mas.baseUrl}/oauth2/revoke`;
|
||||
const revokeAccessTokenPromise = page.waitForRequest(
|
||||
(request) => request.url() === revokeUri && request.postDataJSON()["token_type_hint"] === "access_token",
|
||||
);
|
||||
|
|
|
@ -3,7 +3,7 @@ Copyright 2024 New Vector Ltd.
|
|||
Copyright 2023 Ahmad Kadri
|
||||
Copyright 2023 Nordeck IT + Consulting GmbH.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright 2024 New Vector Ltd.
|
||||
* Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
@ -13,6 +13,8 @@ import { Client } from "../../pages/client";
|
|||
import { ElementAppPage } from "../../pages/ElementAppPage";
|
||||
import { Bot } from "../../pages/bot";
|
||||
|
||||
type RoomRef = { name: string; roomId: string };
|
||||
|
||||
/**
|
||||
* Set up for pinned message tests.
|
||||
*/
|
||||
|
@ -47,7 +49,7 @@ export class Helpers {
|
|||
* @param room - the name of the room to send messages into
|
||||
* @param messages - the list of messages to send, these can be strings or implementations of MessageSpec like `editOf`
|
||||
*/
|
||||
async receiveMessages(room: string | { name: string }, messages: string[]) {
|
||||
async receiveMessages(room: RoomRef, messages: string[]) {
|
||||
await this.sendMessageAsClient(this.bot, room, messages);
|
||||
}
|
||||
|
||||
|
@ -55,9 +57,8 @@ export class Helpers {
|
|||
* Use the supplied client to send messages or perform actions as specified by
|
||||
* the supplied {@link Message} items.
|
||||
*/
|
||||
private async sendMessageAsClient(cli: Client, roomName: string | { name: string }, messages: string[]) {
|
||||
const room = await this.findRoomByName(typeof roomName === "string" ? roomName : roomName.name);
|
||||
const roomId = await room.evaluate((room) => room.roomId);
|
||||
private async sendMessageAsClient(cli: Client, room: RoomRef, messages: string[]) {
|
||||
const roomId = room.roomId;
|
||||
|
||||
for (const message of messages) {
|
||||
await cli.sendMessage(roomId, { body: message, msgtype: "m.text" });
|
||||
|
@ -73,22 +74,11 @@ export class Helpers {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a room by its name
|
||||
* @param roomName
|
||||
* @private
|
||||
*/
|
||||
private async findRoomByName(roomName: string) {
|
||||
return this.app.client.evaluateHandle((cli, roomName) => {
|
||||
return cli.getRooms().find((r) => r.name === roomName);
|
||||
}, roomName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the room with the supplied name.
|
||||
*/
|
||||
async goTo(room: string | { name: string }) {
|
||||
await this.app.viewRoomByName(typeof room === "string" ? room : room.name);
|
||||
async goTo(room: RoomRef) {
|
||||
await this.app.viewRoomByName(room.name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright 2024 New Vector Ltd.
|
||||
* Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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";
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -11,6 +11,8 @@ Please see LICENSE files in the repository root for full details.
|
|||
import { customEvent, many, test } from ".";
|
||||
|
||||
test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
||||
test.slow();
|
||||
|
||||
test.describe("Ignored events", () => {
|
||||
test("If all events after receipt are unimportant, the room is read", async ({
|
||||
roomAlpha: room1,
|
||||
|
@ -120,7 +122,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
|||
await util.assertUnread(room2, 40);
|
||||
|
||||
// When I jump to a message in the middle and page up
|
||||
await msg.jumpTo(room2.name, "x\ny\nz\nMsg0020");
|
||||
await msg.jumpTo(room2, "x\ny\nz\nMsg0020");
|
||||
await util.pageUp();
|
||||
|
||||
// Then the room is still unread
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -13,6 +13,8 @@ import { Bot } from "../../pages/bot";
|
|||
import { Client } from "../../pages/client";
|
||||
import { ElementAppPage } from "../../pages/ElementAppPage";
|
||||
|
||||
type RoomRef = { name: string; roomId: string };
|
||||
|
||||
/**
|
||||
* Set up for a read receipt test:
|
||||
* - Create a user with the supplied name
|
||||
|
@ -22,9 +24,9 @@ import { ElementAppPage } from "../../pages/ElementAppPage";
|
|||
*/
|
||||
export const test = base.extend<{
|
||||
roomAlphaName?: string;
|
||||
roomAlpha: { name: string; roomId: string };
|
||||
roomAlpha: RoomRef;
|
||||
roomBetaName?: string;
|
||||
roomBeta: { name: string; roomId: string };
|
||||
roomBeta: RoomRef;
|
||||
msg: MessageBuilder;
|
||||
util: Helpers;
|
||||
}>({
|
||||
|
@ -248,12 +250,13 @@ export class MessageBuilder {
|
|||
/**
|
||||
* Find and display a message.
|
||||
*
|
||||
* @param roomName the name of the room to look inside
|
||||
* @param roomRef the ref of the room to look inside
|
||||
* @param message the content of the message to fine
|
||||
* @param includeThreads look for messages inside threads, not just the main timeline
|
||||
*/
|
||||
async jumpTo(roomName: string, message: string, includeThreads = false) {
|
||||
const room = await this.helpers.findRoomByName(roomName);
|
||||
async jumpTo(roomRef: RoomRef, message: string, includeThreads = false) {
|
||||
const room = await this.helpers.findRoomById(roomRef.roomId);
|
||||
expect(room).toBeTruthy();
|
||||
const foundMessage = await this.getMessage(room, message, includeThreads);
|
||||
const roomId = await room.evaluate((room) => room.roomId);
|
||||
const foundMessageId = await foundMessage.evaluate((ev) => ev.getId());
|
||||
|
@ -333,9 +336,10 @@ class Helpers {
|
|||
* Use the supplied client to send messages or perform actions as specified by
|
||||
* the supplied {@link Message} items.
|
||||
*/
|
||||
async sendMessageAsClient(cli: Client, roomName: string | { name: string }, messages: Message[]) {
|
||||
const room = await this.findRoomByName(typeof roomName === "string" ? roomName : roomName.name);
|
||||
const roomId = await room.evaluate((room) => room.roomId);
|
||||
async sendMessageAsClient(cli: Client, roomRef: RoomRef, messages: Message[]) {
|
||||
const roomId = roomRef.roomId;
|
||||
const room = await this.findRoomById(roomId);
|
||||
expect(room).toBeTruthy();
|
||||
|
||||
for (const message of messages) {
|
||||
if (typeof message === "string") {
|
||||
|
@ -359,7 +363,7 @@ class Helpers {
|
|||
/**
|
||||
* Open the room with the supplied name.
|
||||
*/
|
||||
async goTo(room: string | { name: string }) {
|
||||
async goTo(room: RoomRef) {
|
||||
await this.app.viewRoomByName(typeof room === "string" ? room : room.name);
|
||||
}
|
||||
|
||||
|
@ -423,17 +427,16 @@ class Helpers {
|
|||
});
|
||||
}
|
||||
|
||||
getRoomListTile(room: string | { name: string }) {
|
||||
const roomName = typeof room === "string" ? room : room.name;
|
||||
return this.page.getByRole("treeitem", { name: new RegExp("^" + roomName) });
|
||||
getRoomListTile(label: string) {
|
||||
return this.page.getByRole("treeitem", { name: new RegExp("^" + label) });
|
||||
}
|
||||
|
||||
/**
|
||||
* Click the "Mark as Read" context menu item on the room with the supplied name
|
||||
* in the room list.
|
||||
*/
|
||||
async markAsRead(room: string | { name: string }) {
|
||||
await this.getRoomListTile(room).click({ button: "right" });
|
||||
async markAsRead(room: RoomRef) {
|
||||
await this.getRoomListTile(room.name).click({ button: "right" });
|
||||
await this.page.getByText("Mark as read").click();
|
||||
}
|
||||
|
||||
|
@ -441,8 +444,8 @@ class Helpers {
|
|||
* Assert that the room with the supplied name is "read" in the room list - i.g.
|
||||
* has not dot or count of unread messages.
|
||||
*/
|
||||
async assertRead(room: string | { name: string }) {
|
||||
const tile = this.getRoomListTile(room);
|
||||
async assertRead(room: RoomRef) {
|
||||
const tile = this.getRoomListTile(room.name);
|
||||
await expect(tile.locator(".mx_NotificationBadge_dot")).not.toBeVisible();
|
||||
await expect(tile.locator(".mx_NotificationBadge_count")).not.toBeVisible();
|
||||
}
|
||||
|
@ -452,7 +455,7 @@ class Helpers {
|
|||
* (In practice, this just waits a short while to allow any unread marker to
|
||||
* appear, and then asserts that the room is read.)
|
||||
*/
|
||||
async assertStillRead(room: string | { name: string }) {
|
||||
async assertStillRead(room: RoomRef) {
|
||||
await this.page.waitForTimeout(200);
|
||||
await this.assertRead(room);
|
||||
}
|
||||
|
@ -462,8 +465,8 @@ class Helpers {
|
|||
* @param room - the name of the room to check
|
||||
* @param count - the numeric count to assert, or if "." specified then a bold/dot (no count) state is asserted
|
||||
*/
|
||||
async assertUnread(room: string | { name: string }, count: number | ".") {
|
||||
const tile = this.getRoomListTile(room);
|
||||
async assertUnread(room: RoomRef, count: number | ".") {
|
||||
const tile = this.getRoomListTile(room.name);
|
||||
if (count === ".") {
|
||||
await expect(tile.locator(".mx_NotificationBadge_dot")).toBeVisible();
|
||||
} else {
|
||||
|
@ -478,8 +481,8 @@ class Helpers {
|
|||
* @param room - the name of the room to check
|
||||
* @param lessThan - the number of unread messages that is too many
|
||||
*/
|
||||
async assertUnreadLessThan(room: string | { name: string }, lessThan: number) {
|
||||
const tile = this.getRoomListTile(room);
|
||||
async assertUnreadLessThan(room: RoomRef, lessThan: number) {
|
||||
const tile = this.getRoomListTile(room.name);
|
||||
// https://playwright.dev/docs/test-assertions#expectpoll
|
||||
// .toBeLessThan doesn't have a retry mechanism, so we use .poll
|
||||
await expect
|
||||
|
@ -496,8 +499,8 @@ class Helpers {
|
|||
* @param room - the name of the room to check
|
||||
* @param greaterThan - the number of unread messages that is too few
|
||||
*/
|
||||
async assertUnreadGreaterThan(room: string | { name: string }, greaterThan: number) {
|
||||
const tile = this.getRoomListTile(room);
|
||||
async assertUnreadGreaterThan(room: RoomRef, greaterThan: number) {
|
||||
const tile = this.getRoomListTile(room.name);
|
||||
// https://playwright.dev/docs/test-assertions#expectpoll
|
||||
// .toBeGreaterThan doesn't have a retry mechanism, so we use .poll
|
||||
await expect
|
||||
|
@ -531,10 +534,10 @@ class Helpers {
|
|||
});
|
||||
}
|
||||
|
||||
async findRoomByName(roomName: string): Promise<JSHandle<Room>> {
|
||||
return this.app.client.evaluateHandle((cli, roomName) => {
|
||||
return cli.getRooms().find((r) => r.name === roomName);
|
||||
}, roomName);
|
||||
async findRoomById(roomId: string): Promise<JSHandle<Room>> {
|
||||
return this.app.client.evaluateHandle((cli, roomId) => {
|
||||
return cli.getRooms().find((r) => r.roomId === roomId);
|
||||
}, roomId);
|
||||
}
|
||||
|
||||
private async getThreadListTile(rootMessage: string) {
|
||||
|
@ -578,7 +581,7 @@ class Helpers {
|
|||
* @param room - the name of the room to send messages into
|
||||
* @param messages - the list of messages to send, these can be strings or implementations of MessageSpec like `editOf`
|
||||
*/
|
||||
async receiveMessages(room: string | { name: string }, messages: Message[]) {
|
||||
async receiveMessages(room: RoomRef, messages: Message[]) {
|
||||
await this.sendMessageAsClient(this.bot, room, messages);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -101,7 +101,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
|||
await util.goTo(room1);
|
||||
|
||||
// When I read an older message in the thread
|
||||
await msg.jumpTo(room2.name, "InThread0000", true);
|
||||
await msg.jumpTo(room2, "InThread0000", true);
|
||||
|
||||
// Then the thread is still marked as unread
|
||||
await util.backToThreadsList();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -59,7 +59,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
|||
await util.assertUnread(room2, 30);
|
||||
|
||||
// When I jump to one of the older messages
|
||||
await msg.jumpTo(room2.name, "Msg0001");
|
||||
await msg.jumpTo(room2, "Msg0001");
|
||||
|
||||
// Then the room is still unread, but some messages were read
|
||||
await util.assertUnreadLessThan(room2, 30);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -49,7 +49,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
|||
await util.assertUnread(room2, 61); // Sanity
|
||||
|
||||
// When I jump to an old message and read the thread
|
||||
await msg.jumpTo(room2.name, "beforeThread0000");
|
||||
await msg.jumpTo(room2, "beforeThread0000");
|
||||
// When the thread is opened, the timeline is scrolled until the thread root reached the center
|
||||
await util.openThread("ThreadRoot");
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
@ -196,7 +196,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
|||
await sendThreadedReadReceipt(app, thread1a, main1);
|
||||
|
||||
// Then the room has only one unread - the one in the thread
|
||||
await util.goTo(otherRoomName);
|
||||
await util.goTo({ name: otherRoomName, roomId: otherRoomId });
|
||||
await util.assertUnreadThread("Message 1");
|
||||
});
|
||||
|
||||
|
@ -214,7 +214,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
|||
|
||||
// Then the room has no unreads
|
||||
await expect(page.getByLabel(`${otherRoomName}`)).toBeVisible();
|
||||
await util.goTo(otherRoomName);
|
||||
await util.goTo({ name: otherRoomName, roomId: otherRoomId });
|
||||
await util.assertReadThread("Message 1");
|
||||
});
|
||||
|
||||
|
@ -239,7 +239,7 @@ test.describe("Read receipts", { tag: "@mergequeue" }, () => {
|
|||
// receipt is for a later event. The room should therefore be
|
||||
// read, and the thread unread.
|
||||
await expect(page.getByLabel(`${otherRoomName}`)).toBeVisible();
|
||||
await util.goTo(otherRoomName);
|
||||
await util.goTo({ name: otherRoomName, roomId: otherRoomId });
|
||||
await util.assertUnreadThread("Message 1");
|
||||
});
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,31 +2,23 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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 { emailHomeserver } from "../../plugins/homeserver/synapse/emailHomeserver.ts";
|
||||
import { isDendrite } from "../../plugins/homeserver/dendrite";
|
||||
|
||||
test.describe("Email Registration", async () => {
|
||||
test.skip(isDendrite, "not yet wired up");
|
||||
|
||||
test.use(emailHomeserver);
|
||||
test.use({
|
||||
startHomeserverOpts: ({ mailhog }, use) =>
|
||||
use({
|
||||
template: "email",
|
||||
variables: {
|
||||
SMTP_HOST: "host.containers.internal",
|
||||
SMTP_PORT: mailhog.instance.smtpPort,
|
||||
},
|
||||
}),
|
||||
config: ({ homeserver }, use) =>
|
||||
config: ({ config }, use) =>
|
||||
use({
|
||||
...config,
|
||||
default_server_config: {
|
||||
"m.homeserver": {
|
||||
base_url: homeserver.config.baseUrl,
|
||||
},
|
||||
...config.default_server_config,
|
||||
"m.identity_server": {
|
||||
base_url: "https://server.invalid",
|
||||
},
|
||||
|
@ -34,14 +26,14 @@ test.describe("Email Registration", async () => {
|
|||
}),
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.beforeEach(async ({ homeserver, page }) => {
|
||||
await page.goto("/#/register");
|
||||
});
|
||||
|
||||
test(
|
||||
"registers an account and lands on the use case selection screen",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, mailhog, request, checkA11y }) => {
|
||||
async ({ page, mailhogClient, request, checkA11y }) => {
|
||||
await expect(page.getByRole("textbox", { name: "Username" })).toBeVisible();
|
||||
// Hide the server text as it contains the randomly allocated Homeserver port
|
||||
const screenshotOptions = { mask: [page.locator(".mx_ServerPicker_server")] };
|
||||
|
@ -58,7 +50,7 @@ test.describe("Email Registration", async () => {
|
|||
|
||||
await expect(page.getByText("An error was encountered when sending the email")).not.toBeVisible();
|
||||
|
||||
const messages = await mailhog.api.messages();
|
||||
const messages = await mailhogClient.messages();
|
||||
expect(messages.items).toHaveLength(1);
|
||||
expect(messages.items[0].to).toEqual("alice@email.com");
|
||||
const [emailLink] = messages.items[0].text.match(/http.+/);
|
||||
|
|
|
@ -2,15 +2,25 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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 { consentHomeserver } from "../../plugins/homeserver/synapse/consentHomeserver.ts";
|
||||
|
||||
test.describe("Registration", () => {
|
||||
test.use(consentHomeserver);
|
||||
test.use({
|
||||
startHomeserverOpts: "consent",
|
||||
config: {
|
||||
// The only thing that we really *need* (otherwise Element refuses to load) is a default homeserver.
|
||||
// We point that to a guaranteed-invalid domain.
|
||||
default_server_config: {
|
||||
"m.homeserver": {
|
||||
base_url: "https://server.invalid",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
|
@ -27,7 +37,7 @@ test.describe("Registration", () => {
|
|||
await expect(page.locator(".mx_Dialog")).toMatchScreenshot("server-picker.png");
|
||||
await checkA11y();
|
||||
|
||||
await page.getByRole("textbox", { name: "Other homeserver" }).fill(homeserver.config.baseUrl);
|
||||
await page.getByRole("textbox", { name: "Other homeserver" }).fill(homeserver.baseUrl);
|
||||
await page.getByRole("button", { name: "Continue", exact: true }).click();
|
||||
// wait for the dialog to go away
|
||||
await expect(page.getByRole("dialog")).not.toBeVisible();
|
||||
|
@ -88,7 +98,7 @@ test.describe("Registration", () => {
|
|||
test("should require username to fulfil requirements and be available", async ({ homeserver, page }) => {
|
||||
await page.getByRole("button", { name: "Edit", exact: true }).click();
|
||||
await expect(page.getByRole("button", { name: "Continue", exact: true })).toBeVisible();
|
||||
await page.getByRole("textbox", { name: "Other homeserver" }).fill(homeserver.config.baseUrl);
|
||||
await page.getByRole("textbox", { name: "Other homeserver" }).fill(homeserver.baseUrl);
|
||||
await page.getByRole("button", { name: "Continue", exact: true }).click();
|
||||
// wait for the dialog to go away
|
||||
await expect(page.getByRole("dialog")).not.toBeVisible();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue