feat: unified E2E testing engine — 205 tests, dual-stack support
Infrastructure: - adapters/: base, tauri (port 9750), electrobun (port 9761 + PTY daemon) - helpers/: 120+ centralized selectors, reusable actions, custom assertions - wdio.shared.conf.js + stack-specific configs 18 unified specs (205 tests): splash(6) smoke(15) settings(19) terminal(14) agent(15) search(12) files(15) comms(10) tasks(10) theme(12) groups(12) keyboard(8) notifications(10) diagnostics(8) status-bar(12) context(9) worktree(8) llm-judged(10) Daemon: --stack tauri|electrobun|both flag Scripts: test:e2e:tauri, test:e2e:electrobun, test:e2e:both
This commit is contained in:
parent
1995f03682
commit
77b9ce9f62
31 changed files with 3547 additions and 344 deletions
76
tests/e2e/helpers/assertions.ts
Normal file
76
tests/e2e/helpers/assertions.ts
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* Custom E2E assertions — domain-specific checks for Agent Orchestrator.
|
||||
*
|
||||
* Uses browser.execute() for DOM queries (WebKitGTK reliability).
|
||||
*/
|
||||
|
||||
import { browser, expect } from '@wdio/globals';
|
||||
import * as S from './selectors.ts';
|
||||
|
||||
/** Assert that a project card with the given name is visible in the grid */
|
||||
export async function assertProjectVisible(name: string): Promise<void> {
|
||||
const found = await browser.execute((n: string) => {
|
||||
const cards = document.querySelectorAll('.project-card, .project-header');
|
||||
for (const card of cards) {
|
||||
if (card.textContent?.includes(n)) return true;
|
||||
}
|
||||
return false;
|
||||
}, name);
|
||||
expect(found).toBe(true);
|
||||
}
|
||||
|
||||
/** Assert that at least one terminal pane responds (xterm container exists) */
|
||||
export async function assertTerminalResponds(): Promise<void> {
|
||||
const xterm = await browser.$(S.XTERM);
|
||||
if (await xterm.isExisting()) {
|
||||
await expect(xterm).toBeDisplayed();
|
||||
}
|
||||
}
|
||||
|
||||
/** Assert that a CSS custom property has changed after a theme switch */
|
||||
export async function assertThemeApplied(varName = '--ctp-base'): Promise<void> {
|
||||
const value = await browser.execute((v: string) => {
|
||||
return getComputedStyle(document.documentElement).getPropertyValue(v).trim();
|
||||
}, varName);
|
||||
expect(value.length).toBeGreaterThan(0);
|
||||
}
|
||||
|
||||
/** Assert that a settings value persists (read via computed style or DOM) */
|
||||
export async function assertSettingsPersist(selector: string): Promise<void> {
|
||||
const el = await browser.$(selector);
|
||||
if (await el.isExisting()) {
|
||||
await expect(el).toBeDisplayed();
|
||||
}
|
||||
}
|
||||
|
||||
/** Assert the status bar is visible and contains expected sections */
|
||||
export async function assertStatusBarComplete(): Promise<void> {
|
||||
const statusBar = await browser.$(S.STATUS_BAR);
|
||||
await expect(statusBar).toBeDisplayed();
|
||||
}
|
||||
|
||||
/** Assert element count matches expected via DOM query */
|
||||
export async function assertElementCount(
|
||||
selector: string,
|
||||
expected: number,
|
||||
comparison: 'eq' | 'gte' | 'lte' = 'eq',
|
||||
): Promise<void> {
|
||||
const count = await browser.execute((sel: string) => {
|
||||
return document.querySelectorAll(sel).length;
|
||||
}, selector);
|
||||
|
||||
switch (comparison) {
|
||||
case 'eq': expect(count).toBe(expected); break;
|
||||
case 'gte': expect(count).toBeGreaterThanOrEqual(expected); break;
|
||||
case 'lte': expect(count).toBeLessThanOrEqual(expected); break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Assert an element has a specific CSS class */
|
||||
export async function assertHasClass(selector: string, className: string): Promise<void> {
|
||||
const hasIt = await browser.execute((sel: string, cls: string) => {
|
||||
const el = document.querySelector(sel);
|
||||
return el?.classList.contains(cls) ?? false;
|
||||
}, selector, className);
|
||||
expect(hasIt).toBe(true);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue