From 3bc8c0590d3d8c355cbc09f6e9727f7dc48f7861 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 24 Apr 2026 18:27:05 +0200 Subject: [PATCH 1/7] dev-tool: Add option to enable extended livekit logs --- src/App.tsx | 2 ++ src/LivekitLogLevelSync.tsx | 22 ++++++++++++++++++++++ src/settings/DeveloperSettingsTab.tsx | 19 +++++++++++++++++++ src/settings/settings.ts | 5 +++++ 4 files changed, 48 insertions(+) create mode 100644 src/LivekitLogLevelSync.tsx diff --git a/src/App.tsx b/src/App.tsx index b87f587c..e124b0bd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -32,6 +32,7 @@ import { type AppViewModel } from "./state/AppViewModel"; import { MediaDevicesContext } from "./MediaDevicesContext"; import { getUrlParams, HeaderStyle } from "./UrlParams"; import { AppBar } from "./AppBar"; +import { LivekitLogLevelSync } from "./LivekitLogLevelSync.tsx"; const SentryRoute = Sentry.withSentryReactRouterV7Routing(Route); @@ -81,6 +82,7 @@ export const App: FC = ({ vm }) => { const content = loaded ? ( + } diff --git a/src/LivekitLogLevelSync.tsx b/src/LivekitLogLevelSync.tsx new file mode 100644 index 00000000..5d3916d2 --- /dev/null +++ b/src/LivekitLogLevelSync.tsx @@ -0,0 +1,22 @@ +/* +Copyright 2026 Element Creations Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE in the repository root for full details. +*/ + +// Syncs the livekit log level with the "Enable extended Livekit logs" developer setting. +import { type FC, useEffect } from "react"; +import { setLogLevel } from "livekit-client"; + +import { useSetting, enableExtendedLivekitLogs } from "./settings/settings.ts"; + +export const LivekitLogLevelSync: FC = () => { + const [extendedLivekitLogs] = useSetting(enableExtendedLivekitLogs); + + useEffect(() => { + setLogLevel(extendedLivekitLogs ? "trace" : "info"); + }, [extendedLivekitLogs]); + + return <>; +}; diff --git a/src/settings/DeveloperSettingsTab.tsx b/src/settings/DeveloperSettingsTab.tsx index 9df6181f..0db5e2ef 100644 --- a/src/settings/DeveloperSettingsTab.tsx +++ b/src/settings/DeveloperSettingsTab.tsx @@ -43,6 +43,7 @@ import { matrixRTCMode as matrixRTCModeSetting, customLivekitUrl as customLivekitUrlSetting, MatrixRTCMode, + enableExtendedLivekitLogs as enableExtendedLivekitLogsSetting, } from "./settings"; import styles from "./DeveloperSettingsTab.module.css"; import { useUrlParams } from "../UrlParams"; @@ -101,6 +102,10 @@ export const DeveloperSettingsTab: FC = ({ alwaysShowIphoneEarpieceSetting, ); + const [enableExtendedLivekitLogs, setEnableExtendedLivekitLogs] = useSetting( + enableExtendedLivekitLogsSetting, + ); + const [customLivekitUrlUpdateError, setCustomLivekitUrlUpdateError] = useState(null); const [customLivekitUrl, setCustomLivekitUrl] = useSetting( @@ -227,6 +232,20 @@ export const DeveloperSettingsTab: FC = ({ )} />{" "} + + ): void => { + setEnableExtendedLivekitLogs(event.target.checked); + }, + [setEnableExtendedLivekitLogs], + )} + />{" "} + e.preventDefault()} helpLabel={ diff --git a/src/settings/settings.ts b/src/settings/settings.ts index 917c79f1..cf0d9d66 100644 --- a/src/settings/settings.ts +++ b/src/settings/settings.ts @@ -129,6 +129,11 @@ export const alwaysShowIphoneEarpiece = new Setting( false, ); +export const enableExtendedLivekitLogs = new Setting( + "extended-livekit-logs", + false, +); + export enum MatrixRTCMode { Legacy = "legacy", Compatibility = "compatibility", From 2ac221661b1ca26d4f021b6d2e0081acf0bf60dd Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 11 May 2026 17:43:34 +0200 Subject: [PATCH 2/7] review: Use Initializer instead of creating a component --- src/App.tsx | 2 -- src/LivekitLogLevelSync.tsx | 22 ---------------------- src/initializer.tsx | 17 +++++++++++++++++ src/main.tsx | 11 ----------- 4 files changed, 17 insertions(+), 35 deletions(-) delete mode 100644 src/LivekitLogLevelSync.tsx diff --git a/src/App.tsx b/src/App.tsx index e124b0bd..b87f587c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -32,7 +32,6 @@ import { type AppViewModel } from "./state/AppViewModel"; import { MediaDevicesContext } from "./MediaDevicesContext"; import { getUrlParams, HeaderStyle } from "./UrlParams"; import { AppBar } from "./AppBar"; -import { LivekitLogLevelSync } from "./LivekitLogLevelSync.tsx"; const SentryRoute = Sentry.withSentryReactRouterV7Routing(Route); @@ -82,7 +81,6 @@ export const App: FC = ({ vm }) => { const content = loaded ? ( - } diff --git a/src/LivekitLogLevelSync.tsx b/src/LivekitLogLevelSync.tsx deleted file mode 100644 index 5d3916d2..00000000 --- a/src/LivekitLogLevelSync.tsx +++ /dev/null @@ -1,22 +0,0 @@ -/* -Copyright 2026 Element Creations Ltd. - -SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial -Please see LICENSE in the repository root for full details. -*/ - -// Syncs the livekit log level with the "Enable extended Livekit logs" developer setting. -import { type FC, useEffect } from "react"; -import { setLogLevel } from "livekit-client"; - -import { useSetting, enableExtendedLivekitLogs } from "./settings/settings.ts"; - -export const LivekitLogLevelSync: FC = () => { - const [extendedLivekitLogs] = useSetting(enableExtendedLivekitLogs); - - useEffect(() => { - setLogLevel(extendedLivekitLogs ? "trace" : "info"); - }, [extendedLivekitLogs]); - - return <>; -}; diff --git a/src/initializer.tsx b/src/initializer.tsx index 2bd6f577..7c6fc529 100644 --- a/src/initializer.tsx +++ b/src/initializer.tsx @@ -23,12 +23,17 @@ import { createRoutesFromChildren, matchRoutes, } from "react-router-dom"; +import { + setLogExtension as setLKLogExtension, + setLogLevel as setLKLogLevel, +} from "livekit-client"; import { getUrlParams } from "./UrlParams"; import { Config } from "./config/Config"; import { platform } from "./Platform"; import { isFailure } from "./utils/fetch"; import { initializeWidget } from "./widget"; +import { enableExtendedLivekitLogs } from "./settings/settings.ts"; // This generates a map of locale names to their URL (based on import.meta.url), which looks like this: // { @@ -189,6 +194,18 @@ export class Initializer { // Add the platform to the DOM, so CSS can query it document.body.setAttribute("data-platform", platform); + + // livekit logging configuration + setLKLogExtension((level, msg, context) => { + // we pass a synthetic logger name of "livekit" to the rageshake to make it easier to read + global.mx_rage_logger.log(level, "livekit", msg, context); + }); + + enableExtendedLivekitLogs.value$.subscribe((enabled) => { + setLKLogLevel(enabled ? "trace" : "info"); + }); + + window.setLKLogLevel = setLKLogLevel; } public static init(): Promise | null { diff --git a/src/main.tsx b/src/main.tsx index 6cbf75fa..8f64c680 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -15,10 +15,6 @@ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import "./index.css"; import { logger } from "matrix-js-sdk/lib/logger"; -import { - setLogExtension as setLKLogExtension, - setLogLevel as setLKLogLevel, -} from "livekit-client"; import { App } from "./App"; import { init as initRageshake } from "./settings/rageshake"; @@ -26,16 +22,9 @@ import { Initializer } from "./initializer"; import { AppViewModel } from "./state/AppViewModel"; import { globalScope } from "./state/ObservableScope"; -window.setLKLogLevel = setLKLogLevel; - initRageshake().catch((e) => { logger.error("Failed to initialize rageshake", e); }); -setLKLogLevel("info"); -setLKLogExtension((level, msg, context) => { - // we pass a synthetic logger name of "livekit" to the rageshake to make it easier to read - global.mx_rage_logger.log(level, "livekit", msg, context); -}); logger.info(`Element Call ${import.meta.env.VITE_APP_VERSION || "dev"}`); From f1b61a9f1c13e48d48b7632b887348f1fa86960f Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 11 May 2026 18:07:40 +0200 Subject: [PATCH 3/7] update developer settings tab snapshot --- .../DeveloperSettingsTab.test.tsx.snap | 70 ++++++++++++++----- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/src/settings/__snapshots__/DeveloperSettingsTab.test.tsx.snap b/src/settings/__snapshots__/DeveloperSettingsTab.test.tsx.snap index af38685a..8d43b12b 100644 --- a/src/settings/__snapshots__/DeveloperSettingsTab.test.tsx.snap +++ b/src/settings/__snapshots__/DeveloperSettingsTab.test.tsx.snap @@ -186,6 +186,44 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = ` + +
+
+ + +
+
renders and matches snapshot 1`] = ` > @@ -203,9 +241,9 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = ` class="_controls_17lij_8" > renders and matches snapshot 1`] = ` Currently, no overwrite is set. Url from well-known or config is used. @@ -237,10 +275,10 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = ` class="_container_1ug7n_10" > renders and matches snapshot 1`] = ` > Compatible with old versions of EC that do not support multi SFU @@ -278,9 +316,9 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = ` class="_container_1ug7n_10" > renders and matches snapshot 1`] = ` > Compatible with homeservers that do not support sticky events (but all other EC clients are v0.17.0 or later) @@ -318,9 +356,9 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = ` class="_container_1ug7n_10" > renders and matches snapshot 1`] = ` > Compatible only with homservers supporting sticky events and all EC clients v0.17.0 or later From 8011f2579c001ce04f640719b0836d5fbac272e3 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 27 May 2026 14:03:31 +0200 Subject: [PATCH 4/7] test: Add test for new option review: Remove uneeed {" "} --- src/settings/DeveloperSettingsTab.test.tsx | 65 ++++++++++++++++++- src/settings/DeveloperSettingsTab.tsx | 4 +- .../DeveloperSettingsTab.test.tsx.snap | 2 - 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/settings/DeveloperSettingsTab.test.tsx b/src/settings/DeveloperSettingsTab.test.tsx index 77ea81d6..da7f75b8 100644 --- a/src/settings/DeveloperSettingsTab.test.tsx +++ b/src/settings/DeveloperSettingsTab.test.tsx @@ -14,7 +14,11 @@ import type { MatrixClient } from "matrix-js-sdk"; import type { Room as LivekitRoom } from "livekit-client"; import { DeveloperSettingsTab } from "./DeveloperSettingsTab"; import { getSFUConfigWithOpenID } from "../livekit/openIDSFU"; -import { customLivekitUrl as customLivekitUrlSetting } from "./settings"; +import { + customLivekitUrl as customLivekitUrlSetting, + enableExtendedLivekitLogs as enableExtendedLivekitLogsSetting, +} from "./settings"; + // Mock url params hook to avoid environment-dependent snapshot churn. vi.mock("../UrlParams", () => ({ useUrlParams: (): { mocked: boolean; answer: number } => ({ @@ -248,4 +252,63 @@ describe("DeveloperSettingsTab", () => { expect(customLivekitUrlSetting.getValue()).toBe(null); }); }); + + // Add this test inside the describe("DeveloperSettingsTab", () => { block, + // after the custom livekit url tests: + + describe("enable extended livekit logs", () => { + afterEach(() => { + enableExtendedLivekitLogsSetting.setValue(false); + }); + + it("toggles extended livekit logs setting", async () => { + const user = userEvent.setup(); + const client = createMockMatrixClient(); + + render( + + + , + ); + + const checkbox = screen.getByLabelText("Enable extended livekit logs"); + + // Initial state should be unchecked (default false) + expect(checkbox).not.toBeChecked(); + expect(enableExtendedLivekitLogsSetting.getValue()).toBe(false); + + // Click to enable + await user.click(checkbox); + expect(checkbox).toBeChecked(); + expect(enableExtendedLivekitLogsSetting.getValue()).toBe(true); + + // Click to disable + await user.click(checkbox); + expect(checkbox).not.toBeChecked(); + expect(enableExtendedLivekitLogsSetting.getValue()).toBe(false); + }); + + it("reflects the current setting value on render", async () => { + const client = createMockMatrixClient(); + + // Set the value to true before rendering + enableExtendedLivekitLogsSetting.setValue(true); + + render( + + + , + ); + + const checkbox = screen.getByLabelText("Enable extended livekit logs"); + expect(checkbox).toBeChecked(); + expect(enableExtendedLivekitLogsSetting.getValue()).toBe(true); + }); + }); }); diff --git a/src/settings/DeveloperSettingsTab.tsx b/src/settings/DeveloperSettingsTab.tsx index 0db5e2ef..74c878e9 100644 --- a/src/settings/DeveloperSettingsTab.tsx +++ b/src/settings/DeveloperSettingsTab.tsx @@ -230,7 +230,7 @@ export const DeveloperSettingsTab: FC = ({ }, [setAlwaysShowIphoneEarpiece], )} - />{" "} + /> = ({ }, [setEnableExtendedLivekitLogs], )} - />{" "} + /> e.preventDefault()} diff --git a/src/settings/__snapshots__/DeveloperSettingsTab.test.tsx.snap b/src/settings/__snapshots__/DeveloperSettingsTab.test.tsx.snap index 2400a535..36e29d80 100644 --- a/src/settings/__snapshots__/DeveloperSettingsTab.test.tsx.snap +++ b/src/settings/__snapshots__/DeveloperSettingsTab.test.tsx.snap @@ -185,7 +185,6 @@ exports[`DeveloperSettingsTab > renders and matches snapshot 1`] = ` Show iPhone earpiece option on all platforms -
renders and matches snapshot 1`] = ` Enable extended livekit logs
- Date: Wed, 27 May 2026 14:18:34 +0200 Subject: [PATCH 5/7] eslint --- src/settings/DeveloperSettingsTab.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/DeveloperSettingsTab.test.tsx b/src/settings/DeveloperSettingsTab.test.tsx index da7f75b8..f5afe55c 100644 --- a/src/settings/DeveloperSettingsTab.test.tsx +++ b/src/settings/DeveloperSettingsTab.test.tsx @@ -291,7 +291,7 @@ describe("DeveloperSettingsTab", () => { expect(enableExtendedLivekitLogsSetting.getValue()).toBe(false); }); - it("reflects the current setting value on render", async () => { + it("reflects the current setting value on render", () => { const client = createMockMatrixClient(); // Set the value to true before rendering From e815277fa26bfc6ed40f10a5909391af8eee0e92 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 28 May 2026 08:59:05 +0200 Subject: [PATCH 6/7] touch commit to unbock gh --- src/settings/DeveloperSettingsTab.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/DeveloperSettingsTab.test.tsx b/src/settings/DeveloperSettingsTab.test.tsx index f5afe55c..5ff0d4d2 100644 --- a/src/settings/DeveloperSettingsTab.test.tsx +++ b/src/settings/DeveloperSettingsTab.test.tsx @@ -291,7 +291,7 @@ describe("DeveloperSettingsTab", () => { expect(enableExtendedLivekitLogsSetting.getValue()).toBe(false); }); - it("reflects the current setting value on render", () => { + it("Use the current setting value on render", () => { const client = createMockMatrixClient(); // Set the value to true before rendering From 8b86c1914dc29accefb038a3f7c960722147aef3 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 28 May 2026 10:40:47 +0200 Subject: [PATCH 7/7] bump playwright update playwright container image --- .github/workflows/test.yaml | 2 +- package.json | 2 +- pnpm-lock.yaml | 36 ++++++++++++++++++------------------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 2cec64f5..05ee362b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -10,7 +10,7 @@ jobs: container: # Make sure to grab the latest version of the Playwright image # https://playwright.dev/docs/docker#pull-the-image - image: mcr.microsoft.com/playwright:v1.59.1-noble + image: mcr.microsoft.com/playwright:v1.60.0-noble steps: - name: Checkout code uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 diff --git a/package.json b/package.json index 705cdc11..1e3a6fee 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@livekit/protocol": "^1.42.2", "@livekit/track-processors": "^0.7.1", "@mediapipe/tasks-vision": "^0.10.18", - "@playwright/test": "^1.59.0", + "@playwright/test": "^1.60.0", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-slider": "^1.1.2", "@radix-ui/react-visually-hidden": "^1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6940982b..6d1c4e0b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -61,8 +61,8 @@ importers: specifier: ^0.10.18 version: 0.10.34 '@playwright/test': - specifier: ^1.59.0 - version: 1.59.1 + specifier: ^1.60.0 + version: 1.60.0 '@radix-ui/react-dialog': specifier: ^1.0.4 version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -158,7 +158,7 @@ importers: version: 4.7.0(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) '@vitest/browser-playwright': specifier: ^4.1.5 - version: 4.1.5(playwright@1.59.1)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.5) + version: 4.1.5(playwright@1.60.0)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.5) '@vitest/coverage-v8': specifier: ^4.0.18 version: 4.1.5(@vitest/browser@4.1.5)(vitest@4.1.5) @@ -1959,8 +1959,8 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@playwright/test@1.59.1': - resolution: {integrity: sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==} + '@playwright/test@1.60.0': + resolution: {integrity: sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==} engines: {node: '>=18'} hasBin: true @@ -5593,13 +5593,13 @@ packages: resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} engines: {node: '>=10'} - playwright-core@1.59.1: - resolution: {integrity: sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==} + playwright-core@1.60.0: + resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==} engines: {node: '>=18'} hasBin: true - playwright@1.59.1: - resolution: {integrity: sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==} + playwright@1.60.0: + resolution: {integrity: sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==} engines: {node: '>=18'} hasBin: true @@ -8760,9 +8760,9 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@playwright/test@1.59.1': + '@playwright/test@1.60.0': dependencies: - playwright: 1.59.1 + playwright: 1.60.0 '@polka/url@1.0.0-next.29': {} @@ -9484,7 +9484,7 @@ snapshots: storybook: 10.3.6(@testing-library/dom@10.4.1)(prettier@3.8.3)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) optionalDependencies: '@vitest/browser': 4.1.5(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.5) - '@vitest/browser-playwright': 4.1.5(playwright@1.59.1)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.5) + '@vitest/browser-playwright': 4.1.5(playwright@1.60.0)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.5) '@vitest/runner': 4.1.5 vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/browser-playwright@4.1.5)(@vitest/coverage-v8@4.1.5)(@vitest/ui@4.1.5)(jsdom@26.1.0)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) transitivePeerDependencies: @@ -10083,11 +10083,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/browser-playwright@4.1.5(playwright@1.59.1)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.5)': + '@vitest/browser-playwright@4.1.5(playwright@1.60.0)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.5)': dependencies: '@vitest/browser': 4.1.5(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.5) '@vitest/mocker': 4.1.5(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) - playwright: 1.59.1 + playwright: 1.60.0 tinyrainbow: 3.1.0 vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/browser-playwright@4.1.5)(@vitest/coverage-v8@4.1.5)(@vitest/ui@4.1.5)(jsdom@26.1.0)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3)) transitivePeerDependencies: @@ -12762,11 +12762,11 @@ snapshots: dependencies: find-up: 5.0.0 - playwright-core@1.59.1: {} + playwright-core@1.60.0: {} - playwright@1.59.1: + playwright@1.60.0: dependencies: - playwright-core: 1.59.1 + playwright-core: 1.60.0 optionalDependencies: fsevents: 2.3.2 @@ -14245,7 +14245,7 @@ snapshots: optionalDependencies: '@opentelemetry/api': 1.9.1 '@types/node': 24.12.2 - '@vitest/browser-playwright': 4.1.5(playwright@1.59.1)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.5) + '@vitest/browser-playwright': 4.1.5(playwright@1.60.0)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(yaml@2.8.3))(vitest@4.1.5) '@vitest/coverage-v8': 4.1.5(@vitest/browser@4.1.5)(vitest@4.1.5) '@vitest/ui': 4.1.5(vitest@4.1.5) jsdom: 26.1.0