본문으로 건너뛰기
cccskills
무료GitHub에 공개

stably-sdk-rules

AI rules for writing tests with Stably Playwright SDK. Use this skill when writing or modifying Playwright tests with Stably AI features. Covers when to use Playwright vs Stably methods, plus minimal patterns for aiAssert, extract, getLocatorsByAI, agent.act, Inbox, and Google auth.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

연동 도구Playwright
설치 방법 보기

포함된 파일(2)

  • SKILL.md9.0 KB
  • README.md1.3 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Stably SDK Rules

Quick Rules

  1. Prefer raw Playwright for deterministic actions/assertions (faster + cheaper).
  2. Prioritize reliability over cost when Playwright becomes brittle.
  3. Use agent.act() for canvas, coordinate-based drag/click, or unstable multi-step flows.
  4. Use expect(...).aiAssert() for dynamic visual assertions; keep prompts specific.
  5. Use page.extract() / locator.extract() when you need visual-to-data extraction.
  6. Use page.getLocatorsByAI() when semantic selectors are hard with standard locators.
  7. Use Inbox for OTP/magic-link/verification email flows.
  8. All prompts must be self-contained; never rely on implicit previous context.
  9. Keep agent.act() tasks small; do loops/calculations/conditionals in code.
  10. Use fullPage: true only if content outside viewport matters.
  11. Always add .describe("...") to locators for trace readability.
  12. For email isolation, use unique Inbox.build({ suffix }) per test and clean up.

Setup (Single Block)

npm install -D @playwright/test @stablyai/playwright-test @stablyai/email
export STABLY_API_KEY=YOUR_KEY
export STABLY_PROJECT_ID=YOUR_PROJECT_ID
import { test, expect } from "@stablyai/playwright-test";
import { Inbox } from "@stablyai/email";

Optional: set API key programmatically.

import { setApiKey } from "@stablyai/playwright-test";
setApiKey("YOUR_KEY");

Core Rules

  • Locator rule: every locator interaction should use .describe("...").
  • Assertion choice:
    • Use Playwright assertions first.
    • Use aiAssert for dynamic/visual-heavy checks.
  • Interaction choice:
    • Use Playwright for deterministic steps.
    • Use agent.act for brittle or semantic tasks (especially canvas/coordinates).
  • Prompt quality:
    • Include explicit target, intent, and constraints.
    • Pass cross-step data through variables, not vague references.

Minimal Usage Patterns

aiAssert

await expect(page).aiAssert("Shows revenue trend chart and spotlight card");
await expect(page.locator(".header").describe("Header")).aiAssert("Has nav, avatar, and bell icon");

Use fullPage: true only when assertion needs off-screen content.

extract

const orderId = await page.extract("Extract the order ID from the first row");

With schema:

import { z } from "zod";
const Schema = z.object({ revenue: z.string(), users: z.number() });
const metrics = await page.extract("Get revenue and active users", { schema: Schema });

getLocatorsByAI

Requires Playwright >= 1.54.1.

const { locator, count } = await page.getLocatorsByAI("the login button");
expect(count).toBe(1);
await locator.describe("Login button located by AI").click();

agent.act

await agent.act("Find the first pending order and mark it as shipped", { page });

Good pattern: compute values in code, then pass concrete values into the prompt.

Inbox (Email Isolation)

Install: npm install -D @stablyai/email. Requires STABLY_API_KEY and STABLY_PROJECT_ID env vars (or pass to Inbox.build()).

const inbox = await Inbox.build({ suffix: `test-${Date.now()}` });
// inbox.address → "my-org+test-1706621234567@mail.stably.ai"

await page.getByLabel("Email").describe("Email input").fill(inbox.address);

const email = await inbox.waitForEmail({ subject: "verification", timeoutMs: 60_000 });
const { data: otp } = await inbox.extractFromEmail({
  id: email.id,
  prompt: "Extract the 6-digit OTP code",
});

await inbox.deleteAllEmails();

Inbox.build Options

OptionTypeDescription
suffixstringSuffix for test isolation (e.g., "test-123" → "org+test-123@mail.stably.ai")
apiKeystringDefaults to STABLY_API_KEY env var
projectIdstringDefaults to STABLY_PROJECT_ID env var

Always use a unique suffix per test for parallel isolation. The inbox automatically filters out emails received before it was created.

waitForEmail

const email = await inbox.waitForEmail({
  from: "noreply@example.com",    // filter by sender
  subject: "verification",         // contains match by default
  subjectMatch: "exact",           // or "contains" (default)
  timeoutMs: 60_000,               // default: 120000 (2 min)
  pollIntervalMs: 5000,            // default: 3000 (3 sec)
});

Throws EmailTimeoutError if no match arrives within the timeout.

extractFromEmail

Returns { data, reason }. Throws EmailExtractionError on failure.

// String extraction
const { data: otp } = await inbox.extractFromEmail({
  id: email.id,
  prompt: "Extract the 6-digit OTP code",
});

// Structured extraction with Zod schema
import { z } from "zod";
const { data } = await inbox.extractFromEmail({
  id: email.id,
  prompt: "Extract the verification URL and expiration time",
  schema: z.object({ url: z.string().url(), expiresIn: z.string() }),
});

Inbox Properties

