Files
kandev/apps/web/e2e/helpers/settings-prompt-editor.ts
2026-08-21 16:40:58 +01:00

96 lines
2.8 KiB
TypeScript

import { type Locator, type Page, expect } from "@playwright/test";
type PromptEditorOptions = {
touch?: boolean;
};
type CompletionOptions = {
keyboard?: boolean;
touch?: boolean;
};
/** Return the Monaco host inside a SettingsPromptEditor wrapper. */
export function monacoPromptEditor(editor: Locator): Locator {
return editor.locator(".monaco-editor");
}
/** Focus Monaco's EditContext target, which is the input surface in this build. */
export async function focusPromptEditor(
editor: Locator,
{ touch = false }: PromptEditorOptions = {},
): Promise<Locator> {
const monaco = monacoPromptEditor(editor);
await expect(monaco).toBeVisible({ timeout: 10_000 });
if (touch) await monaco.tap();
else await monaco.click();
const editContext = monaco.locator(".native-edit-context");
await expect(editContext).toBeFocused({ timeout: 5_000 });
return monaco;
}
export async function replacePromptEditor(
page: Page,
editor: Locator,
value: string,
options?: PromptEditorOptions,
): Promise<Locator> {
const monaco = await focusPromptEditor(editor, options);
await page.keyboard.press("Control+A");
await page.keyboard.press("Backspace");
await page.keyboard.type(value);
return monaco;
}
export async function waitForPromptInStore(page: Page, promptName: string): Promise<void> {
await page.waitForFunction(
(name) => {
const store = (
window as Window & {
__KANDEV_E2E_STORE__?: {
getState: () => {
prompts: {
loaded: boolean;
items: Array<{ name: string }>;
};
};
};
}
).__KANDEV_E2E_STORE__;
const prompts = store?.getState().prompts;
return prompts?.loaded === true && prompts.items.some((prompt) => prompt.name === name);
},
promptName,
{
timeout: 10_000,
message: `saved prompt ${promptName} was not loaded into the settings store`,
},
);
}
export async function acceptPromptCompletion(
page: Page,
label: string,
{ keyboard = false, touch = false }: CompletionOptions = {},
): Promise<void> {
const suggestWidget = page.locator(".suggest-widget:visible").last();
await expect(suggestWidget).toBeVisible({ timeout: 5_000 });
const suggestion = suggestWidget.locator(".monaco-list-row").filter({ hasText: label }).first();
await expect(suggestion).toBeVisible({ timeout: 5_000 });
if (!keyboard) {
if (touch) await suggestion.tap();
else await suggestion.click();
return;
}
const index = Number((await suggestion.getAttribute("data-index")) ?? "0");
await page.keyboard.press("Home");
for (let step = 0; step < index; step += 1) {
await page.keyboard.press("ArrowDown");
}
await page.keyboard.press("Enter");
}
export function promptEditorText(editor: Locator): Locator {
return monacoPromptEditor(editor).locator(".view-lines");
}