Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions tests/e2e/objects/quickInputs/Quickpick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,46 @@ import { expect } from "@playwright/test";
* Object representing a VS Code {@link https://code.visualstudio.com/api/ux-guidelines/quick-picks quickpick}.
*/
export class Quickpick {
constructor(public readonly page: Page) {}
constructor(
public readonly page: Page,
/** Optional pattern to filter quickpicks by their `title` text. */
public readonly titlePattern?: string | RegExp,
) {}

/** The main quickpick widget locator. */
get locator(): Locator {
return this.page.locator(".quick-input-widget");
const baseLocator = this.page.locator(".quick-input-widget");
if (!this.titlePattern) {
return baseLocator;
}

return baseLocator.filter({
has: this.page.locator(".quick-input-title", { hasText: this.titlePattern }),
});
Comment thread
shouples marked this conversation as resolved.
}

/** The quickpick header container. */
get header(): Locator {
return this.locator.locator(".quick-input-header");
}

/** Wait for the quickpick widget to be visible before interacting with it. */
async waitForVisible(): Promise<void> {
await expect(this.locator).toBeVisible();
}

/**
* Press Enter to confirm the current selection(s). This is mainly done with multi-select
* quickpicks since clicking a single item in a regular quickpick will automatically confirm it.
*/
async confirm(): Promise<void> {
await this.waitForVisible();
await this.locator.press("Enter");
}

/** Press Escape to cancel the input. */
async cancel(): Promise<void> {
await this.waitForVisible();
await this.locator.press("Escape");
}

Expand All @@ -48,6 +66,7 @@ export class Quickpick {
* one matches before clicking, so a stale/prefix name can't silently select the wrong item.
*/
async selectItemByText(text: string, options: { exact?: boolean } = {}): Promise<void> {
await this.waitForVisible();
await this.textInput.fill(text);
// `hasText` is a substring match; `exact` instead requires a label that equals `text` so a
// prefix/stale name (e.g. "env" against "env-2") resolves to 0 items and the guard below fires
Expand Down