Consolidate vitest CI & coverage (#33808)

* Consolidate modules vitest coverage

* Use vite-common as base for modules vitest config

* Make knip happier

* Fix coverage paths

* Place modules unit tests alongside src

* Switch to defineProject for better type safety

* Consolidate vitest CI & coverage

Kills off vite-common

* Update comment

* Update lockfile

* Fix shared-components vitest config

* Soften eslint config for tests in modules

* Run eslint on modules/playwright dir too

* Make tsc happy
This commit is contained in:
Michael Telatynski
2026-06-10 17:00:34 +01:00
committed by GitHub
parent 042ded86c7
commit e9a89d9872
34 changed files with 252 additions and 301 deletions
+2 -2
View File
@@ -42,7 +42,7 @@ module.exports = {
},
overrides: [
{
files: ["playwright/**/*.ts", "modules/*/e2e/**/*.{ts,tsx}"],
files: ["playwright/**/*.ts", "*/e2e/**/*.{ts,tsx}", "*/src/**/*.test.{ts,tsx}"],
rules: {
// This is necessary for Playwright fixtures
"no-empty-pattern": "off",
@@ -55,7 +55,7 @@ module.exports = {
],
settings: {
react: {
version: "detect",
version: "19",
},
},
};
+1 -1
View File
@@ -3,7 +3,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"lint:js": "eslint --max-warnings 0 */src -c ./.eslintrc.cjs",
"lint:js": "eslint --max-warnings 0 playwright */src -c ./.eslintrc.cjs",
"lint:ts": "tsc --noEmit",
"test:playwright": "nx test:playwright --",
"test:playwright:open": "nx test:playwright -- --ui",
+1 -1
View File
@@ -45,7 +45,7 @@ playwright project.
const projects: Project<Options>[] = [];
// Get all the directories that hold playwright tests
const moduleTestDirectories = globSync("*/e2e", { cwd: __dirname });
const moduleTestDirectories = globSync("*/e2e", { cwd: __dirname }).map((d) => path.join(__dirname, d));
// Process each directory
for (const testDirectory of moduleTestDirectories) {
-1
View File
@@ -13,7 +13,6 @@
"devDependencies": {
"@element-hq/element-web-module-api": "workspace:*",
"@types/node": "^22.10.7",
"@vitest/coverage-v8": "catalog:",
"typescript": "catalog:",
"vite": "catalog:",
"vitest": "catalog:"
@@ -7,12 +7,13 @@ Please see LICENSE files in the repository root for full details.
import { describe, expect, it } from "vitest";
import WidgetLifecycleModule, { type WidgetLifecycleApiAdapter } from "../src/WidgetLifecycleModule";
import WidgetLifecycleModule, { type WidgetLifecycleApiAdapter } from "./WidgetLifecycleModule";
import type {
CapabilitiesApprover,
IdentityApprover,
PreloadApprover,
WidgetDescriptor,
Api,
} from "@element-hq/element-web-module-api";
const createApi = (config: unknown = {}) => {
@@ -40,7 +41,7 @@ const createApi = (config: unknown = {}) => {
get: () => config,
},
widgetLifecycle,
},
} as Api,
handlers,
};
};
@@ -49,7 +50,8 @@ const widget: WidgetDescriptor = {
id: "widget-id",
templateUrl: "https://example.com/",
creatorUserId: "@user-id",
kind: "room",
type: "com.example.custom",
origin: "example.com",
};
describe("WidgetLifecycleModule", () => {
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
import { describe, expect, it } from "vitest";
import { parseWidgetLifecycleConfig } from "../src/config";
import { parseWidgetLifecycleConfig } from "./config";
describe("parseWidgetLifecycleConfig", () => {
it("accepts missing configuration", () => {
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
import { describe, expect, it } from "vitest";
import { constructWidgetPermissions, sortLongestMatchLast } from "../src/utils/constructWidgetPermissions";
import { constructWidgetPermissions, sortLongestMatchLast } from "./constructWidgetPermissions";
describe("constructWidgetPermissions", () => {
it("finds exact match", () => {
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
import { describe, expect, it } from "vitest";
import { matchPattern } from "../src/utils/matchPattern";
import { matchPattern } from "./matchPattern";
describe("matchPattern", () => {
it.each([
+2 -9
View File
@@ -5,17 +5,10 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { defineConfig } from "vitest/config";
import { defineProject } from "vitest/config";
export default defineConfig({
export default defineProject({
test: {
include: ["tests/**/*.test.ts"],
exclude: ["./e2e/**/*", "./node_modules/**/*"],
reporters: ["default"],
coverage: {
provider: "v8",
include: ["src/**/*.ts"],
reporter: [["lcov", { projectRoot: "../../" }], "text"],
},
},
});
-1
View File
@@ -20,7 +20,6 @@
"@types/react": "^19",
"@vitejs/plugin-react": "catalog:",
"@vitest/browser-playwright": "catalog:",
"@vitest/coverage-v8": "catalog:",
"react": "catalog:",
"typescript": "catalog:",
"vite": "catalog:",
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
import { describe, expect, test } from "vitest";
import { WidgetTogglesConfig } from "../src/config";
import { WidgetTogglesConfig } from "./config";
describe("WidgetTogglesConfig", () => {
test("parses a valid config with an array of widget types", () => {
@@ -10,9 +10,9 @@ import { render, type RenderResult, screen } from "@testing-library/react";
import { type Api } from "@element-hq/element-web-module-api";
import { type IWidget } from "matrix-widget-api";
import WidgetToggleModule from "../src/index";
import { CONFIG_KEY, WidgetTogglesConfig } from "../src/config";
import { mockWidget, mockWidgetApi } from "./mocks";
import WidgetToggleModule from "./index";
import { CONFIG_KEY, WidgetTogglesConfig } from "./config";
import { mockWidget, mockWidgetApi } from "./tests/mocks";
const makeApi = (widgets: IWidget[] = []): Api => {
const addRoomHeaderButtonCallback = vi.fn();
@@ -13,8 +13,8 @@ import { type PropsWithChildren } from "react";
import { TooltipProvider } from "@vector-im/compound-web";
import userEvent from "@testing-library/user-event";
import { WidgetToggle } from "../src/toggle";
import { mockI18nApi, mockWidget, mockWidgetApi } from "./mocks";
import { WidgetToggle } from "./toggle";
import { mockI18nApi, mockWidget, mockWidgetApi } from "./tests/mocks";
const roomId = "!room:example.com";
@@ -1,7 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"jsx": "react-jsx"
},
"include": ["."]
}
+3 -10
View File
@@ -5,25 +5,18 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { defineConfig } from "vitest/config";
import { defineProject } from "vitest/config";
import { playwright } from "@vitest/browser-playwright";
export default defineConfig({
export default defineProject({
test: {
include: ["tests/**/*.test.{ts,tsx}"],
exclude: ["./e2e/**/*", "./node_modules/**/*"],
reporters: ["default"],
coverage: {
provider: "v8",
include: ["src/**/*.ts"],
reporter: [["lcov", { projectRoot: "../../" }], "text"],
},
browser: {
enabled: true,
headless: true,
provider: playwright({}),
instances: [{ browser: "chromium" }],
},
setupFiles: ["tests/setupTests.ts"],
setupFiles: ["src/tests/setupTests.ts"],
},
});