Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/test/sanity/src/wsl.test.ts
5232 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import assert from 'assert';
7
import { _electron } from 'playwright';
8
import { TestContext } from './context.js';
9
import { UITest } from './uiTest.js';
10
11
export function setup(context: TestContext) {
12
context.test('wsl-server-arm64', ['windows', 'arm64', 'wsl'], async () => {
13
const dir = await context.downloadAndUnpack('server-linux-arm64');
14
const entryPoint = context.getServerEntryPoint(dir, true);
15
await testServer(entryPoint);
16
});
17
18
context.test('wsl-server-x64', ['windows', 'x64', 'wsl'], async () => {
19
const dir = await context.downloadAndUnpack('server-linux-x64');
20
const entryPoint = context.getServerEntryPoint(dir, true);
21
await testServer(entryPoint);
22
});
23
24
context.test('wsl-server-web-arm64', ['windows', 'arm64', 'wsl', 'browser'], async () => {
25
const dir = await context.downloadAndUnpack('server-linux-arm64-web');
26
const entryPoint = context.getServerEntryPoint(dir, true);
27
await testServerWeb(entryPoint);
28
});
29
30
context.test('wsl-server-web-x64', ['windows', 'x64', 'wsl', 'browser'], async () => {
31
const dir = await context.downloadAndUnpack('server-linux-x64-web');
32
const entryPoint = context.getServerEntryPoint(dir, true);
33
await testServerWeb(entryPoint);
34
});
35
36
context.test('wsl-desktop-arm64', ['windows', 'arm64', 'wsl', 'desktop'], async () => {
37
const dir = await context.downloadAndUnpack('win32-arm64-archive');
38
context.validateAllAuthenticodeSignatures(dir);
39
if (!context.options.downloadOnly) {
40
const entryPoint = context.getDesktopEntryPoint(dir);
41
const dataDir = context.createPortableDataDir(dir);
42
await testDesktopApp(entryPoint, dataDir);
43
}
44
});
45
46
context.test('wsl-desktop-x64', ['windows', 'x64', 'wsl', 'desktop'], async () => {
47
const dir = await context.downloadAndUnpack('win32-x64-archive');
48
context.validateAllAuthenticodeSignatures(dir);
49
if (!context.options.downloadOnly) {
50
const entryPoint = context.getDesktopEntryPoint(dir);
51
const dataDir = context.createPortableDataDir(dir);
52
await testDesktopApp(entryPoint, dataDir);
53
}
54
});
55
56
async function testServer(entryPoint: string) {
57
if (context.options.downloadOnly) {
58
return;
59
}
60
61
await context.runCliApp('WSL Server', 'wsl',
62
[
63
context.toWslPath(entryPoint),
64
'--accept-server-license-terms',
65
'--connection-token', context.getRandomToken(),
66
'--host', '0.0.0.0',
67
'--port', context.getUniquePort(),
68
'--server-data-dir', context.createWslTempDir(),
69
'--extensions-dir', context.createWslTempDir(),
70
],
71
async (line) => {
72
const port = /Extension host agent listening on (\d+)/.exec(line)?.[1];
73
if (!port) {
74
return;
75
}
76
77
const url = new URL('version', context.getWebServerUrl(port)).toString();
78
79
context.log(`Fetching version from ${url}`);
80
const response = await context.fetchNoErrors(url);
81
const version = await response.text();
82
assert.strictEqual(version, context.options.commit, `Expected commit ${context.options.commit} but got ${version}`);
83
84
return true;
85
}
86
);
87
}
88
89
async function testServerWeb(entryPoint: string) {
90
if (context.options.downloadOnly) {
91
return;
92
}
93
94
const wslWorkspaceDir = context.createWslTempDir();
95
const wslExtensionsDir = context.createWslTempDir();
96
const token = context.getRandomToken();
97
const test = new WslUITest(context, undefined, wslWorkspaceDir, wslExtensionsDir);
98
99
await context.runCliApp('WSL Server', 'wsl',
100
[
101
context.toWslPath(entryPoint),
102
'--accept-server-license-terms',
103
'--connection-token', token,
104
'--host', '0.0.0.0',
105
'--port', context.getUniquePort(),
106
'--server-data-dir', context.createWslTempDir(),
107
'--extensions-dir', wslExtensionsDir,
108
'--user-data-dir', context.createWslTempDir(),
109
],
110
async (line) => {
111
const port = /Extension host agent listening on (\d+)/.exec(line)?.[1];
112
if (!port) {
113
return false;
114
}
115
116
const url = context.getWebServerUrl(port, token, wslWorkspaceDir).toString();
117
const browser = await context.launchBrowser();
118
const page = await context.getPage(browser.newPage());
119
120
context.log(`Navigating to ${url}`);
121
await page.goto(url, { waitUntil: 'networkidle' });
122
123
context.log('Waiting for the workbench to load');
124
await page.waitForSelector('.monaco-workbench');
125
126
await test.run(page);
127
128
context.log('Closing browser');
129
await browser.close();
130
131
test.validate();
132
return true;
133
}
134
);
135
}
136
137
async function testDesktopApp(entryPoint: string, dataDir: string) {
138
const wslExtensionsDir = context.getWslServerExtensionsDir();
139
context.deleteWslDir(wslExtensionsDir);
140
141
const wslWorkspaceDir = context.createWslTempDir();
142
const wslDistro = context.getDefaultWslDistro();
143
const test = new WslUITest(context, dataDir, wslWorkspaceDir, wslExtensionsDir);
144
145
const args = [
146
'--extensions-dir', context.createTempDir(),
147
'--user-data-dir', test.userDataDir,
148
'--folder-uri', `vscode-remote://wsl+${wslDistro}${wslWorkspaceDir}`,
149
];
150
151
context.log(`Starting VS Code ${entryPoint} with args ${args.join(' ')}`);
152
const app = await _electron.launch({ executablePath: entryPoint, args });
153
const window = await context.getPage(app.firstWindow());
154
155
context.log('Installing WSL extension');
156
await window.getByRole('button', { name: 'Install and Reload' }).click();
157
158
context.log('Waiting for WSL connection');
159
await window.getByText(/WSL/).waitFor();
160
161
await test.run(window);
162
163
context.log('Closing the application');
164
await app.close();
165
166
test.validate();
167
}
168
}
169
170
/**
171
* UI Test subclass for WSL that validates files in WSL filesystem.
172
*/
173
class WslUITest extends UITest {
174
constructor(
175
context: TestContext,
176
dataDir: string | undefined,
177
private readonly wslWorkspaceDir: string,
178
private readonly wslExtensionsDir: string
179
) {
180
super(context, dataDir);
181
}
182
183
protected override verifyTextFileCreated() {
184
this.context.log('Verifying file contents in WSL');
185
const result = this.context.runNoErrors('wsl', 'cat', `${this.wslWorkspaceDir}/helloWorld.txt`);
186
assert.strictEqual(result.stdout.trim(), 'Hello, World!', 'File contents in WSL do not match expected value');
187
}
188
189
protected override verifyExtensionInstalled() {
190
this.context.log(`Verifying extension is installed in WSL at ${this.wslExtensionsDir}`);
191
const result = this.context.runNoErrors('wsl', 'ls', this.wslExtensionsDir);
192
const hasExtension = result.stdout.split('\n').some(ext => ext.startsWith('github.vscode-pull-request-github'));
193
assert.strictEqual(hasExtension, true, 'GitHub Pull Requests extension is not installed in WSL');
194
}
195
}
196
197