Skip to content

Commit

Permalink
pw_ide: Add VSC end-to-end extension testing
Browse files Browse the repository at this point in the history
Change-Id: Ibfef13be5b7e8cf5b374ce7d1a23df2a669835b7
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/260973
Presubmit-Verified: CQ Bot Account <[email protected]>
Lint: Lint 🤖 <[email protected]>
Reviewed-by: Chad Norvell <[email protected]>
Docs-Not-Needed: Asad Memon <[email protected]>
Commit-Queue: Asad Memon <[email protected]>
Pigweed-Auto-Submit: Asad Memon <[email protected]>
  • Loading branch information
asadm authored and CQ Bot Account committed Feb 11, 2025
1 parent cb8a650 commit 9ea3210
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ yarn-error.log

# pw_ide
.pw_ide.user.yaml
.vscode-test

# Emboss
*.emb.h
Expand Down
25 changes: 25 additions & 0 deletions pw_ide/ts/pigweed-vscode/.vscode-test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2025 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

import { defineConfig } from '@vscode/test-cli';
import path from 'path';

export default defineConfig({
files: 'out/**/*.e2e.test.js',
workspaceFolder: path.join(process.cwd(), '..', '..', '..'),
mocha: {
timeout: 60000
},
launchArgs: ['--install-extension', 'BazelBuild.vscode-bazel']
});
14 changes: 12 additions & 2 deletions pw_ide/ts/pigweed-vscode/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions pw_ide/ts/pigweed-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
"bundle": "webpack --mode production --devtool hidden-source-map",
"watch:build": "tsc -watch -p ./",
"watch:bundle": "webpack --mode development --watch",
"watch:e2e": "tsc -watch -p tsconfig.e2e.json",
"lint": "eslint src --ext ts",
"prePackage": "tsx scripts/prepostPackage.mts --pre",
"doPackage": "vsce package",
Expand All @@ -170,7 +171,7 @@
"package": "npm run clean && npm run build && npm run bundle && npm run prePackage && npm run doPackage && npm run postPackage",
"packagePrerelease": "npm run clean && npm run build && npm run bundle && npm run prePackage && npm run doPackagePrerelease && npm run postPackage",
"test:jest": "jest '.*.test.ts'",
"test:vscode": "vscode-test"
"test:e2e": "vscode-test"
},
"dependencies": {
"@bazel/bazelisk": "^1.19.0",
Expand All @@ -186,17 +187,19 @@
"@types/hjson": "^2.4.6",
"@types/jest": "29.5.12",
"@types/js-yaml": "^4.0.9",
"@types/mocha": "^10.0.1",
"@types/node": "^20.14.10",
"@types/vscode": "^1.75.0",
"@typescript-eslint/eslint-plugin": "^7.16.0",
"@typescript-eslint/parser": "^7.16.0",
"@vscode/test-cli": "^0.0.10",
"@vscode/test-electron": "^2.4.1",
"@vscode/test-electron": "^2.3.9",
"eslint": "^8.56.0",
"prettier": "^3.3.2",
"rimraf": "^6.0.1",
"jest": "^29.7.0",
"mocha": "^10.2.0",
"node-polyfill-webpack-plugin": "^4.0.0",
"prettier": "^3.3.2",
"rimraf": "^6.0.1",
"ts-jest": "^29.2.2",
"ts-loader": "^9.5.1",
"tsx": "^4.16.2",
Expand Down
7 changes: 4 additions & 3 deletions pw_ide/ts/pigweed-vscode/src/clangd/bazel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ export const clangdPath = () =>
const createClangdSymlinkTarget = ':copy_clangd' as const;

/** Create the `clangd` symlink and add it to settings. */
export async function initBazelClangdPath(): Promise<void> {
export async function initBazelClangdPath(): Promise<boolean> {
logger.info('Ensuring presence of stable clangd symlink');
const cwd = (await getPigweedProjectRoot(settings, workingDir)) as string;
const cmd = getReliableBazelExecutable();

if (!cmd) {
logger.error("Couldn't find a Bazel or Bazelisk executable");
return;
return false;
}

const args = ['build', createClangdSymlinkTarget];
Expand Down Expand Up @@ -68,8 +68,9 @@ export async function initBazelClangdPath(): Promise<void> {
});
});

