원클릭으로
e2e-testing
Use when working with e2e tests.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when working with e2e tests.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | e2e-testing |
| description | Use when working with e2e tests. |
🧠 Continuous Improvement: If you discover new patterns, common pitfalls, or efficient ways to run/debug tests while working in this domain, please update this file to capture that knowledge for future agents.
This project uses WebdriverIO with the wdio-obsidian-service for end-to-end testing. Tests run a real instance of Obsidian with the Anker plugin installed.
test/specs/**/*.e2e.ts (The actual test files)test/vaults/ (Markdown files and assets used during tests)wdio.conf.mtsThis command rebuilds the plugin and runs the full suite against the latest Obsidian version.
npm run test:e2e:latest
You usually need to build the plugin first so the test uses the latest code.
npm run build && npx wdio run wdio.conf.mts --spec test/specs/card-errors.e2e.ts
Standard .click() often fails in Obsidian due to custom UI layers or non-standard listeners.
Problem: element not interactable or click intercepted.
Solution: Use JS execution to force the click.
const btn = await $(".my-button");
// Avoid: await btn.click();
await browser.execute((el) => el.click(), btn);
You can run code inside the Obsidian process using executeObsidian.
await browser.executeObsidian(async (app) => {
// This runs inside Obsidian's renderer process
const file = app.vault.getAbstractFileByPath("flashcards/my-card.md");
await app.workspace.getLeaf().openFile(file);
});
Always verify the exact Command ID in src/main.ts. Anker commands usually start with anker:.
// Good
await browser.executeObsidianCommand("anker:open-failed-cards");
Obsidian is heavily asynchronous (file system, metadata cache, UI animations).
browser.pause(5000) unless absolutely necessary.waitForExist, waitForDisplayed, or waitUntil.Example: Waiting for a modal
const modal = await $(".modal");
await modal.waitForDisplayed({ timeout: 5000 });
Some Obsidian modals use hidden file inputs (display: none). WebDriverIO cannot interact with them directly.
Use browser.execute to temporarily make the input visible before setValue.
await browser.execute((sel: string) => {
const input = document.querySelector(sel) as HTMLInputElement | null;
if (input) input.style.display = "block";
}, ".my-hidden-file-input");
const fileInput = $(".my-hidden-file-input");
await fileInput.setValue(remotePath);
Tests share the same vault folder (test/vaults). Ensure you clean up or reset state in beforeEach.
beforeEach(async () => {
// Reset contents of a file to a known clean state
await browser.executeObsidian(async (app) => {
const file = app.vault.getAbstractFileByPath("flashcards/test-card.md");
await app.vault.modify(file, "Initial clean content");
});
});
If a test opens a modal, ensure it is closed in afterEach to avoid stacked modals and timeouts.
afterEach(async () => {
await browser.execute(() => {
const buttons = document.querySelectorAll(
".modal-container .modal-close-button",
);
buttons.forEach((btn) => (btn as HTMLElement).click());
});
await browser.pause(200);
});
anker:open-failed-cards).app.vault.create doesn't mean the cache is ready instantly. If your test depends on frontmatter readings immediately after creation, you might hit a race condition.templates/ folder in beforeEach to avoid blocking tests.any.awaited.