VSCode拡張機能テストサービス
wdio-vscode-serviceはサードパーティ製のパッケージです。詳細については、GitHub | npm を参照してください。
テスト環境
VSCode拡張機能をテストするためのWebdriverIOサービス。
このWebdriverIOサービスを使用すると、VSCode Desktop IDEまたはWeb拡張機能として、VSCode拡張機能をエンドツーエンドでシームレスにテストできます。拡張機能へのパスを指定するだけで、サービスが残りの処理を行います。
- 🏗️ VSCodeのインストール (stable、insiders、または指定されたバージョン)
- ⬇️ 特定のVSCodeバージョンに対応したChromedriverのダウンロード
- 🚀 テストからVSCode APIにアクセスできるようにします
- 🖥️ カスタムユーザー設定でVSCodeを起動 (Ubuntu、MacOS、WindowsでのVSCodeのサポートを含む)
- 🌐 または、Web拡張機能をテストするために、任意のブラウザからアクセスできるように、サーバーからVSCodeを提供します
- 📔 VSCodeのバージョンに一致するロケーターを使用してページオブジェクトをブートストラップします
このプロジェクトは、Seleniumベースのvscode-extension-testerプロジェクトに大きく触発されました。このパッケージは、そのアイデアを採用し、WebdriverIOに適合させました。
VSCode v1.86以降では、設定なしでChromedriverをインストールするには、webdriverio v8.14以降を使用する必要があります。以前のバージョンの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 }]]
     */
    // ...
};
wdio:vscodeOptionsをbrowserNameとしてvscode以外(たとえばchrome)で定義すると、サービスは拡張機能をWeb拡張機能として提供します。Chromeでテストする場合は、追加のドライバサービスは不要です。例:
// wdio.conf.ts
export const config = {
    outputDir: 'trace',
    // ...
    capabilities: [{
        browserName: 'chrome',
        'wdio:vscodeOptions': {
            extensionPath: __dirname
        }
    }],
    services: ['vscode'],
    // ...
};
注意: Web拡張機能をテストする場合は、browserVersionとしてstableまたはinsidersのみを選択できます。
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でテストを実行するには、browserNameとしてvscodeを定義する必要があります。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以降では、設定なしでChromedriverをインストールするにはwebdriverio v8.14以降を使用する必要があります。簡略化されたブラウザ自動化の設定がすべてを処理します。
以前のバージョンの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')
独自のPageObjectの作成
このサービスで使用されているコンポーネントを、独自のレビューページオブジェクトで再利用できます。そのためには、まずすべてのセレクターを定義するファイルを作成します。例:
// 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 (27,000ダウンロード)
- Live Server (2,780万ダウンロード)
- Visual Studio Code用DVC拡張機能 (11,200ダウンロード)
- Nx Console (120万ダウンロード)
- inlang – i18n supercharged (3,000ダウンロード)
コントリビューション
プルリクエストを投稿する前に、以下を実行してください。
- git clone git@github.com: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の詳細については、プロジェクトのホームページをご覧ください。
