本文へ移動
cccskills
無料GitHub で公開

test:playwright

Write and review Playwright demo tests for Rossoctl - markStep segments, assertions, selectors, narration alignment

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctlスター 303(GitHub 303 + cccskills 0)
連携ツールPlaywright

実行スコア 未検証

インストール方法を見る

含まれるファイル(1)

  • SKILL.md4.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Write Playwright Demo Tests

Write Playwright tests for recording narrated demo videos of the Rossoctl platform.

When to Use

  • Creating a new demo walkthrough test
  • Reviewing an existing demo test for quality
  • Fixing a failing demo test (wrong selectors, missing assertions)
  • Called by playwright-demo before recording

Test Location

Source tests: .worktrees/playwright-demos/local_experiments/e2e/<name>.spec.ts

Required Structure

Every Playwright demo test MUST have:

1. Timestamp tracking

const stepTimestamps: { step: string; time: number }[] = [];
const demoStartTime = Date.now();
const markStep = (step: string) => {
  const elapsed = (Date.now() - demoStartTime) / 1000;
  stepTimestamps.push({ step, time: elapsed });
  console.log(`[demo-ts] ${elapsed.toFixed(1)}s - ${step}`);
};

2. Cursor injection

Copy injectCursor, humanMove, demoClick from existing tests. These create a visible red cursor dot in the video (headless Playwright has no cursor).

3. markStep at every visual transition

markStep('section_name');  // MUST be outside any if/catch block

Rules:

  • ALWAYS outside conditionals (narration sync depends on every step firing)
  • Each section should be 3-15 seconds
  • Names must match [section] markers in narration file exactly

4. Section-level assertions

Tests MUST fail if content doesn't load. Never use silent .catch(() => {}):

// REQUIRED after login
expect(page.url()).not.toContain('/realms/');

// REQUIRED after SPA navigation
await expect(page).toHaveURL(/\/agents/, { timeout: 10000 });

// REQUIRED before critical interaction
await expect(element).toBeVisible({ timeout: 5000 });

// REQUIRED after content load
expect(cardCount, 'Page should have cards').toBeGreaterThan(0);

Keep .catch() ONLY for truly optional elements:

  • VERIFY_PROFILE form fields
  • scrollIntoViewIfNeeded
  • waitForLoadState('networkidle')

5. SPA navigation (Rossoctl pages)

Use sidebar clicks, NOT page.goto() — full reload loses Keycloak tokens:

// CORRECT - SPA client-side routing
const link = page.locator('nav a').filter({ hasText: /^Agents$/ });
await demoClick(link.first(), 'Agents sidebar');

// WRONG - loses auth tokens
await page.goto(`${UI_URL}/agents`);

Use page.goto() only for external apps (MLflow, Phoenix, Kiali).

6. Timestamps file

Write at test end:

const fs = require('fs');
const path = require('path');
const scriptDir = process.env.PLAYWRIGHT_OUTPUT_DIR || path.join(__dirname, '..');
const tsFile = path.join(scriptDir, '..', '<name>-timestamps.json');
fs.writeFileSync(tsFile, JSON.stringify(stepTimestamps, null, 2));

Selector Patterns

Read UI source (rossoctl/ui-v2/src/pages/) to find correct selectors:

UI PatternPlaywright Selector
PatternFly Buttonpage.getByRole('button', { name: /text/i })
PatternFly Tabpage.getByRole('tab', { name: /text/i })
React Router Linkpage.locator('nav a').filter({ hasText: /text/ })
Aria labelpage.locator('[aria-label="Select namespace"]')
Button with onClick (not <a>)page.getByRole('button', { name: /View Agents/i })
PatternFly Cardpage.locator('.pf-v5-c-card')

Multiple selector strategies

Try multiple selectors with .or() for resilience:

const chatTab = page.getByRole('tab', { name: /Chat/i })
  .or(page.locator('button:has-text("Chat")'))
  .or(page.locator('.pf-v5-c-tabs__link:has-text("Chat")'));

Narration File

Each test needs a matching narration file with one [section] per markStep():

[intro]
Welcome to the Kay-jentee platform...

[login]
We authenticate through Keycloak...

[section_name]
Description of what's visible on screen.

Pronunciation: Kay-jentee, A-to-A, M-C-P, mutual TLS, O-I-D-C.

Review Checklist

Before recording, verify:

  • All markStep() calls outside conditionals
  • Every section has expect() assertion (not silent .catch())
  • markStep names match narration [section] markers 1:1
  • SPA navigation for Rossoctl pages (not page.goto())
  • demoClick() used for cursor visibility (not .click())
  • Timestamps written to <name>-timestamps.json
  • 10-second final pause
  • Test passes without narration: --no-narration

After Writing

  1. Run test without narration to verify it passes
  2. Fix any selector issues using playwright-demo:debug
  3. Proceed to playwright-demo for recording with voiceover

Related Skills

  • playwright-demo -- Record videos (uses this skill's tests)
  • playwright-demo:debug -- Fix failing selectors and auth
  • playwright-research -- Analyze UI code for selectors
  • test:review -- General test quality review patterns

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

auth

無料

Authentication and authorization patterns for Rossoctl services

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

Create confidential OAuth2 clients in Keycloak for server-to-service authentication

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

Configure MLflow with mlflow-oidc-auth plugin for Keycloak OIDC authentication

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

Configure OpenTelemetry Collector with OAuth2 authentication for trace export

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

ci

無料

CI pipeline monitoring, status checks, and PR validation workflows

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

Monitor running CI jobs, wait for completion, create tasks for results

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

rossoctl のスキルをすべて見る

このスキルの問題を報告する