Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 33 additions & 18 deletions common/config/subspaces/default/pnpm-lock.yaml

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

2 changes: 1 addition & 1 deletion common/config/subspaces/default/repo-state.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush.
{
"pnpmShrinkwrapHash": "b0dbc9dd6df6e790055edb199b9d85eb3a0f200f",
"pnpmShrinkwrapHash": "558d394293c3672c682dbbb67d513799873503f3",
"preferredVersionsHash": "a9b67c38568259823f9cfb8270b31bf6d8470b27"
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
"build": "heft build --clean",
"build:watch": "heft build-watch",
"start": "heft start",
"pretest": "npm run build",
"test": "node ./lib/test/runTest.js",
"_phase:build": "heft run --only build -- --clean",
"_phase:test": ""
},
Expand Down Expand Up @@ -106,8 +108,13 @@
"@rushstack/heft-vscode-extension-rig": "workspace:*",
"@rushstack/heft-node-rig": "workspace:*",
"@rushstack/heft": "workspace:*",
"@types/glob": "7.1.1",
"@types/mocha": "10.0.6",
"@types/node": "20.17.19",
"@types/vscode": "1.103.0",
"@types/webpack-env": "1.18.8"
"@types/webpack-env": "1.18.8",
"@vscode/test-electron": "^1.6.2",
"glob": "~7.0.5",
"mocha": "^10.1.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# VS Code Extension Tests

This directory contains the test harness for the Playwright Local Browser Server VS Code extension using the VS Code Extension Host.

## Test Structure

- **runTest.ts**: Entry point for running tests. Uses `@vscode/test-electron` to download VS Code and run the test suite.
- **suite/index.ts**: Mocha test suite configuration that discovers and runs all `*.test.js` files.
- **suite/extension.test.ts**: Main test file containing tests for:
- Extension installation and activation
- Command registration validation
- Command execution tests
- Package.json command validation

## Running Tests

To run the tests:

```bash
npm test
```

Or using Rush from the repository root:

```bash
rush test --to playwright-local-browser-server
```

The `pretest` script automatically builds the extension before running tests.

## Test Coverage

The test suite validates:

1. **Extension Presence**: Verifies the extension is installed
2. **Extension Activation**: Ensures the extension activates correctly
3. **Command Registration**: Validates all commands from package.json are registered:
- `playwright-local-browser-server.start`
- `playwright-local-browser-server.stop`
- `playwright-local-browser-server.manageAllowlist`
- `playwright-local-browser-server.showLog`
- `playwright-local-browser-server.showSettings`
- `playwright-local-browser-server.showMenu`
4. **Command Execution**: Tests non-interactive commands (`showLog`, `showSettings`)

## Limitations

- Interactive commands (`start`, `stop`, `manageAllowlist`, `showMenu`) are tested for registration but not execution, as they show dialogs that would block automated testing
- Tests require network access to download VS Code on first run
- The downloaded VS Code instance is cached by `@vscode/test-electron`

## Test Framework

- **Test Runner**: [VS Code Extension Test](https://code.visualstudio.com/api/working-with-extensions/testing-extension)
- **Test Framework**: [Mocha](https://mochajs.org/)
- **Assertions**: Node.js `assert` module

## Future Improvements

To test interactive commands without blocking on dialogs, consider:
- Mocking VS Code UI interactions
- Using dependency injection to allow testing without user interaction
- Creating unit tests for command handlers separately from integration tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

import * as path from 'path';

import { runTests } from '@vscode/test-electron';

async function main(): Promise<void> {
try {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
const extensionDevelopmentPath: string = path.resolve(__dirname, '../../');

// The path to test runner
// Passed to --extensionTestsPath
const extensionTestsPath: string = path.resolve(__dirname, './suite/index');

// Download VS Code, unzip it and run the integration test
await runTests({ extensionDevelopmentPath, extensionTestsPath });
} catch (err) {
// eslint-disable-next-line no-console
console.error('Failed to run tests');
process.exit(1);
}
}

// eslint-disable-next-line @typescript-eslint/no-floating-promises
main();
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

import * as assert from 'assert';
import * as vscode from 'vscode';

suite('Playwright Local Browser Server Extension Test Suite', () => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
vscode.window.showInformationMessage('Start all tests.');

test('Extension should be present', () => {
const extensionId: string = 'ms-RushStack.playwright-local-browser-server';
const extension: vscode.Extension<unknown> | undefined = vscode.extensions.getExtension(extensionId);
assert.ok(extension, `Extension ${extensionId} should be installed`);
});

test('Extension should activate', async () => {
const extensionId: string = 'ms-RushStack.playwright-local-browser-server';
const extension: vscode.Extension<unknown> | undefined = vscode.extensions.getExtension(extensionId);
assert.ok(extension, 'Extension should be installed');

await extension.activate();
assert.strictEqual(extension.isActive, true, 'Extension should be active');
});

suite('Command Registration Tests', () => {
const commands: string[] = [
'playwright-local-browser-server.start',
'playwright-local-browser-server.stop',
'playwright-local-browser-server.manageAllowlist',
'playwright-local-browser-server.showLog',
'playwright-local-browser-server.showSettings',
'playwright-local-browser-server.showMenu'
];

commands.forEach((commandId) => {
test(`Command '${commandId}' should be registered`, async () => {
const allCommands: string[] = await vscode.commands.getCommands(true);
assert.ok(allCommands.includes(commandId), `Command '${commandId}' should be registered`);
});
});
});

suite('Command Execution Tests', () => {
suiteSetup(async () => {
// Ensure extension is activated before testing command execution
const extensionId: string = 'ms-RushStack.playwright-local-browser-server';
const extension: vscode.Extension<unknown> | undefined = vscode.extensions.getExtension(extensionId);
if (extension && !extension.isActive) {
await extension.activate();
}
});

test('Command playwright-local-browser-server.showLog should execute without error', async () => {
await vscode.commands.executeCommand('playwright-local-browser-server.showLog');
// If we get here without throwing, the command executed successfully
assert.ok(true, 'showLog command executed');
});

test('Command playwright-local-browser-server.showSettings should execute without error', async () => {
await vscode.commands.executeCommand('playwright-local-browser-server.showSettings');
// If we get here without throwing, the command executed successfully
assert.ok(true, 'showSettings command executed');
});

// Note: We skip testing start, stop, manageAllowlist, and showMenu commands
// because they show interactive dialogs that would block automated testing.
// In a real-world scenario, these would need to be mocked or use
// dependency injection to allow testing without user interaction.
});

suite('Package.json Command Validation', () => {
test('All commands in package.json should be registered', async () => {
// Get the extension's package.json
const extensionId: string = 'ms-RushStack.playwright-local-browser-server';
const extension: vscode.Extension<unknown> | undefined = vscode.extensions.getExtension(extensionId);
assert.ok(extension, 'Extension should be installed');

const packageJson: { contributes?: { commands?: Array<{ command: string }> } } = extension.packageJSON;
const contributedCommands: string[] =
packageJson.contributes?.commands?.map((cmd: { command: string }) => cmd.command) || [];

// Get all registered commands
const allCommands: string[] = await vscode.commands.getCommands(true);

// Verify each contributed command is registered
for (const commandId of contributedCommands) {
assert.ok(
allCommands.includes(commandId),
`Command '${commandId}' from package.json should be registered`
);
}
});
});
});
Loading