Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/test/sanity/src/uiTest.ts
5221 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 fs from 'fs';
8
import path from 'path';
9
import { Page } from 'playwright';
10
import { TestContext } from './context.js';
11
12
/**
13
* UI Test helper class to perform common UI actions and verifications.
14
*/
15
export class UITest {
16
private _extensionsDir: string | undefined;
17
private _workspaceDir: string | undefined;
18
private _userDataDir: string | undefined;
19
20
constructor(
21
protected readonly context: TestContext,
22
dataDir?: string
23
) {
24
if (dataDir) {
25
this._extensionsDir = path.join(dataDir, 'extensions');
26
this._userDataDir = path.join(dataDir, 'user-data');
27
}
28
}
29
30
/**
31
* The directory where extensions are installed.
32
*/
33
public get extensionsDir(): string {
34
return this._extensionsDir ??= this.context.createTempDir();
35
}
36
37
/**
38
* The workspace directory used for testing.
39
*/
40
public get workspaceDir(): string {
41
return this._workspaceDir ??= this.context.createTempDir();
42
}
43
44
/**
45
* The user data directory used for testing.
46
*/
47
public get userDataDir(): string {
48
return this._userDataDir ??= this.context.createTempDir();
49
}
50
51
/**
52
* Run the UI test actions.
53
*/
54
public async run(page: Page) {
55
await this.dismissWorkspaceTrustDialog(page);
56
await this.createTextFile(page);
57
await this.installExtension(page);
58
}
59
60
/**
61
* Validate the results of the UI test actions.
62
*/
63
public validate() {
64
this.verifyTextFileCreated();
65
this.verifyExtensionInstalled();
66
}
67
68
/**
69
* Dismiss the workspace trust dialog.
70
*/
71
private async dismissWorkspaceTrustDialog(page: Page) {
72
this.context.log('Dismissing workspace trust dialog');
73
await page.getByText('Yes, I trust the authors').click();
74
await page.waitForTimeout(500);
75
}
76
77
/**
78
* Run a command from the command palette.
79
*/
80
private async runCommand(page: Page, command: string) {
81
this.context.log(`Running command: ${command}`);
82
await page.keyboard.press('F1');
83
await page.getByPlaceholder(/^Type the name of a command/).fill(`>${command}`);
84
await page.locator('span.monaco-highlighted-label', { hasText: new RegExp(`^${command}$`) }).click();
85
await page.waitForTimeout(1000);
86
}
87
88
/**
89
* Create a new text file in the editor with some content and save it.
90
*/
91
private async createTextFile(page: Page) {
92
await this.runCommand(page, 'View: Show Explorer');
93
94
this.context.log('Clicking New File button');
95
await page.getByLabel('New File...').click();
96
97
this.context.log('Typing file name');
98
await page.getByRole('textbox', { name: /^Type file name/ }).fill('helloWorld.txt');
99
await page.keyboard.press('Enter');
100
101
this.context.log('Focusing the code editor');
102
await page.getByText(/Start typing/).focus();
103
104
this.context.log('Typing some content into the file');
105
await page.keyboard.type('Hello, World!');
106
107
await this.runCommand(page, 'File: Save');
108
}
109
110
/**
111
* Verify that the text file was created with the expected content.
112
*/
113
protected verifyTextFileCreated() {
114
this.context.log('Verifying file contents');
115
const filePath = `${this.workspaceDir}/helloWorld.txt`;
116
const fileContents = fs.readFileSync(filePath, 'utf-8');
117
assert.strictEqual(fileContents, 'Hello, World!', 'File contents do not match expected value');
118
}
119
120
/**
121
* Install GitHub Pull Requests extension from the Extensions view.
122
*/
123
private async installExtension(page: Page) {
124
await this.runCommand(page, 'View: Show Extensions');
125
126
this.context.log('Typing extension name to search for');
127
await page.getByText('Search Extensions in Marketplace').focus();
128
await page.keyboard.type('GitHub Pull Requests');
129
130
this.context.log('Clicking Install on the first extension in the list');
131
await page.locator('.extension-list-item').getByText(/^GitHub Pull Requests$/).waitFor();
132
await page.locator('.extension-action:not(.disabled)', { hasText: /Install/ }).first().click();
133
await page.waitForTimeout(1000);
134
135
this.context.log('Waiting for extension to be installed');
136
await page.locator('.extension-action:not(.disabled)', { hasText: /Uninstall/ }).waitFor();
137
}
138
139
/**
140
* Verify that the GitHub Pull Requests extension is installed.
141
*/
142
protected verifyExtensionInstalled() {
143
this.context.log('Verifying extension is installed');
144
const extensions = fs.readdirSync(this.extensionsDir);
145
const hasExtension = extensions.some(ext => ext.startsWith('github.vscode-pull-request-github'));
146
assert.strictEqual(hasExtension, true, 'GitHub Pull Requests extension is not installed');
147
}
148
}
149
150