跳到正文
cccskills
免费在 GitHub 公开

test:ui-sandbox

Playwright selector patterns for sandbox agent chat — proven selectors for sessions, agents, messages, tool calls

中文简介正在准备中。当前显示原文说明。

rossoctl/rossoctl星标 303(GitHub 303 + cccskills 0)
集成工具Playwright

实测评分 未实测

查看安装方法

包含的文件(1)

  • SKILL.md4.4 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Sandbox UI Test Patterns

Proven Playwright selectors and patterns for testing the Rossoctl sandbox agent chat UI. Based on 20+ iterations of debugging on live HyperShift clusters.

Agent Selection

// Select an agent in the Sandboxes sidebar (proven pattern from sandbox-variants)
const agentEntry = page.locator('div[role="button"]').filter({
  hasText: agentName,
}).filter({
  hasText: /session/i,  // Agents show "N sessions" text
});
await expect(agentEntry.first()).toBeVisible({ timeout: 30000 });
await agentEntry.first().click();

Chat Input

// Message input (SandboxPage)
const input = page.locator('textarea[aria-label="Message input"]');
await input.fill('my message');
await input.press('Enter');  // Enter sends (not click Send button)

// Or via Send button
await page.getByRole('button', { name: /Send/i }).click();

Agent Response Detection

The agent may respond with text (.sandbox-markdown) or tool calls (ToolCallStep divs). Always check for both:

// Wait for ANY agent output (text or tool calls)
const agentOutput = page.locator('.sandbox-markdown')
  .or(page.locator('text=/Tool Call:|Result:/i'));
await expect(agentOutput.first()).toBeVisible({ timeout: 180000 });

// Count each type
const mdCount = await page.locator('.sandbox-markdown').count();
const toolCount = await page.locator('text=/Tool Call:|Result:/i').count();

.sandbox-markdown

Renders for assistant messages with text content (not tool calls):

<div class="sandbox-markdown">
  <ReactMarkdown>response text here</ReactMarkdown>
</div>

ToolCallStep

Renders for tool_call and tool_result events. Uses <div> with click handler, NOT <details>:

<div style="border-left: 3px solid ...">
  <div style="font-weight: 600">▶ Tool Call: web_fetch</div>
</div>

Selector: page.locator('text=/Tool Call:|Result:/i')

Session URL & Navigation

Capture session URL from test 3 for reuse in tests 4-6:

let sessionUrl: string | null = null;

// After sending message and getting response:
sessionUrl = page.url();
// URL format: /sandbox?session=<context_id>

Navigate to session (avoiding Keycloak re-auth redirect):

WRONG — triggers full page load through Keycloak, redirects to /:

await page.goto(sessionUrl); // Keycloak redirects to /

RIGHT — SPA routing via pushState:

await page.goto('/');
await loginIfNeeded(page);
const sid = sessionUrl.match(/session=([a-f0-9]+)/)?.[1];
await page.evaluate((s) => {
  window.history.pushState({}, '', `/sandbox?session=${s}`);
  window.dispatchEvent(new PopStateEvent('popstate'));
}, sid);
// pushState triggers sync React re-render — no DOM indicator to await
    await page.waitForTimeout(5000);

History Loading (toMessage conversion)

When a session reloads from history, the backend's paginated history API converts agent messages into kind: "data" parts. The frontend toMessage() function must distinguish tool calls from text:

  • kind: "data" + type: "tool_call" → renders as ToolCallStep
  • kind: "data" + type: "tool_result" → renders as ToolCallStep
  • kind: "data" + type: "llm_response" → should render as .sandbox-markdown
  • kind: "text" → always renders as .sandbox-markdown

Known Issues

  1. rca-agent shows "0 sessions" — sessions not tagged with agent name in metadata
  2. TOFU PermissionError — agent Dockerfile needs chmod g+w /app for OCP arbitrary UID
  3. SSE rendering flaky — .sandbox-markdown sometimes doesn't appear during streaming (tool calls render, but final text may not). Workaround: poll with retry.

Test Structure for Serial Agent Tests

test.describe('Agent Workflow', () => {
  test.describe.configure({ mode: 'serial' });
  test.setTimeout(300000);
  let sessionUrl: string | null = null;

  test.beforeAll(() => { /* cleanup agent */ });

  test('1 — deploy', async ({ page }) => { /* wizard + patch */ });
  test('2 — verify card', async ({ page }) => { /* kubectl exec httpx */ });
  test('3 — send message', async ({ page }) => {
    // ... send and wait for response ...
    sessionUrl = page.url();
  });
  test('4 — reload session', async ({ page }) => {
    // Login first, then SPA-navigate to sessionUrl
  });
});

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。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 的全部技能

报告此技能的问题