VSCode 扩展测试服务
测试于
用于测试 VSCode 扩展的 WebdriverIO 服务。
此 WebdriverIO 服务允许您在 VSCode 桌面 IDE 中或作为 Web 扩展无缝地端到端测试您的 VSCode 扩展。您只需提供扩展的路径,服务就会通过以下方式完成其余工作:
- 🏗️ 安装 VSCode(
stable
、insiders
或指定版本) - ⬇️ 下载特定于给定 VSCode 版本的 Chromedriver
- 🚀 使您能够从测试中访问 VSCode API
- 🖥️ 使用自定义用户设置启动 VSCode(包括对 Ubuntu、MacOS 和 Windows 上的 VSCode 的支持)
- 🌐 或从服务器提供 VSCode,以便任何浏览器都可以访问以测试Web 扩展
- 📔 使用与您的 VSCode 版本匹配的定位器引导页面对象
这个项目受到vscode-extension-tester项目的启发,该项目基于 Selenium。此包采用了该想法并将其应用于 WebdriverIO。
从 VSCode v1.86 开始,需要使用 webdriverio
v8.14 或更高版本来安装 Chromedriver,无需任何配置。如果您需要测试 VSCode 的早期版本,请参阅下面的Chromedriver 配置部分。
安装
要启动一个新的 WebdriverIO 项目,请运行
npm create wdio ./
安装向导将指导您完成整个过程。确保选择 TypeScript 作为编译器,并且不要让它为您生成页面对象,因为此项目附带了所有需要的页面对象。然后确保在服务列表中选择vscode
有关如何安装WebdriverIO
的更多信息,请查看项目文档。
示例配置
要使用该服务,您需要将vscode
添加到服务列表中,可以选择后跟一个配置对象。这将使 WebdriverIO 下载给定的 VSCode 二进制文件和相应的 Chromedriver 版本
// wdio.conf.ts
export const config = {
outputDir: 'trace',
// ...
capabilities: [{
browserName: 'vscode',
browserVersion: '1.86.0', // "insiders" or "stable" for latest VSCode version
'wdio:vscodeOptions': {
extensionPath: __dirname,
userSettings: {
"editor.fontSize": 14
}
}
}],
services: ['vscode'],
/**
* Optionally define the path WebdriverIO stores all VSCode binaries, e.g.:
* services: [['vscode', { cachePath: __dirname }]]
*/
// ...
};
如果您使用除vscode
以外的任何其他browserName
定义wdio:vscodeOptions
,例如chrome
,则该服务将把扩展程序作为 Web 扩展程序提供服务。如果您在 Chrome 上进行测试,则不需要其他驱动程序服务,例如:
// wdio.conf.ts
export const config = {
outputDir: 'trace',
// ...
capabilities: [{
browserName: 'chrome',
'wdio:vscodeOptions': {
extensionPath: __dirname
}
}],
services: ['vscode'],
// ...
};
注意:在测试 Web 扩展程序时,您只能在stable
或insiders
之间选择作为browserVersion
。
TypeScript 设置
在您的tsconfig.json
中,确保将wdio-vscode-service
添加到您的类型列表中
{
"compilerOptions": {
"types": [
"node",
"webdriverio/async",
"@wdio/mocha-framework",
"expect-webdriverio",
"wdio-vscode-service"
],
"target": "es2019",
"moduleResolution": "node",
"esModuleInterop": true
}
}
用法
然后,您可以使用getWorkbench
方法访问页面对象,以获取与您所需的 VSCode 版本匹配的定位器
describe('WDIO VSCode Service', () => {
it('should be able to load VSCode', async () => {
const workbench = await browser.getWorkbench()
expect(await workbench.getTitleBar().getTitle())
.toBe('[Extension Development Host] - README.md - wdio-vscode-service - Visual Studio Code')
})
})
访问 VSCode API
如果您想通过VSCode API执行某些自动化操作,您可以通过自定义executeWorkbench
命令运行远程命令来实现。此命令允许您在 VSCode 环境中远程执行测试中的代码,并使您能够访问 VSCode API。您可以将任意参数传递到函数中,然后这些参数将传播到函数中。vscode
对象将始终作为外部函数参数后的第一个参数传入。请注意,您无法访问函数作用域之外的变量,因为回调是在远程执行的。这是一个示例
const workbench = await browser.getWorkbench()
await browser.executeWorkbench((vscode, param1, param2) => {
vscode.window.showInformationMessage(`I am an ${param1} ${param2}!`)
}, 'API', 'call')
const notifs = await workbench.getNotifications()
console.log(await notifs[0].getMessage()) // outputs: "I am an API call!"
有关完整的页面对象文档,请查看文档。您可以在此项目的测试套件中找到各种使用示例。
配置
通过服务配置,您可以管理 VSCode 版本以及 VSCode 的用户设置
服务选项
服务选项是服务设置测试环境所需的选项。
cachePath
定义一个缓存路径以避免重新下载 VS Code 包。这对于 CI/CD 很有用,可以避免在每次测试运行时重新下载 VSCode。
类型:string
默认值:process.cwd()
VSCode 功能 (wdio:vscodeOptions
)
为了通过 VSCode 运行测试,您必须将vscode
定义为browserName
。您可以通过提供browserVersion
功能来指定 VSCode 版本。自定义 VSCode 选项然后在自定义wdio:vscodeOptions
功能中定义。选项如下所示
binary
本地安装的 VSCode 安装路径。如果未提供此选项,则服务将根据给定的browserVersion
(如果未给出,则为stable
)下载 VSCode。
类型:string
extensionPath
定义要测试的扩展程序的目录。
类型:string
storagePath
定义 VS Code 存储所有数据自定义位置。这是内部 VS Code 目录(部分列表)的根目录:
- user-data-dir:存储所有用户设置(全局设置)、扩展程序日志等的位置。
- extension-install-dir:安装 VS Code 扩展程序的目录。
如果未提供,则使用临时目录。
类型:string
userSettings
定义要应用于 VSCode 的自定义用户设置。
类型:Record<string, number | string | object | boolean>
默认值:{}
workspacePath
为特定工作区打开 VSCode。如果未提供,则 VSCode 将在没有打开工作区的情况下启动。
类型:string
filePath
打开 VSCode 并打开特定文件。
类型:string
vscodeArgs
作为对象的其他启动参数,例如:
vscodeArgs: { fooBar: true, 'bar-foo': '/foobar' }
将作为
--foo-bar --fooBar --bar-foo=/foobar
类型:Record<string, string | boolean>
默认值:请参阅constants.ts#L5-L14
verboseLogging
如果设置为 true,则服务会记录来自扩展程序主机和控制台 API 的 VSCode 输出。
类型:boolean
默认值:false
vscodeProxyOptions
VSCode API 代理配置定义了 WebdriverIO 如何连接到 VSCode 工作台以使您能够访问 VSCode API。
类型:VSCodeProxyOptions
默认值
{
/**
* If set to true, the service tries to establish a connection with the
* VSCode workbench to enable access to the VSCode API
*/
enable: true,
/**
* Port of the WebSocket connection used to connect to the workbench.
* By default set to an available port in your operating system.
*/
// port?: number
/**
* Timeout for connecting to WebSocket inside of VSCode
*/
connectionTimeout: 5000,
/**
* Timeout for command to be executed within VSCode
*/
commandTimeout: 5000
}
Chromedriver
从 VSCode v1.86 开始,需要使用 webdriverio
v8.14 或更高版本来安装 Chromedriver,无需任何配置。 简化的浏览器自动化设置 会为您处理所有事情。
要测试 VS Code 的早期版本,请从日志中找到预期的 Chromedriver 版本,下载 Chromedriver,并配置路径。例如
[0-0] ERROR webdriver: Failed downloading chromedriver v108: Download failed: ...
capabilities: [{
browserName: 'vscode',
browserVersion: '1.80.0',
'wdio:chromedriverOptions': {
binary: path.join(cacheDir, 'chromedriver-108.0.5359.71')
创建您自己的页面对象
您可以将此服务中使用的组件重复用于您自己的审查页面对象。为此,首先创建一个定义所有选择器的文件,例如
// e.g. in /test/pageobjects/locators.ts
export const componentA = {
elem: 'form', // component container element
submit: 'button[type="submit"]', // submit button
username: 'input.username', // username input
password: 'input.password' // password input
}
现在您可以按如下方式创建页面对象
// e.g. in /test/pageobjects/loginForm.ts
import { PageDecorator, IPageDecorator, BasePage } from 'wdio-vscode-service'
import * as locatorMap, { componentA as componentALocators } from './locators'
export interface LoginForm extends IPageDecorator<typeof componentALocators> {}
@PageDecorator(componentALocators)
export class LoginForm extends BasePage<typeof componentALocators, typeof locatorMap> {
/**
* @private locator key to identify locator map (see locators.ts)
*/
public locatorKey = 'componentA' as const
public login (username: string, password: string) {
await this.username$.setValue(username)
await this.password$.setValue(password)
await this.submit$.click()
}
}
现在在您的测试中,您可以按如下方式使用您的页面对象
import { LoginForm } from '../pageobjects/loginForm'
import * as locatorMap from '../locators'
// e.g. in /test/specs/example.e2e.ts
describe('my extension', () => {
it('should login', async () => {
const loginForm = new LoginForm(locatorMap)
await loginForm.login('admin', 'test123')
// you can also use page object elements directly via `[selector]$`
// or `[selector]$$`, e.g.:
await loginForm.submit$.click()
// or access locators directly
console.log(loginForm.locators.username)
// outputs: "input.username"
})
})
TypeScript 支持
如果您将 WebdriverIO 与 TypeScript 一起使用,请确保在 tsconfig.json
中的 types
中添加 wdio-vscode-service
,例如
{
"compilerOptions": {
"moduleResolution": "node",
"types": [
"webdriverio/async",
"@wdio/mocha-framework",
"expect-webdriverio",
// add this service to your types
"wdio-devtools-service"
],
"target": "es2019"
}
}
代理支持
在此服务的初始化期间,会下载 ChromeDriver 和 VSCode 发行版。您可以通过设置环境变量 HTTPS_PROXY
或 https_proxy
来通过代理隧道这些请求。例如
HTTPS_PROXY=http://127.0.0.1:1080 npm run wdio
参考
以下 VS Code 扩展程序使用 wdio-vscode-service
- Marquee(27k 下载量)
- Live Server(2780万下载量)
- Visual Studio Code 的 DVC 扩展(11.2k 下载量)
- Nx 控制台(120万下载量)
- inlang – i18n 加强版(3k 下载量)
贡献
在发布拉取请求之前,请运行以下命令
git clone [email protected]:webdriverio-community/wdio-vscode-service.git
cd wdio-vscode-service
npm install
npm run build
npm run test
(或npm run ci
)
了解更多
如果您想了解有关测试 VSCode 扩展的更多信息,请查看 Christian Bromann 在 OpenJS World 2022 上的演讲。
有关 WebdriverIO 的更多信息,请查看项目 主页。