Skip to content

Commit df11864

Browse files
authored
Add extension activation test case (#2407)
1 parent 3016b3b commit df11864

6 files changed

Lines changed: 127 additions & 46 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for details.
3+
4+
import { Page } from "playwright";
5+
import { SmokeTestLogger } from "./helper/smokeTestLogger";
6+
import { app, screenshots } from "./main";
7+
import assert = require("assert");
8+
9+
export function startExtensionActivationTests(): void {
10+
describe("ExtensionActivationTest", () => {
11+
async function initApp(): Promise<Page> {
12+
await app.launch();
13+
return app.getMainPage();
14+
}
15+
16+
async function dispose() {
17+
try {
18+
if (this.currentTest?.state === "failed") {
19+
SmokeTestLogger.info("Test failed, taking screenshot ...");
20+
await screenshots.takeScreenshots(
21+
this.currentTest.parent?.title || "Others",
22+
this.currentTest.title.replace(/\s+/g, "_"),
23+
);
24+
}
25+
} catch (error) {
26+
// Log error when screenshot get error, but not throw exception
27+
SmokeTestLogger.log(`Error with taking screenshot: ${error}`);
28+
}
29+
30+
try {
31+
SmokeTestLogger.info(`Dispose test: "${this.currentTest.title}" ...`);
32+
if (app) {
33+
await app.close();
34+
}
35+
} catch (error) {
36+
SmokeTestLogger.error(`Error while dispose: ${error}`);
37+
}
38+
}
39+
40+
afterEach(dispose);
41+
42+
it("Verify extension is activated", async () => {
43+
const page = await initApp();
44+
const isActivited = await app.getExtension().checkExtensionActivated(page);
45+
assert.ok(isActivited, "Extension is not activated. Skip other test cases...");
46+
});
47+
});
48+
}

test/smoke/suites/commands.test.ts

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,58 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for details.
33

4+
import { Page } from "playwright";
45
import { SmokeTestLogger } from "./helper/smokeTestLogger";
56
import { app, screenshots } from "./main";
67
import * as assert from "assert";
78

89
export function startCommandPaletteTests(): void {
9-
describe("Command palette test", () => {
10-
async function initApp(): Promise<void> {
10+
describe("CommandPaletteTest", () => {
11+
async function initApp(): Promise<Page> {
1112
await app.launch();
13+
return app.getMainPage();
1214
}
1315

14-
async function disposeAll() {
16+
async function dispose() {
1517
try {
16-
SmokeTestLogger.info("Dispose all ...");
18+
if (this.currentTest?.state === "failed") {
19+
SmokeTestLogger.info("Test failed, taking screenshot ...");
20+
await screenshots.takeScreenshots(
21+
this.currentTest.parent?.title || "Others",
22+
this.currentTest.title.replace(/\s+/g, "_"),
23+
);
24+
}
25+
} catch (error) {
26+
// Log error when screenshot get error, but not throw exception
27+
SmokeTestLogger.log(`Error with taking screenshot: ${error}`);
28+
}
29+
30+
try {
31+
SmokeTestLogger.info(`Dispose test: "${this.currentTest.title}" ...`);
1732
if (app) {
18-
SmokeTestLogger.info("Stopping application ...");
1933
await app.close();
2034
}
2135
} catch (error) {
22-
SmokeTestLogger.error("Error while disposeAll:");
23-
SmokeTestLogger.error(error);
36+
SmokeTestLogger.error(`Error while dispose: ${error}`);
2437
}
2538
}
2639

27-
afterEach(disposeAll);
40+
afterEach(dispose);
2841

2942
it("Verify react native command is visible in command palette", async () => {
30-
await initApp();
31-
const page = app.getMainPage();
43+
const page = await initApp();
3244

3345
const cmdKey = process.platform === "darwin" ? "Meta" : "Control";
34-
3546
await page.keyboard.press(`${cmdKey}+Shift+P`);
3647
await page.waitForSelector(".quick-input-widget", { timeout: 10000 });
3748

3849
await page.keyboard.type("React Native: Start Packager");
39-
4050
const option = await page.waitForSelector("#quickInput_list .monaco-list-row.focused", {
4151
timeout: 30000,
4252
});
43-
const value = await option.getAttribute("aria-label");
4453

45-
try {
46-
assert.ok(value?.includes("React Native: Start Packager"));
47-
} catch {
48-
await screenshots.takeScreenshots("CommandPaletteTest", "VerifyCommandVisible");
49-
}
54+
const value = await option.getAttribute("aria-label");
55+
assert.ok(value?.includes("React Native: Start Packager"));
5056
});
5157
});
5258
}

test/smoke/suites/helper/application.ts

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ export class Application {
1414
private app: ElectronApplication | null = null;
1515
private mainPage: Page | null = null;
1616
private extension: Extension | null = null;
17+
private vscodeExecutablePath: string | null = null;
18+
private isExtensionActivited: boolean = false;
1719
private extensionDirectory = path.join(__dirname, "..", "..", ".vscode-test", "extensions");
1820
private userDataDirectory = path.join(__dirname, "..", "..", ".vscode-test", "temp-user-data");
1921
private vsixDirectory = path.join(__dirname, "..", "..", "resources", "extension");
@@ -27,8 +29,11 @@ export class Application {
2729
async launch(): Promise<Page> {
2830
if (this.mainPage) return this.mainPage;
2931

30-
const vscodeExecutablePath = await this.downloadVSCodeExecutable();
32+
if (!this.vscodeExecutablePath) {
33+
throw new Error("VSCode has not been downloaded yet.");
34+
}
3135

36+
const vscodeExecutablePath = this.vscodeExecutablePath;
3237
const [...args] = resolveCliArgsFromVSCodeExecutablePath(vscodeExecutablePath);
3338
args.push("--disable-workspace-trust");
3439
args.push("--no-sandbox");
@@ -59,14 +64,6 @@ export class Application {
5964
SmokeTestLogger.info("Cannot clean up user data, will try it again in test setup.");
6065
}
6166

62-
try {
63-
await this.cleanExtensionData();
64-
} catch {
65-
SmokeTestLogger.info(
66-
"Cannot clean up extension data, will try it again in test setup.",
67-
);
68-
}
69-
7067
if (this.app) {
7168
await this.app.close();
7269
this.app = null;
@@ -91,8 +88,9 @@ export class Application {
9188
utilities.spawnSync(cliPath, args, { stdio: "inherit" });
9289
}
9390

94-
this.extension = new Extension();
95-
return this.extension;
91+
const extension = new Extension();
92+
this.extension = extension;
93+
return extension;
9694
}
9795

9896
getMainPage(): Page {
@@ -102,6 +100,28 @@ export class Application {
102100
return this.mainPage;
103101
}
104102

103+
getExtension(): Extension {
104+
if (!this.extension) {
105+
throw new Error("VSCode has not been launched yet.");
106+
}
107+
return this.extension;
108+
}
109+
110+
setVSCodeExecutablePath(vscodeExecutablePath: string) {
111+
this.vscodeExecutablePath = vscodeExecutablePath;
112+
}
113+
114+
setExtensionStatus(isActivited: boolean) {
115+
this.isExtensionActivited = isActivited;
116+
}
117+
118+
getExtensionStatus(): boolean {
119+
if (!this.isExtensionActivited) {
120+
throw new Error("Cannot get extension status.");
121+
}
122+
return this.isExtensionActivited;
123+
}
124+
105125
async cleanUserData(): Promise<void> {
106126
if (fs.existsSync(this.userDataDirectory)) {
107127
SmokeTestLogger.info(
Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1-
import { app } from "../main";
2-
import { waitConditionUntil } from "./utilities";
1+
import { Page } from "playwright";
2+
import { SmokeTestLogger } from "./smokeTestLogger";
33

44
export class Extension {
5-
private application = app;
6-
private extensionId = "msjsdiag.vscode-react-native";
5+
async checkExtensionActivated(page: Page): Promise<boolean> {
6+
const prodExtensionId = "msjsdiag.vscode-react-native.togglePackagerItem";
7+
const previewExtensionId = "msjsdiag.vscode-react-native-preview.togglePackagerItem";
78

8-
async waitForExtensionActive(): Promise<void> {
9-
const mainPage = this.application.getMainPage();
10-
if (!mainPage) {
11-
throw new Error("VSCode must be launched before waiting for extension activation.");
9+
try {
10+
await page.waitForSelector(`[id="${previewExtensionId}"]`, { timeout: 2000 });
11+
SmokeTestLogger.info("React-native-preview extension is activated");
12+
return true;
13+
} catch {
14+
try {
15+
await page.waitForSelector(`[id="${prodExtensionId}"]`, { timeout: 2000 });
16+
SmokeTestLogger.info("React-native-prod extension is activated");
17+
return true;
18+
} catch {
19+
return false;
20+
}
1221
}
13-
await waitConditionUntil(
14-
() =>
15-
(window as any).vscode?.extensions?.getExtension(this.extensionId)?.isActive ==
16-
true,
17-
1000,
18-
10000,
19-
);
2022
}
2123
}

test/smoke/suites/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ startSmokeTests(setUp, cleanUp);
1212

1313
async function setUp(): Promise<void> {
1414
const vscodeExecutablePath = await app.downloadVSCodeExecutable();
15+
await app.setVSCodeExecutablePath(vscodeExecutablePath);
1516
await app.cleanUserData();
16-
await app.cleanExtensionData();
1717
await app.installExtensionFromVSIX(vscodeExecutablePath);
1818
await screenshots.prepareScreenshotFolderForPlatform();
1919
}

test/smoke/suites/smoke.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for details.
33

4+
import { startExtensionActivationTests } from "./activation.test";
45
import { startCommandPaletteTests } from "./commands.test";
56
import { SmokeTestLogger } from "./helper/smokeTestLogger";
67
import { smokeTestFail } from "./helper/utilities";
@@ -19,7 +20,11 @@ export function startSmokeTests(setup: () => Promise<void>, cleanUp: () => Promi
1920
SmokeTestLogger.info("Test execution completed.");
2021
});
2122

22-
describe("Extension smoke tests", () => {
23+
describe("Extension smoke tests", function () {
24+
// Using bail, when startExtensionActivationTests() failed, skip other test cases.
25+
this.bail(true);
26+
startExtensionActivationTests();
27+
2328
startCommandPaletteTests();
2429
});
2530
}

0 commit comments

Comments
 (0)