-
Notifications
You must be signed in to change notification settings - Fork 7
Add Positron API integration tests and CI workflow #4298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
jonvanausdeln
merged 2 commits into
main
from
jonv/publisher-extension-api-tests-4cd2ea
Jul 22, 2026
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| name: Positron-API-Tests | ||
| on: [workflow_call] | ||
| permissions: | ||
| contents: read | ||
| env: | ||
| POSITRON_CHANNEL: stable | ||
| jobs: | ||
| test: | ||
| # @posit-dev/positron-test-electron currently supports macOS only. | ||
| runs-on: macos-latest | ||
| steps: | ||
| - uses: actions/checkout@v7 | ||
| - uses: actions/setup-node@v7 | ||
| with: | ||
| node-version: "22" | ||
| cache: "npm" | ||
| cache-dependency-path: "**/package-lock.json" | ||
| # The interpreter-discovery tests need Python and R installed so | ||
| # Positron's runtime discovery can find them. | ||
| - uses: actions/setup-python@v7 | ||
| with: | ||
| python-version: "3.12" | ||
| - uses: r-lib/actions/setup-r@v2 | ||
| with: | ||
| r-version: "4.4" | ||
| - id: get-date | ||
| run: echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT | ||
| shell: bash | ||
| - uses: actions/cache/restore@v6 | ||
| id: cache | ||
| with: | ||
| path: ./extensions/vscode/.positron-test | ||
| key: positron-${{ env.POSITRON_CHANNEL }}-${{ steps.get-date.outputs.date }} | ||
| - run: npm ci --no-audit --no-fund | ||
| - name: Run Positron API tests | ||
| uses: posit-dev/setup-positron@main | ||
| with: | ||
| positron-channel: ${{ env.POSITRON_CHANNEL }} | ||
| working-directory: extensions/vscode | ||
| run: npm run test-positron | ||
| - uses: actions/cache/save@v6 | ||
| if: steps.cache.outputs.cache-hit != 'true' | ||
| with: | ||
| path: ./extensions/vscode/.positron-test | ||
| key: positron-${{ env.POSITRON_CHANNEL }}-${{ steps.get-date.outputs.date }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,4 +2,5 @@ out | |
| dist | ||
| node_modules | ||
| .vscode-test/ | ||
| .positron-test/ | ||
| *.vsix | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| import { defineConfig } from "@vscode/test-cli"; | ||
|
|
||
| export default defineConfig({ | ||
| files: "out/test/**/*.test.js", | ||
| // Only the plain VSCode suite; out/test/positron/ holds the Positron-only | ||
| // tests, which are run by `npm run test-positron` inside a Positron build. | ||
| files: "out/test/suite/**/*.test.js", | ||
| workspaceFolder: `${import.meta.dirname}/../../../../test/sample-content/fastapi-simple`, | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| // Copyright (C) 2026 by Posit Software, PBC. | ||
|
|
||
| // Launcher for the Positron-only integration tests (src/test/positron/). | ||
| // | ||
| // Downloads (or reuses a cached) Positron build and runs the compiled Mocha | ||
| // entry point (out/test/positron/index.js) inside it, via | ||
| // @posit-dev/positron-test-electron. | ||
| // | ||
| // Run with `npm run test-positron` (which builds the extension and tests | ||
| // first). Set POSITRON_CHANNEL=daily to test against a daily Positron build | ||
| // (default: stable). | ||
| // | ||
| // NOTE: the released @posit-dev/positron-test-electron supports macOS only; | ||
| // Windows/Linux support has landed upstream and is pending an npm release. | ||
|
|
||
| import * as path from "node:path"; | ||
| import { fileURLToPath } from "node:url"; | ||
| import { runTests } from "@posit-dev/positron-test-electron"; | ||
|
|
||
| const __dirname = path.dirname(fileURLToPath(import.meta.url)); | ||
|
|
||
| async function main() { | ||
| // Extension root (contains package.json); scripts/ lives one level below it. | ||
| const extensionDevelopmentPath = path.resolve(__dirname, ".."); | ||
|
|
||
| // Compiled Mocha entry point that discovers and runs the Positron tests. | ||
| const extensionTestsPath = path.resolve( | ||
| extensionDevelopmentPath, | ||
| "out", | ||
| "test", | ||
| "positron", | ||
| "index.js", | ||
| ); | ||
|
|
||
| // Publisher activates on workspaceContains:/ — open the same sample project | ||
| // the plain VSCode suite uses (.vscode-test.mjs). | ||
| const workspacePath = path.resolve( | ||
| extensionDevelopmentPath, | ||
| "..", | ||
| "..", | ||
| "test", | ||
| "sample-content", | ||
| "fastapi-simple", | ||
| ); | ||
|
|
||
| const code = await runTests({ | ||
| channel: process.env.POSITRON_CHANNEL === "daily" ? "daily" : "stable", | ||
| extensionDevelopmentPath, | ||
| extensionTestsPath, | ||
| // The interpreter-discovery tests need Positron's bundled runtime | ||
| // extensions (Python, Ark/R) to register language runtimes, so opt out of | ||
| // the default --disable-extensions. Copilot is bundled too and spams the | ||
| // logs with failed GitHub auth attempts on credential-less machines, so | ||
| // disable it individually. | ||
| disableExtensions: false, | ||
| launchArgs: [ | ||
| workspacePath, | ||
| "--disable-workspace-trust", | ||
| "--disable-extension", | ||
| "GitHub.copilot-chat", | ||
| ], | ||
| }); | ||
|
|
||
| process.exit(code); | ||
| } | ||
|
|
||
| main().catch((err) => { | ||
| console.error("Failed to run Positron integration tests:"); | ||
| console.error(err); | ||
| process.exit(1); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| # Positron API Tests | ||
|
|
||
| Integration tests that run the Publisher extension inside a real | ||
| [Positron](https://positron.posit.co/) build and exercise its use of the | ||
| Positron API — code paths that the plain VSCode suite (`src/test/suite/`) and | ||
| the mock-based contract tests (`test/extension-contract-tests/`) can't reach. | ||
|
|
||
| Part of the rollout tracked in | ||
| [posit-dev/positron#14531](https://github.com/posit-dev/positron/issues/14531). | ||
|
|
||
| ## How it works | ||
|
|
||
| - `scripts/run-positron-tests.mjs` uses | ||
| [`@posit-dev/positron-test-electron`](https://github.com/posit-dev/positron-test-electron) | ||
| to download (and cache, under `.positron-test/`) a Positron build, then runs | ||
| the compiled Mocha entry point (`out/test/positron/index.js`) inside its | ||
| extension host — the Positron analog of `@vscode/test-electron`. | ||
| - `index.ts` is that entry point: it discovers `*.test.js` files in this | ||
| directory and runs them with Mocha (tdd UI). | ||
| - Tests are compiled by `esbuild.tests.mjs` along with the plain suite; the | ||
| two are kept apart by directory (`out/test/suite/` vs `out/test/positron/`). | ||
| - Positron's bundled extensions are left enabled (no `--disable-extensions`) | ||
| because runtime discovery — which Publisher's interpreter resolution relies | ||
| on — is provided by the bundled Python and Ark (R) extensions. | ||
|
|
||
| ## Running locally | ||
|
|
||
| ```bash | ||
| npm run test-positron # against the latest stable Positron | ||
| POSITRON_CHANNEL=daily npm run test-positron # against a daily build | ||
| ``` | ||
|
|
||
| > **Note:** the released `@posit-dev/positron-test-electron` supports **macOS | ||
| > only**; Windows/Linux support has landed upstream | ||
| > ([posit-dev/positron-test-electron#3](https://github.com/posit-dev/positron-test-electron/issues/3)) | ||
| > and is pending an npm release. Until then, on other platforms rely on the | ||
| > `Positron-API-Tests` GitHub Actions workflow | ||
| > (`.github/workflows/positron-api-tests.yaml`), which runs on every PR and | ||
| > push to `main`. | ||
|
|
||
| The interpreter-discovery tests expect a Python and an R installation that | ||
| Positron can discover on the machine. | ||
|
|
||
| ## Adding tests | ||
|
|
||
| Add a `<name>.test.ts` file in this directory using Mocha's tdd UI | ||
| (`suite`/`test`). Things to know: | ||
|
|
||
| - The Positron API is reached through the `acquirePositronApi()` global that | ||
| Positron injects into the extension host (typed by | ||
| `src/@types/positron.d.ts`). Publisher's own code feature-detects Positron | ||
| the same way (`src/utils/vscode.ts`). | ||
| - Prefer testing Publisher's real behavior at the API boundary: import the | ||
| extension source (e.g. `import { ... } from "src/utils/vscode"`) and assert | ||
| on what it sends to / receives from the live API. | ||
| - Runtime discovery is asynchronous and can be slow on cold CI machines; wait | ||
| for Positron to report a runtime before asserting on code that depends on | ||
| one (see `waitForPreferredRuntime` in `interpreter-discovery.test.ts`). | ||
| - Keep tests independent of a live kernel actually starting whenever possible | ||
| — metadata-level assertions (`getPreferredRuntime`) are much faster and less | ||
| flaky than session-level ones. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| // Copyright (C) 2026 by Posit Software, PBC. | ||
|
|
||
| // Positron-only integration test. | ||
| // | ||
| // Sanity checks for the contract Publisher depends on when running inside | ||
| // Positron: the extension host injects an `acquirePositronApi` global | ||
| // (Publisher feature-detects Positron by calling it — see | ||
| // src/utils/vscode.ts), and the Publisher extension activates. | ||
|
|
||
| import * as assert from "assert"; | ||
| import { extensions } from "vscode"; | ||
|
|
||
| suite("Positron: extension host", () => { | ||
| test("Positron injects the acquirePositronApi global", () => { | ||
| assert.strictEqual( | ||
| typeof acquirePositronApi, | ||
| "function", | ||
| "the extension host should provide the acquirePositronApi global", | ||
| ); | ||
|
|
||
| const api = acquirePositronApi(); | ||
| assert.ok(api, "acquirePositronApi() should return the Positron API"); | ||
| assert.strictEqual(typeof api.version, "string"); | ||
| assert.ok( | ||
| api.version.length > 0, | ||
| "the Positron API should report a version", | ||
| ); | ||
| }); | ||
|
|
||
| test("Publisher activates in Positron", async () => { | ||
| const publisher = extensions.getExtension("posit.publisher"); | ||
| assert.ok( | ||
| publisher, | ||
| "posit.publisher should be present in the extension host", | ||
| ); | ||
|
|
||
| await publisher.activate(); | ||
| assert.ok(publisher.isActive, "Publisher should activate without error"); | ||
| }); | ||
| }); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be worth a note in #3647 to update this ref when we start using the
@posit-dev/positrontypes package.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add a note in #3647