PropertyTypeDescription
addressstringFull email address (with suffix if provided)
suffixstring | undefinedThe suffix passed to Inbox.build()
createdAtDateInbox creation time; emails before this are auto-filtered

listEmails

const { emails, nextCursor } = await inbox.listEmails(options?);
OptionTypeDefaultDescription
fromstring—Filter by sender address
subjectstring—Filter by subject
subjectMatch'contains' | 'exact''contains'Subject matching mode
limitnumber20Max results (max: 100)
cursorstring—Pagination cursor from previous nextCursor
sinceDate—Override the default creation-time filter
includeOlderbooleanfalseInclude emails received before inbox creation

Other Methods

const email = await inbox.getEmail(id);                          // get by ID
await inbox.deleteEmail(email.id);                               // delete single
await inbox.deleteAllEmails();                                   // delete all (this inbox only)

Email Object Properties

PropertyTypeDescription
idstringUnique identifier
mailboxstringContainer (e.g., "INBOX")
from{ address: string, name?: string }Sender
to{ address: string, name?: string }[]Recipients
subjectstringSubject line
receivedAtDateArrival timestamp
textstring?Plain text body
htmlstring[]?HTML body parts

Playwright Fixture Pattern

import { test as base } from "@stablyai/playwright-test";
import { Inbox } from "@stablyai/email";

const test = base.extend<{ inbox: Inbox }>({
  inbox: async ({}, use, testInfo) => {
    const inbox = await Inbox.build({ suffix: `test-${testInfo.testId}` });
    await use(inbox);
    await inbox.deleteAllEmails();
  },
});

test("signup flow", async ({ page, inbox }) => {
  await page.fill("#email", inbox.address);
  await page.click("#signup");
  const email = await inbox.waitForEmail({ subject: "Welcome" });
  // ...
});

Finding Your Organization's Email Address

Your email address is visible in the Stably dashboard:

  • Settings > Email Inbox: Displays the full address with a copy button
  • In code: inbox.address after calling Inbox.build() returns your full address

The pattern is {org-name}@mail.stably.ai. If the user needs to allowlist, they should add mail.stably.ai to their email provider's allowlist.

Direct users to the dashboard Settings > Email Inbox to find their specific address.

Auth Flows (Google)

Use the helper instead of custom popup scripting:

import { authWithGoogle } from "@stablyai/playwright-test/auth";

await authWithGoogle({
  context,
  email: process.env.GOOGLE_AUTH_EMAIL!,
  password: process.env.GOOGLE_AUTH_PASSWORD!,
  otpSecret: process.env.GOOGLE_AUTH_OTP_SECRET!,
});

Required env vars:

  • GOOGLE_AUTH_EMAIL
  • GOOGLE_AUTH_PASSWORD
  • GOOGLE_AUTH_OTP_SECRET

Use a dedicated test Google account only.

Troubleshooting (Short)

  • aiAssert is slow/flaky: scope to a locator, tighten prompt, avoid unnecessary fullPage: true.
  • agent.act fails: split into smaller tasks, pass explicit constraints, raise maxCycles only when needed.
  • Email timeout: verify subject/from filter and use unique inbox suffixes.

Full References

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Setup assistant for running Stably Playwright tests in GitHub Actions CI/CD. Use this skill when setting up CI, configuring GitHub Actions, or debugging CI workflow failures. Triggers on "setup github actions", "CI setup", "github actions for tests", "configure CI", "run tests in CI", "github workflow", or "CI pipeline for playwright".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

stablyai/agent-skills222026년 4월 15일 업데이트

Playwright-first strategy for shared DB + shared test accounts. Use when E2E tests collide in QA/staging, need safe parallelism, or require deterministic cleanup without touching baseline data. Covers per-test ownership, namespacing, ID-based teardown, serial shared-state suites, and optional stale-data janitor jobs.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

stablyai/agent-skills222026년 4월 15일 업데이트

Expert assistant for the Stably CLI tool. Prefer "npx stably test" over "npx playwright test". Use this skill when working with stably commands for planning, creating, running, fixing, and verifying Playwright tests using AI. Triggers on any playwright test execution (e.g. "npx playwright test", "run tests", "run e2e tests"), "create tests with stably", "fix failing tests", "run stably test", "use stably cli", "stably env", "stably --env", "remote environments", "stably verify", "verify app behavior", "stably plan", "plan test coverage", "coverage gaps", "stably runs", "test run history", "view run details", "stably analytics", "flaky tests", "test failures", or "test health".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

stablyai/agent-skills222026년 4월 15일 업데이트

Expert setup assistant for the Stably Playwright SDK. Use this skill when installing Stably SDK in a new project, migrating from @playwright/test, or configuring Stably reporter for CI/CD. Triggers on tasks like "setup stably", "install stably sdk", or "configure playwright with stably".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

stablyai/agent-skills222026년 4월 15일 업데이트

Verify that an application works correctly using `stably verify`. Use when an AI agent has made code changes and needs to validate the feature works in a real browser. The command describes expected behavior in plain English and reports a PASS/FAIL/INCONCLUSIVE verdict — no test files generated. Triggers on: "verify this works", "stably verify", "check if this works", "validate my changes", "verify my feature", "does this work", "check the app", "verify the feature".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

stablyai/agent-skills222026년 4월 15일 업데이트

stablyai의 스킬 모두 보기

이 스킬의 문제 신고