if (!success) return;
if (!success) return false;

const { update: updatePath } = stringSettingFor('path', 'clangd');
await updatePath(clangdPath());
return true;
}
38 changes: 38 additions & 0 deletions pw_ide/ts/pigweed-vscode/src/hello.e2e.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2025 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

import * as assert from 'assert';
import * as vscode from 'vscode';
import { initBazelClangdPath } from './clangd/bazel';
import { executeInTerminalAndGetStdout } from './terminal';
import { patchBazeliskIntoTerminalPath } from './terminal';

suite('Extension Test Suite', () => {
vscode.window.showInformationMessage('Starting tests.');
test('Clang init', async () => {
const success = await initBazelClangdPath();
assert.strictEqual(success, true);
});

test('Bazel build test', async () => {
await patchBazeliskIntoTerminalPath();
const output = await executeInTerminalAndGetStdout(
'bazel build //pw_status',
);
assert.strictEqual(
output.indexOf('Build completed successfully') > 0,
true,
);
});
});
51 changes: 51 additions & 0 deletions pw_ide/ts/pigweed-vscode/src/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import * as fs from 'fs';
import * as path from 'path';
import * as process from 'process';
import * as os from 'os';
import { randomBytes } from 'crypto';

// Convert `exec` from callback style to promise style.
import { exec as cbExec } from 'child_process';
Expand Down Expand Up @@ -217,3 +219,52 @@ export async function patchBazeliskIntoTerminalPath(
terminal.sendText(cmd, true);
terminal.show();
}

/**
* This method runs the given commands in the active terminal
* and returns the output text. Currently, the API does not
* support reading terminal buffer so instead, we pipe output
* to a temp text file and then read it out once execution
* has completed.
*/
export async function executeInTerminalAndGetStdout(
cmd: string,
): Promise<string> {
const terminal = vscode.window.activeTerminal;

if (!terminal) {
throw new Error('No active terminal found.');
}

const tmpDir = os.tmpdir();
const randomOutputFileName = `vscode-terminal-output-${randomBytes(
8,
).toString('hex')}.txt`;
const randomDoneFileName = `vscode-terminal-done-${randomBytes(8).toString(
'hex',
)}.txt`;
const tmpOutputFilePath = path.join(tmpDir, randomOutputFileName);
const tmpDoneFilePath = path.join(tmpDir, randomDoneFileName);

try {
// Construct the command to redirect output to the temp file and then touch the done file
const commandToExecute = `${cmd} &> ${tmpOutputFilePath} && touch ${tmpDoneFilePath}\n`;

terminal.sendText(commandToExecute);

// Wait for the done file to exist
while (!fs.existsSync(tmpDoneFilePath)) {
await new Promise((resolve) => setTimeout(resolve, 10));
}

const output = fs.readFileSync(tmpOutputFilePath, 'utf-8');
return output;
} catch (error) {
console.error('Error during command execution:', error);
throw error;
} finally {
// Delete the temporary files
fs.unlinkSync(tmpOutputFilePath);
fs.unlinkSync(tmpDoneFilePath);
}
}
15 changes: 15 additions & 0 deletions pw_ide/ts/pigweed-vscode/src/types/node_modules-path.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2025 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

declare module 'node_modules-path';
25 changes: 25 additions & 0 deletions pw_ide/ts/pigweed-vscode/tsconfig.e2e.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2020",
"lib": [
"es2020"
],
"outDir": "out",
"esModuleInterop": true,
"sourceMap": true,
"rootDir": ".",
"strict": true,
"types": [
"node",
"mocha"
],
"typeRoots": [
"./node_modules/@types",
"./src/types"
]
},
"include": [
"**/*.e2e.test.ts"
]
}
3 changes: 2 additions & 1 deletion pw_ide/ts/pigweed-vscode/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"strict": true
},
"exclude": [
"*.js"
"*.js",
"**/*.e2e.test.ts"
]
}

0 comments on commit 9ea3210

Please sign in to comment.