Skip to content

Commit 07f42d1

Browse files
committed
Improve test stability with ensureEditorServicesIsConnected
This uses a newly added `ExternalApi` function `waitUntilStarted` that ensures the LSP server (PowerShell session) is started after manually activating the extension.
1 parent 5eeaf7a commit 07f42d1

File tree

6 files changed

+44
-12
lines changed

6 files changed

+44
-12
lines changed

src/features/ExternalApi.ts

+31-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface IPowerShellExtensionClient {
1818
registerExternalExtension(id: string, apiVersion?: string): string;
1919
unregisterExternalExtension(uuid: string): boolean;
2020
getPowerShellVersionDetails(uuid: string): Promise<IExternalPowerShellDetails>;
21+
waitUntilStarted(uuid: string): Promise<void>;
2122
}
2223

2324
/*
@@ -99,6 +100,16 @@ export class ExternalApiFeature extends LanguageClientConsumer implements IPower
99100
return true;
100101
}
101102

103+
private getRegisteredExtension(uuid: string = ""): IExternalExtension {
104+
if (!ExternalApiFeature.registeredExternalExtension.has(uuid)) {
105+
throw new Error(
106+
"UUID provided was invalid, make sure you ran the 'powershellExtensionClient.registerExternalExtension(extensionId)' method and pass in the UUID that it returns to subsequent methods.");
107+
}
108+
109+
// TODO: When we have more than one API version, make sure to include a check here.
110+
return ExternalApiFeature.registeredExternalExtension.get(uuid);
111+
}
112+
102113
/*
103114
DESCRIPTION:
104115
This will fetch the version details of the PowerShell used to start
@@ -118,13 +129,7 @@ export class ExternalApiFeature extends LanguageClientConsumer implements IPower
118129
}
119130
*/
120131
public async getPowerShellVersionDetails(uuid: string = ""): Promise<IExternalPowerShellDetails> {
121-
if (!ExternalApiFeature.registeredExternalExtension.has(uuid)) {
122-
throw new Error(
123-
"UUID provided was invalid, make sure you ran the 'powershellExtensionClient.registerExternalExtension(extensionId)' method and pass in the UUID that it returns to subsequent methods.");
124-
}
125-
126-
// TODO: When we have more than one API version, make sure to include a check here.
127-
const extension = ExternalApiFeature.registeredExternalExtension.get(uuid);
132+
const extension = this.getRegisteredExtension(uuid);
128133
this.log.writeDiagnostic(`Extension '${extension.id}' called 'getPowerShellVersionDetails'`);
129134

130135
await this.sessionManager.waitUntilStarted();
@@ -137,6 +142,25 @@ export class ExternalApiFeature extends LanguageClientConsumer implements IPower
137142
architecture: versionDetails.architecture
138143
};
139144
}
145+
/*
146+
DESCRIPTION:
147+
This will wait until the extension's PowerShell session is started.
148+
149+
USAGE:
150+
powerShellExtensionClient.waitUntilStarted(
151+
"uuid"); // the uuid from above for tracking purposes
152+
153+
RETURNS:
154+
A void promise that resolves only once the extension is started.
155+
156+
If the extension is not started by some mechanism
157+
then this will wait indefinitely.
158+
*/
159+
public async waitUntilStarted(uuid: string = ""): Promise<void> {
160+
const extension = this.getRegisteredExtension(uuid);
161+
this.log.writeDiagnostic(`Extension '${extension.id}' called 'waitUntilStarted'`);
162+
return this.sessionManager.waitUntilStarted();
163+
}
140164

141165
public dispose() {
142166
// Nothing to dispose.

src/main.ts

+1
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ export function activate(context: vscode.ExtensionContext): IPowerShellExtension
175175
registerExternalExtension: (id: string, apiVersion: string = 'v1') => externalApi.registerExternalExtension(id, apiVersion),
176176
unregisterExternalExtension: uuid => externalApi.unregisterExternalExtension(uuid),
177177
getPowerShellVersionDetails: uuid => externalApi.getPowerShellVersionDetails(uuid),
178+
waitUntilStarted: uuid => externalApi.waitUntilStarted(uuid),
178179
};
179180
}
180181

test/core/paths.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as vscode from "vscode";
88
import utils = require("../utils");
99

1010
describe("Path assumptions", function () {
11-
before(utils.ensureExtensionIsActivated);
11+
before(utils.ensureEditorServicesIsConnected);
1212

1313
// TODO: This is skipped because it intereferes with other tests. Either
1414
// need to find a way to close the opened folder via a Code API, or find

test/features/ISECompatibility.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe("ISE compatibility feature", function () {
1515
before(async function () {
1616
// Save user's current theme.
1717
currentTheme = await vscode.workspace.getConfiguration("workbench").get("colorTheme");
18-
await utils.ensureExtensionIsActivated();
18+
await utils.ensureEditorServicesIsConnected();
1919
});
2020

2121
after(async function () {

test/features/RunCode.test.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ enum LaunchType {
1919
}
2020

2121
describe("RunCode feature", function () {
22-
before(utils.ensureExtensionIsActivated);
22+
before(utils.ensureEditorServicesIsConnected);
2323

2424
it("Creates the launch config", function () {
2525
const commandToRun: string = "Invoke-Build";
@@ -49,8 +49,6 @@ describe("RunCode feature", function () {
4949
// Open the PowerShell file with Pester tests and then wait a while for
5050
// the extension to finish connecting to the server.
5151
await vscode.commands.executeCommand("vscode.open", vscode.Uri.file(pesterTests));
52-
// TODO: Find a non-sleep way to wait for the connection to establish.
53-
await sleep(15000);
5452

5553
// Now run the Pester tests, check the debugger started, wait a bit for
5654
// it to run, and then kill it for safety's sake.

test/utils.ts

+9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import * as path from "path";
77
import * as vscode from "vscode";
8+
import { IPowerShellExtensionClient } from "../src/features/ExternalApi";
89

910
// This lets us test the rest of our path assumptions against the baseline of
1011
// this test file existing at `<root>/out/test/utils.js`.
@@ -18,3 +19,11 @@ export async function ensureExtensionIsActivated(): Promise<vscode.Extension<any
1819
if (!extension.isActive) { await extension.activate(); }
1920
return extension;
2021
}
22+
23+
export async function ensureEditorServicesIsConnected(): Promise<void> {
24+
const powershellExtension = await ensureExtensionIsActivated();
25+
const client = powershellExtension!.exports as IPowerShellExtensionClient;
26+
const sessionId = client.registerExternalExtension(extensionId);
27+
await client.waitUntilStarted(sessionId);
28+
client.unregisterExternalExtension(sessionId);
29+
}

0 commit comments

Comments
 (0)