From b351eb7cfaa730528d02f51965c817f1e10848a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2026 06:09:00 +0000 Subject: [PATCH 1/4] Bump @vscode-elements/react-elements in /extensions/ql-vscode Bumps [@vscode-elements/react-elements](https://github.com/vscode-elements/react-elements) from 0.9.0 to 2.4.0. - [Release notes](https://github.com/vscode-elements/react-elements/releases) - [Commits](https://github.com/vscode-elements/react-elements/compare/v0.9.0...v2.4.0) --- updated-dependencies: - dependency-name: "@vscode-elements/react-elements" dependency-version: 2.4.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- extensions/ql-vscode/package-lock.json | 78 +++++++++++++++----------- extensions/ql-vscode/package.json | 2 +- 2 files changed, 47 insertions(+), 33 deletions(-) diff --git a/extensions/ql-vscode/package-lock.json b/extensions/ql-vscode/package-lock.json index 079dcaee7b8..8edc01ed793 100644 --- a/extensions/ql-vscode/package-lock.json +++ b/extensions/ql-vscode/package-lock.json @@ -15,7 +15,7 @@ "@octokit/plugin-retry": "^8.1.0", "@octokit/plugin-throttling": "^9.6.0", "@octokit/rest": "^22.0.1", - "@vscode-elements/react-elements": "^0.9.0", + "@vscode-elements/react-elements": "^2.4.0", "@vscode/codicons": "^0.0.44", "@vscode/debugadapter": "^1.68.0", "@vscode/debugprotocol": "^1.68.0", @@ -5155,11 +5155,20 @@ } }, "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz", - "integrity": "sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.6.0.tgz", + "integrity": "sha512-VHb0ALPMTlgKjM6yIxxoQNnpKyUKLD04VzeQdsiXkMqkvYlAHxq9glGLmgbb889/1GsohSOAjvQYoiBppXFqrQ==", "license": "BSD-3-Clause" }, + "node_modules/@lit/context": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@lit/context/-/context-1.1.6.tgz", + "integrity": "sha512-M26qDE6UkQbZA2mQ3RjJ3Gzd8TxP+/0obMgE5HfkfLhEEyYE3Bui4A5XHiGPjy0MUGAyxB3QgVuw2ciS0kHn6A==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit/reactive-element": "^1.6.2 || ^2.1.0" + } + }, "node_modules/@lit/react": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@lit/react/-/react-1.0.7.tgz", @@ -5170,12 +5179,12 @@ } }, "node_modules/@lit/reactive-element": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", - "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.2.tgz", + "integrity": "sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==", "license": "BSD-3-Clause", "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0" + "@lit-labs/ssr-dom-shim": "^1.5.0" } }, "node_modules/@mdx-js/react": { @@ -10229,25 +10238,30 @@ ] }, "node_modules/@vscode-elements/elements": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@vscode-elements/elements/-/elements-1.14.0.tgz", - "integrity": "sha512-fUOP8O/Pwy8zbD8hGSy1plBg/764hdM9jIMu8uG7GQJOrOB+uQ/ystYxkiUcN6P7OBHvqkBKO1j6vDrkaOJg6Q==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@vscode-elements/elements/-/elements-2.5.1.tgz", + "integrity": "sha512-HiKgIj9GwlfYkw1LrxG7dM5bMQUr8/GkOqG1HU1+npGHd51nRKCF6ZZ9FtnfoC2wujNN0lc+m0emH/wMpAseYQ==", "license": "MIT", "dependencies": { + "@lit/context": "^1.1.3", "lit": "^3.2.1" + }, + "peerDependencies": { + "@vscode/codicons": ">=0.0.40" } }, "node_modules/@vscode-elements/react-elements": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@vscode-elements/react-elements/-/react-elements-0.9.0.tgz", - "integrity": "sha512-pGWp6OBDAZXJ0tZqN+2SCiKhvhW3/cE4XJyiVHXH4Ft6KteuNVg20oexFv0M66U9iAZElQjPF8M9pBBABLaUZg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@vscode-elements/react-elements/-/react-elements-2.4.0.tgz", + "integrity": "sha512-gDLHE+JE0ViYN+Bzp0obUKBA+guc8Vk0X3n1157z9J+X9GCwHo5ZNziDmiNXyd3QA4IE/kkcg5+3RsemYLlZqg==", "license": "ISC", "dependencies": { - "@lit/react": "^1.0.6", - "@vscode-elements/elements": "^1.13.0" + "@lit/react": "^1.0.7", + "@vscode-elements/elements": "^2.4.0" }, "peerDependencies": { - "react": "^18.0.0" + "react": "17 || 18 || 19", + "react-dom": "17 || 18 || 19" } }, "node_modules/@vscode/codicons": { @@ -21839,31 +21853,31 @@ } }, "node_modules/lit": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz", - "integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.3.tgz", + "integrity": "sha512-fycuvZg/hkpozL00lm1pEJH5nN/lr9ZXd6mJI2HSN4+Bzc+LDNdEApJ6HFbPkdFNHLvOplIIuJvxkS4XUxqirw==", "license": "BSD-3-Clause", "dependencies": { - "@lit/reactive-element": "^2.0.4", - "lit-element": "^4.1.0", - "lit-html": "^3.2.0" + "@lit/reactive-element": "^2.1.0", + "lit-element": "^4.2.0", + "lit-html": "^3.3.0" } }, "node_modules/lit-element": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.1.tgz", - "integrity": "sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.2.tgz", + "integrity": "sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==", "license": "BSD-3-Clause", "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0", - "@lit/reactive-element": "^2.0.4", - "lit-html": "^3.2.0" + "@lit-labs/ssr-dom-shim": "^1.5.0", + "@lit/reactive-element": "^2.1.0", + "lit-html": "^3.3.0" } }, "node_modules/lit-html": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.1.tgz", - "integrity": "sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.3.tgz", + "integrity": "sha512-el8M6jK2o3RXBnrSHX3ZKrsN8zEV63pSExTO1wYJz7QndGYZ8353e2a5PPX+qHe2aGayfnchQmkAojaWAREOIA==", "license": "BSD-3-Clause", "dependencies": { "@types/trusted-types": "^2.0.2" diff --git a/extensions/ql-vscode/package.json b/extensions/ql-vscode/package.json index c8ae22b70e9..540f37ce27a 100644 --- a/extensions/ql-vscode/package.json +++ b/extensions/ql-vscode/package.json @@ -2073,7 +2073,7 @@ "@octokit/plugin-retry": "^8.1.0", "@octokit/plugin-throttling": "^9.6.0", "@octokit/rest": "^22.0.1", - "@vscode-elements/react-elements": "^0.9.0", + "@vscode-elements/react-elements": "^2.4.0", "@vscode/codicons": "^0.0.44", "@vscode/debugadapter": "^1.68.0", "@vscode/debugprotocol": "^1.68.0", From e5d00732f3bd6d79b1a0fc75b2e68979994479a0 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Wed, 29 Jul 2026 10:45:45 +0100 Subject: [PATCH 2/4] Add ResizeObserver polyfill to view test setup @vscode-elements/elements 2.x uses ResizeObserver in several components (e.g. vscode-table, vscode-form-container), which is not implemented in jsdom. Polyfill it in the view jest setup so these components render in tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f20698a7-f008-46a3-92a4-63037eb03a05 --- extensions/ql-vscode/src/view/jest.setup.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/extensions/ql-vscode/src/view/jest.setup.ts b/extensions/ql-vscode/src/view/jest.setup.ts index 31dc6657d40..66bafd99fe6 100644 --- a/extensions/ql-vscode/src/view/jest.setup.ts +++ b/extensions/ql-vscode/src/view/jest.setup.ts @@ -18,6 +18,14 @@ Object.defineProperty(window, "matchMedia", { // Used by Primer React window.CSS.supports = jest.fn().mockResolvedValue(false); +// ResizeObserver is not implemented in jsdom but is used by some +// @vscode-elements/elements components (e.g. vscode-table, vscode-form-container). +window.ResizeObserver = class ResizeObserver { + observe = jest.fn(); + unobserve = jest.fn(); + disconnect = jest.fn(); +}; + // Functions that are not implemented in jsdom window.CSSStyleSheet.prototype.replaceSync = jest .fn() From 74fb5166ffeceb663f480d7873bdc71e0c7d8983 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Wed, 29 Jul 2026 10:46:55 +0100 Subject: [PATCH 3/4] Fix RepoRow checkbox lookup for vscode-elements 2.x The vscode-checkbox host element no longer exposes a "checkbox" ARIA role in @vscode-elements/elements 2.x (the role now lives on an inside its shadow DOM, which testing-library cannot reach). Find the checkbox by tag name instead, waiting for the disabled attribute that Lit reflects asynchronously. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f20698a7-f008-46a3-92a4-63037eb03a05 --- .../__tests__/RepoRow.spec.tsx | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/extensions/ql-vscode/src/view/variant-analysis/__tests__/RepoRow.spec.tsx b/extensions/ql-vscode/src/view/variant-analysis/__tests__/RepoRow.spec.tsx index 1c89400615d..893df3d9522 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/__tests__/RepoRow.spec.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/__tests__/RepoRow.spec.tsx @@ -1,4 +1,9 @@ -import { act, render as reactRender, screen } from "@testing-library/react"; +import { + act, + render as reactRender, + screen, + waitFor, +} from "@testing-library/react"; import { VariantAnalysisRepoStatus, VariantAnalysisScannedRepositoryDownloadStatus, @@ -24,6 +29,21 @@ describe(RepoRow.name, () => { ); }; + // The `vscode-checkbox` web component no longer exposes a `checkbox` ARIA role + // on its host element (the role now lives on an inside its shadow DOM, + // which testing-library cannot reach), so find it by tag name instead. The + // `disabled` property is reflected to a `disabled` attribute asynchronously by + // Lit, so wait for the expected state. + const findCheckbox = async (container: HTMLElement): Promise => { + return waitFor(() => { + const checkbox = container.querySelector("vscode-checkbox"); + if (!checkbox) { + throw new Error("Unable to find a vscode-checkbox element"); + } + return checkbox as HTMLElement; + }); + }; + it("renders the pending state", () => { render(); @@ -394,25 +414,25 @@ describe(RepoRow.name, () => { }); it("does not allow selecting the item if the item has not succeeded", async () => { - render({ + const { container } = render({ status: VariantAnalysisRepoStatus.InProgress, }); - const checkbox = await screen.findByRole("checkbox"); + const checkbox = await findCheckbox(container); expect(checkbox).toBeDisabled(); }); it("does not allow selecting the item if the item has not been downloaded", async () => { - render({ + const { container } = render({ status: VariantAnalysisRepoStatus.Succeeded, }); - const checkbox = await screen.findByRole("checkbox"); + const checkbox = await findCheckbox(container); expect(checkbox).toBeDisabled(); }); it("does not allow selecting the item if the item has not been downloaded successfully", async () => { - render({ + const { container } = render({ status: VariantAnalysisRepoStatus.Succeeded, downloadState: { repositoryId: 1, @@ -420,12 +440,12 @@ describe(RepoRow.name, () => { }, }); - const checkbox = await screen.findByRole("checkbox"); + const checkbox = await findCheckbox(container); expect(checkbox).toBeDisabled(); }); it("allows selecting the item if the item has been downloaded", async () => { - render({ + const { container } = render({ status: VariantAnalysisRepoStatus.Succeeded, downloadState: { repositoryId: 1, @@ -434,7 +454,7 @@ describe(RepoRow.name, () => { }, }); - const checkbox = await screen.findByRole("checkbox"); + const checkbox = await findCheckbox(container); expect(checkbox).toBeEnabled(); }); }); From 2017ea30af8fdaa71979e809822ec115a8ac4ff0 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Wed, 29 Jul 2026 11:45:02 +0100 Subject: [PATCH 4/4] Assert checkbox state inside waitFor in RepoRow tests The findCheckbox helper only waited for the vscode-checkbox element to exist, not for Lit to reflect the disabled property to an attribute, so the enabled/disabled assertions at each call site raced the async update. Move the assertion into the waitFor callback via an expected state argument so the retry loop waits for reflection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0f8ebf0f-6429-4147-b7eb-ffacf1a942da --- .../__tests__/RepoRow.spec.tsx | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/extensions/ql-vscode/src/view/variant-analysis/__tests__/RepoRow.spec.tsx b/extensions/ql-vscode/src/view/variant-analysis/__tests__/RepoRow.spec.tsx index 893df3d9522..617d0284f67 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/__tests__/RepoRow.spec.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/__tests__/RepoRow.spec.tsx @@ -34,12 +34,20 @@ describe(RepoRow.name, () => { // which testing-library cannot reach), so find it by tag name instead. The // `disabled` property is reflected to a `disabled` attribute asynchronously by // Lit, so wait for the expected state. - const findCheckbox = async (container: HTMLElement): Promise => { + const findCheckbox = async ( + container: HTMLElement, + expected: "enabled" | "disabled", + ): Promise => { return waitFor(() => { const checkbox = container.querySelector("vscode-checkbox"); if (!checkbox) { throw new Error("Unable to find a vscode-checkbox element"); } + if (expected === "disabled") { + expect(checkbox).toBeDisabled(); + } else { + expect(checkbox).toBeEnabled(); + } return checkbox as HTMLElement; }); }; @@ -418,8 +426,7 @@ describe(RepoRow.name, () => { status: VariantAnalysisRepoStatus.InProgress, }); - const checkbox = await findCheckbox(container); - expect(checkbox).toBeDisabled(); + await findCheckbox(container, "disabled"); }); it("does not allow selecting the item if the item has not been downloaded", async () => { @@ -427,8 +434,7 @@ describe(RepoRow.name, () => { status: VariantAnalysisRepoStatus.Succeeded, }); - const checkbox = await findCheckbox(container); - expect(checkbox).toBeDisabled(); + await findCheckbox(container, "disabled"); }); it("does not allow selecting the item if the item has not been downloaded successfully", async () => { @@ -440,8 +446,7 @@ describe(RepoRow.name, () => { }, }); - const checkbox = await findCheckbox(container); - expect(checkbox).toBeDisabled(); + await findCheckbox(container, "disabled"); }); it("allows selecting the item if the item has been downloaded", async () => { @@ -454,7 +459,6 @@ describe(RepoRow.name, () => { }, }); - const checkbox = await findCheckbox(container); - expect(checkbox).toBeEnabled(); + await findCheckbox(container, "enabled"); }); });