Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/test/sanity/src/devTunnel.test.ts
13523 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 { Page } from 'playwright';
7
import { TestContext } from './context.js';
8
import { GitHubAuth } from './githubAuth.js';
9
import { UITest } from './uiTest.js';
10
11
export function setup(context: TestContext) {
12
/*
13
TODO: @dmitrivMS Reenable other platforms once throttling issues with GitHub account are resolved.
14
15
context.test('dev-tunnel-alpine-arm64', ['alpine', 'arm64', 'browser', 'github-account'], async () => {
16
const dir = await context.downloadAndUnpack('cli-alpine-arm64');
17
const entryPoint = context.getCliEntryPoint(dir);
18
await testCliApp(entryPoint);
19
});
20
21
context.test('dev-tunnel-alpine-x64', ['alpine', 'x64', 'browser', 'github-account'], async () => {
22
const dir = await context.downloadAndUnpack('cli-alpine-x64');
23
const entryPoint = context.getCliEntryPoint(dir);
24
await testCliApp(entryPoint);
25
});
26
27
context.test('dev-tunnel-linux-arm64', ['linux', 'arm64', 'browser', 'github-account'], async () => {
28
const dir = await context.downloadAndUnpack('cli-linux-arm64');
29
const entryPoint = context.getCliEntryPoint(dir);
30
await testCliApp(entryPoint);
31
});
32
33
context.test('dev-tunnel-linux-armhf', ['linux', 'arm32', 'browser', 'github-account'], async () => {
34
const dir = await context.downloadAndUnpack('cli-linux-armhf');
35
const entryPoint = context.getCliEntryPoint(dir);
36
await testCliApp(entryPoint);
37
});
38
39
context.test('dev-tunnel-linux-x64', ['linux', 'x64', 'browser', 'github-account'], async () => {
40
const dir = await context.downloadAndUnpack('cli-linux-x64');
41
const entryPoint = context.getCliEntryPoint(dir);
42
await testCliApp(entryPoint);
43
});
44
45
context.test('dev-tunnel-darwin-arm64', ['darwin', 'arm64', 'browser', 'github-account'], async () => {
46
const dir = await context.downloadAndUnpack('cli-darwin-arm64');
47
context.validateAllCodesignSignatures(dir);
48
const entryPoint = context.getCliEntryPoint(dir);
49
await testCliApp(entryPoint);
50
});
51
*/
52
53
context.test('dev-tunnel-darwin-x64', ['darwin', 'x64', 'browser', 'github-account'], async () => {
54
const dir = await context.downloadAndUnpack('cli-darwin-x64');
55
context.validateAllCodesignSignatures(dir);
56
const entryPoint = context.getCliEntryPoint(dir);
57
await testCliApp(entryPoint);
58
});
59
60
/** TODO: @dmitrivMS Fix flakiness and then reenable
61
context.test('dev-tunnel-win32-arm64', ['windows', 'arm64', 'browser', 'github-account'], async () => {
62
const dir = await context.downloadAndUnpack('cli-win32-arm64');
63
context.validateAllAuthenticodeSignatures(dir);
64
context.validateAllVersionInfo(dir);
65
const entryPoint = context.getCliEntryPoint(dir);
66
await testCliApp(entryPoint);
67
});
68
69
context.test('dev-tunnel-win32-x64', ['windows', 'x64', 'browser', 'github-account'], async () => {
70
const dir = await context.downloadAndUnpack('cli-win32-x64');
71
context.validateAllAuthenticodeSignatures(dir);
72
context.validateAllVersionInfo(dir);
73
const entryPoint = context.getCliEntryPoint(dir);
74
await testCliApp(entryPoint);
75
});
76
*/
77
78
async function testCliApp(entryPoint: string) {
79
if (context.options.downloadOnly) {
80
return;
81
}
82
83
const cliDataDir = context.createTempDir();
84
context.log('Logging out of Dev Tunnel to ensure fresh authentication');
85
context.run(entryPoint, '--cli-data-dir', cliDataDir, 'tunnel', 'user', 'logout');
86
87
const test = new UITest(context);
88
const auth = new GitHubAuth(context);
89
const browser = await context.launchBrowser();
90
try {
91
const page = await context.getPage(browser.newPage());
92
context.log('Starting Dev Tunnel to local server using CLI');
93
await context.runCliApp('CLI', entryPoint,
94
[
95
'--cli-data-dir', cliDataDir,
96
'tunnel',
97
'--accept-server-license-terms',
98
'--server-data-dir', context.createTempDir(),
99
'--extensions-dir', test.extensionsDir,
100
'--verbose'
101
],
102
async (line) => {
103
const deviceCode = /To grant access .* use code ([A-Z0-9-]+)/.exec(line)?.[1];
104
if (deviceCode) {
105
context.log(`Device code detected: ${deviceCode}, starting device flow authentication`);
106
await auth.runDeviceCodeFlow(page, deviceCode);
107
return;
108
}
109
110
const tunnelUrl = /Open this link in your browser (https?:\/\/[^\s]+)/.exec(line)?.[1];
111
if (tunnelUrl) {
112
await connectToTunnel(tunnelUrl, page, test, auth);
113
await test.run(page);
114
test.validate();
115
return true;
116
}
117
}
118
);
119
} finally {
120
context.log('Closing browser');
121
await browser.close();
122
}
123
}
124
125
async function connectToTunnel(tunnelUrl: string, page: Page, test: UITest, auth: GitHubAuth) {
126
try {
127
const tunnelId = new URL(tunnelUrl).pathname.split('/').pop()!;
128
const url = context.getTunnelUrl(tunnelUrl, test.workspaceDir);
129
context.log(`CLI started successfully with tunnel URL: ${url}`);
130
131
context.log(`Navigating to ${url}`);
132
await page.goto(url);
133
134
context.log('Waiting for the workbench to load');
135
await page.waitForSelector('.monaco-workbench');
136
137
await test.dismissWelcomeDialog(page);
138
139
context.log('Selecting GitHub Account');
140
await page.locator('span.monaco-highlighted-label', { hasText: 'GitHub' }).click();
141
142
context.log('Clicking Allow on confirmation dialog');
143
const popup = page.waitForEvent('popup');
144
await page.getByRole('button', { name: 'Allow' }).click();
145
146
await auth.runAuthorizeFlow(await popup);
147
148
context.log('Waiting for connection to be established');
149
await page.getByRole('button', { name: `remote ${tunnelId}` }).waitFor({ timeout: 5 * 60 * 1000 });
150
} catch (error) {
151
context.log('Error during tunnel connection, capturing screenshot');
152
await context.captureScreenshot(page);
153
throw error;
154
}
155
}
156
}
157
158