mirror of
https://github.com/vector-im/element-call.git
synced 2026-03-07 05:47:03 +00:00
Merge branch 'livekit' into robin/berry
This commit is contained in:
35
.github/workflows/playwright.yml
vendored
Normal file
35
.github/workflows/playwright.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Playwright Tests
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
branches: [livekit, full-mesh]
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 10
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version-file: ".node-version"
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Install Playwright Browsers
|
||||
run: yarn playwright install --with-deps
|
||||
- name: Run backend components
|
||||
run: |
|
||||
docker compose -f dev-backend-docker-compose.yml up -d
|
||||
docker ps
|
||||
- name: Copy config file
|
||||
run: cp config/config.devenv.json public/config.json
|
||||
- name: Run Playwright tests
|
||||
run: yarn playwright test
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 3
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -9,6 +9,8 @@ dist-ssr
|
||||
public/config.json
|
||||
backend/synapse_tmp/*
|
||||
/coverage
|
||||
|
||||
# Yarn
|
||||
yarn-error.log
|
||||
/.pnp.*
|
||||
/.yarn/*
|
||||
@@ -18,3 +20,9 @@ yarn-error.log
|
||||
!/.yarn/sdks
|
||||
!/.yarn/versions
|
||||
/.links.yaml
|
||||
|
||||
# Playwright
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
|
||||
58
README.md
58
README.md
@@ -190,6 +190,64 @@ yarn backend
|
||||
# podman-compose -f dev-backend-docker-compose.yml up
|
||||
```
|
||||
|
||||
### Playwright tests
|
||||
|
||||
Our Playwright tests run automatically as part of our CI along with our other tests,
|
||||
on every pull request.
|
||||
|
||||
You may need to follow instructions to set up your development environment for running
|
||||
Playwright by following <https://playwright.dev/docs/browsers#install-browsers> and
|
||||
<https://playwright.dev/docs/browsers#install-system-dependencies>.
|
||||
|
||||
However the Playwright tests are run, an element-call instance must be running on
|
||||
https://localhost:3000 (this is configured in `playwright.config.ts`) - this is what will
|
||||
be tested.
|
||||
|
||||
The local backend environment should be running for the test to work:
|
||||
`yarn backend`
|
||||
|
||||
There are a few different ways to run the tests yourself. The simplest is to run:
|
||||
|
||||
```shell
|
||||
yarn run test:playwright
|
||||
```
|
||||
|
||||
This will run the Playwright tests once, non-interactively.
|
||||
|
||||
There is a more user-friendly way to run the tests in interactive mode:
|
||||
|
||||
```shell
|
||||
yarn run test:playwright:open
|
||||
```
|
||||
|
||||
The easiest way to develop new test is to use the codegen feature of Playwright:
|
||||
|
||||
```shell
|
||||
npx playwright codegen
|
||||
```
|
||||
|
||||
This will record your action and write the test code for you. Use the tool bar to test visibility, text content,
|
||||
clicking.
|
||||
|
||||
##### Investigate a failed test from the CI
|
||||
|
||||
In the failed action page, click on the failed job, then scroll down to the `upload-artifact` step.
|
||||
You will find a link to download the zip report, as per:
|
||||
|
||||
```
|
||||
Artifact playwright-report has been successfully uploaded! Final size is 1360358 bytes. Artifact ID is 2746265841
|
||||
Artifact download URL: https://github.com/element-hq/element-call/actions/runs/13837660687/artifacts/2746265841
|
||||
```
|
||||
|
||||
Unzip the report then use this command to open the report in your browser:
|
||||
|
||||
```shell
|
||||
npx playwright show-report ~/Downloads/playwright-report/
|
||||
```
|
||||
|
||||
Under the failed test there is a small icon looking like "3 columns" (next to test name file name),
|
||||
click on it to see the live screenshots/console output.
|
||||
|
||||
### Test Coverage
|
||||
|
||||
<img src="https://codecov.io/github/element-hq/element-call/graphs/tree.svg?token=O6CFVKK6I1"></img>
|
||||
|
||||
@@ -46,10 +46,15 @@ experimental_features:
|
||||
max_event_delay_duration: 24h
|
||||
|
||||
rc_message:
|
||||
# This needs to match at least the heart-beat frequency plus a bit of headroom
|
||||
# Currently the heart-beat is every 5 seconds which translates into a rate of 0.2s
|
||||
# This needs to match at least e2ee key sharing frequency plus a bit of headroom
|
||||
# Note key sharing events are bursty
|
||||
per_second: 0.5
|
||||
burst_count: 30
|
||||
# This needs to match at least the heart-beat frequency plus a bit of headroom
|
||||
# Currently the heart-beat is every 5 seconds which translates into a rate of 0.2s
|
||||
rc_delayed_event_mgmt:
|
||||
per_second: 1
|
||||
burst_count: 20
|
||||
```
|
||||
|
||||
### MatrixRTC Backend
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
"i18n:check": "i18next --fail-on-warnings --fail-on-update",
|
||||
"test": "vitest",
|
||||
"test:coverage": "vitest --coverage",
|
||||
"backend": "docker-compose -f dev-backend-docker-compose.yml up"
|
||||
"backend": "docker-compose -f dev-backend-docker-compose.yml up",
|
||||
"test:playwright": "playwright test",
|
||||
"test:playwright:open": "yarn test:playwright --ui"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.16.5",
|
||||
@@ -43,6 +45,7 @@
|
||||
"@opentelemetry/sdk-trace-base": "^1.25.1",
|
||||
"@opentelemetry/sdk-trace-web": "^1.9.1",
|
||||
"@opentelemetry/semantic-conventions": "^1.25.1",
|
||||
"@playwright/test": "^1.51.0",
|
||||
"@radix-ui/react-dialog": "^1.0.4",
|
||||
"@radix-ui/react-slider": "^1.1.2",
|
||||
"@radix-ui/react-visually-hidden": "^1.0.3",
|
||||
|
||||
76
playwright.config.ts
Normal file
76
playwright.config.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { defineConfig, devices } from "@playwright/test";
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: "./playwright",
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: "html",
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: "https://localhost:3000",
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
},
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
use: {
|
||||
...devices["Desktop Chrome"],
|
||||
permissions: ["microphone", "camera"],
|
||||
ignoreHTTPSErrors: true,
|
||||
launchOptions: {
|
||||
args: [
|
||||
"--use-fake-ui-for-media-stream",
|
||||
"--use-fake-device-for-media-stream",
|
||||
"--mute-audio",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "firefox",
|
||||
use: {
|
||||
...devices["Desktop Firefox"],
|
||||
ignoreHTTPSErrors: true,
|
||||
launchOptions: {
|
||||
firefoxUserPrefs: {
|
||||
"permissions.default.microphone": 1,
|
||||
"permissions.default.camera": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// No safari for now, until I find a solution to fix `Not allowed to request resource` due to calling
|
||||
// clear http to the homeserver
|
||||
],
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: {
|
||||
command: "yarn dev",
|
||||
url: "https://localhost:3000",
|
||||
reuseExistingServer: !process.env.CI,
|
||||
ignoreHTTPSErrors: true,
|
||||
},
|
||||
});
|
||||
55
playwright/create-call.spec.ts
Normal file
55
playwright/create-call.spec.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
test("Start a new call then leave and show the feedback screen", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/");
|
||||
|
||||
await page.getByTestId("home_callName").click();
|
||||
await page.getByTestId("home_callName").fill("HelloCall");
|
||||
await page.getByTestId("home_displayName").click();
|
||||
await page.getByTestId("home_displayName").fill("John Doe");
|
||||
await page.getByTestId("home_go").click();
|
||||
|
||||
await expect(page.locator("video")).toBeVisible();
|
||||
await expect(page.getByTestId("lobby_joinCall")).toBeVisible();
|
||||
|
||||
// Check the button toolbar
|
||||
// await expect(page.getByRole('button', { name: 'Mute microphone' })).toBeVisible();
|
||||
// await expect(page.getByRole('button', { name: 'Stop video' })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "Settings" })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "End call" })).toBeVisible();
|
||||
|
||||
// Join the call
|
||||
await page.getByTestId("lobby_joinCall").click();
|
||||
|
||||
// Ensure that the call is connected
|
||||
await page
|
||||
.locator("div")
|
||||
.filter({ hasText: /^HelloCall$/ })
|
||||
.click();
|
||||
// Check the number of participants
|
||||
await expect(page.locator("div").filter({ hasText: /^1$/ })).toBeVisible();
|
||||
// The tooltip with the name should be visible
|
||||
await expect(page.getByTestId("name_tag")).toContainText("John Doe");
|
||||
|
||||
// leave the call
|
||||
await page.getByTestId("incall_leave").click();
|
||||
await expect(page.getByRole("heading")).toContainText(
|
||||
"John Doe, your call has ended. How did it go?",
|
||||
);
|
||||
await expect(page.getByRole("main")).toContainText(
|
||||
"Why not finish by setting up a password to keep your account?",
|
||||
);
|
||||
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Not now, return to home screen" }),
|
||||
).toBeVisible();
|
||||
});
|
||||
30
playwright/landing.spec.ts
Normal file
30
playwright/landing.spec.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { test, expect } from "@playwright/test";
|
||||
|
||||
test("has title", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
|
||||
await expect(page).toHaveTitle(/Element Call/);
|
||||
});
|
||||
|
||||
test("Landing page", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
|
||||
// There should be a login button in the header
|
||||
await expect(page.getByRole("link", { name: "Log In" })).toBeVisible();
|
||||
|
||||
await expect(
|
||||
page.getByRole("heading", { name: "Start new call" }),
|
||||
).toBeVisible();
|
||||
|
||||
await expect(page.getByTestId("home_callName")).toBeVisible();
|
||||
await expect(page.getByTestId("home_displayName")).toBeVisible();
|
||||
|
||||
await expect(page.getByTestId("home_go")).toBeVisible();
|
||||
});
|
||||
@@ -13,6 +13,7 @@ export default defineConfig((configEnv) =>
|
||||
},
|
||||
},
|
||||
setupFiles: ["src/vitest.setup.ts"],
|
||||
include: ["src/**/*.test.ts", "src/**/*.test.tsx"],
|
||||
coverage: {
|
||||
reporter: ["html", "json"],
|
||||
include: ["src/"],
|
||||
@@ -21,6 +22,7 @@ export default defineConfig((configEnv) =>
|
||||
"src/utils/test.ts",
|
||||
"src/utils/test-viewmodel.ts",
|
||||
"src/utils/test-fixtures.ts",
|
||||
"playwright/**",
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
55
yarn.lock
55
yarn.lock
@@ -3054,6 +3054,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@playwright/test@npm:^1.51.0":
|
||||
version: 1.51.0
|
||||
resolution: "@playwright/test@npm:1.51.0"
|
||||
dependencies:
|
||||
playwright: "npm:1.51.0"
|
||||
bin:
|
||||
playwright: cli.js
|
||||
checksum: 10c0/ae83dd2c3a32133de58f44a9dbcd73a8059155ebd8acc736ba8bd0a7ca99b194afe2e8f5a500861d18b1c8f06b4e4ea8de4a2402297c59053d4becc404b47e0a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2":
|
||||
version: 1.1.2
|
||||
resolution: "@protobufjs/aspromise@npm:1.1.2"
|
||||
@@ -6851,6 +6862,7 @@ __metadata:
|
||||
"@opentelemetry/sdk-trace-base": "npm:^1.25.1"
|
||||
"@opentelemetry/sdk-trace-web": "npm:^1.9.1"
|
||||
"@opentelemetry/semantic-conventions": "npm:^1.25.1"
|
||||
"@playwright/test": "npm:^1.51.0"
|
||||
"@radix-ui/react-dialog": "npm:^1.0.4"
|
||||
"@radix-ui/react-slider": "npm:^1.1.2"
|
||||
"@radix-ui/react-visually-hidden": "npm:^1.0.3"
|
||||
@@ -7946,6 +7958,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fsevents@npm:2.3.2":
|
||||
version: 2.3.2
|
||||
resolution: "fsevents@npm:2.3.2"
|
||||
dependencies:
|
||||
node-gyp: "npm:latest"
|
||||
checksum: 10c0/be78a3efa3e181cda3cf7a4637cb527bcebb0bd0ea0440105a3bb45b86f9245b307dc10a2507e8f4498a7d4ec349d1910f4d73e4d4495b16103106e07eee735b
|
||||
conditions: os=darwin
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fsevents@npm:~2.3.2, fsevents@npm:~2.3.3":
|
||||
version: 2.3.3
|
||||
resolution: "fsevents@npm:2.3.3"
|
||||
@@ -7956,6 +7978,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin<compat/fsevents>":
|
||||
version: 2.3.2
|
||||
resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin<compat/fsevents>::version=2.3.2&hash=df0bf1"
|
||||
dependencies:
|
||||
node-gyp: "npm:latest"
|
||||
conditions: os=darwin
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin<compat/fsevents>, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin<compat/fsevents>":
|
||||
version: 2.3.3
|
||||
resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin<compat/fsevents>::version=2.3.3&hash=df0bf1"
|
||||
@@ -10266,6 +10297,30 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"playwright-core@npm:1.51.0":
|
||||
version: 1.51.0
|
||||
resolution: "playwright-core@npm:1.51.0"
|
||||
bin:
|
||||
playwright-core: cli.js
|
||||
checksum: 10c0/8f5de23088c5e97c00327f356b17e0223181e921baf99f4e38d9a3b18d0693db288f8b5389e96d0cb4a1b55f03870f140dd7346128a0c02ce36d11eb92153841
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"playwright@npm:1.51.0":
|
||||
version: 1.51.0
|
||||
resolution: "playwright@npm:1.51.0"
|
||||
dependencies:
|
||||
fsevents: "npm:2.3.2"
|
||||
playwright-core: "npm:1.51.0"
|
||||
dependenciesMeta:
|
||||
fsevents:
|
||||
optional: true
|
||||
bin:
|
||||
playwright: cli.js
|
||||
checksum: 10c0/e8509ea500e03e8051fd243f2347ac3196ff8dde4c20ae3aba4cf723e2b647a0158d209fba062995dab90590229a483d723562cf1ea8b2fc11698617027416fd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pluralize@npm:^8.0.0":
|
||||
version: 8.0.0
|
||||
resolution: "pluralize@npm:8.0.0"
|
||||
|
||||
Reference in New Issue
Block a user