Cucumber and Playwright E2E Tests
langgenius/dify
Guides changes and reviews of the Cucumber and Playwright end-to-end suite under `e2e/`: feature files, step definitions, support code, tags, locators and assertions.
Diagnoses and fixes flaky Playwright e2e tests by replacing race-prone patterns with retry-safe alternatives.
$ npx skills add Comfy-Org/ComfyUI_frontend --skill hardening-flaky-e2e-tests -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install Comfy-Org/ComfyUI_frontend hardening-flaky-e2e-tests --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/Comfy-Org/ComfyUI_frontend.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/hardening-flaky-e2e-tests .claude/skills/hardening-flaky-e2e-tests && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "hardening-flaky-e2e-tests" agent skill from https://github.com/Comfy-Org/ComfyUI_frontend/tree/main/.claude/skills/hardening-flaky-e2e-tests into .claude/skills/hardening-flaky-e2e-tests/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hardening-flaky-e2e-tests", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/Comfy-Org/ComfyUI_frontend/tree/main/.claude/skills/hardening-flaky-e2e-testsType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add Comfy-Org/ComfyUI_frontend --skill hardening-flaky-e2e-tests -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install Comfy-Org/ComfyUI_frontend hardening-flaky-e2e-tests --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Comfy-Org/ComfyUI_frontend.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/hardening-flaky-e2e-tests .agents/skills/hardening-flaky-e2e-tests && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "hardening-flaky-e2e-tests" agent skill from https://github.com/Comfy-Org/ComfyUI_frontend/tree/main/.claude/skills/hardening-flaky-e2e-tests into .agents/skills/hardening-flaky-e2e-tests/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hardening-flaky-e2e-tests", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Comfy-Org/ComfyUI_frontend --skill hardening-flaky-e2e-tests -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install Comfy-Org/ComfyUI_frontend hardening-flaky-e2e-tests --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Comfy-Org/ComfyUI_frontend.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/hardening-flaky-e2e-tests .cursor/skills/hardening-flaky-e2e-tests && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "hardening-flaky-e2e-tests" agent skill from https://github.com/Comfy-Org/ComfyUI_frontend/tree/main/.claude/skills/hardening-flaky-e2e-tests into .cursor/skills/hardening-flaky-e2e-tests/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hardening-flaky-e2e-tests", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/Comfy-Org/ComfyUI_frontend.git --path .claude/skills/hardening-flaky-e2e-tests--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add Comfy-Org/ComfyUI_frontend --skill hardening-flaky-e2e-tests -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install Comfy-Org/ComfyUI_frontend hardening-flaky-e2e-tests --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Comfy-Org/ComfyUI_frontend.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/hardening-flaky-e2e-tests .gemini/skills/hardening-flaky-e2e-tests && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "hardening-flaky-e2e-tests" agent skill from https://github.com/Comfy-Org/ComfyUI_frontend/tree/main/.claude/skills/hardening-flaky-e2e-tests into .gemini/skills/hardening-flaky-e2e-tests/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hardening-flaky-e2e-tests", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install Comfy-Org/ComfyUI_frontend hardening-flaky-e2e-testsInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add Comfy-Org/ComfyUI_frontend --skill hardening-flaky-e2e-tests -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/Comfy-Org/ComfyUI_frontend.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/hardening-flaky-e2e-tests .github/skills/hardening-flaky-e2e-tests && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "hardening-flaky-e2e-tests" agent skill from https://github.com/Comfy-Org/ComfyUI_frontend/tree/main/.claude/skills/hardening-flaky-e2e-tests into .github/skills/hardening-flaky-e2e-tests/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hardening-flaky-e2e-tests", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Comfy-Org/ComfyUI_frontend --skill hardening-flaky-e2e-tests -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install Comfy-Org/ComfyUI_frontend hardening-flaky-e2e-tests --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Comfy-Org/ComfyUI_frontend.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/hardening-flaky-e2e-tests .opencode/skills/hardening-flaky-e2e-tests && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "hardening-flaky-e2e-tests" agent skill from https://github.com/Comfy-Org/ComfyUI_frontend/tree/main/.claude/skills/hardening-flaky-e2e-tests into .opencode/skills/hardening-flaky-e2e-tests/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hardening-flaky-e2e-tests", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
hardening-flaky-e2e-testsDiagnoses and fixes flaky Playwright e2e tests by replacing race-prone patterns with retry-safe alternatives.
Hardening Flaky E2E Tests is an agent skill from Comfy-Org/ComfyUI_frontend. Diagnoses and fixes flaky Playwright e2e tests by replacing race-prone patterns with retry-safe alternatives. Use when triaging CI flakes, hardening spec files, fixing timing races, or asked to stabilize browser tests. Triggers on: flaky, flake, harden, stabilize, race condition in e2e, intermittent failure.
Its SKILL.md is about 2.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Testing & QA, covering End-to-end testing, Failing and flaky tests and Async programming. It works with Playwright. The repository describes itself as: Official front-end implementation of ComfyUI. The licence is GPL-3.0.
7 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit f9be289. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
ghgitpnpmFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use gh, git and pnpm, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Hardening Flaky E2E Tests loads about 2.8k tokens when it runs. Until then it costs about 84 tokens; SKILL.md has 806 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from Comfy-Org/ComfyUI_frontend at commit f9be289, republished under its GPL-3.0 licence (© Comfy-Org). 806 words, ~2,782 tokens.
.claude/skills/hardening-flaky-e2e-tests/SKILL.md (or your agent's skills folder).Fix flaky Playwright specs by identifying race-prone patterns and replacing them with retry-safe alternatives. This skill covers diagnosis, pattern matching, and mechanical transforms — not writing new tests (see writing-playwright-tests for that). The general rules behind every transform here (wait on the real readiness boundary, never sleep, never weaken an assertion, check history before removing a guard) are in docs/guidance/testing-principles.md.
gh run list --workflow=ci-test.yaml --limit=5
gh run download <run-id> -n playwright-reportreport.json and search for "status": "flaky" entries.error-context.md, traces, and page snapshots before editing code.Read the failing assertion and match it against the pattern table. Most flakes fall into one of these categories:
| # | Pattern | Signature in Code | Fix |
|---|---|---|---|
| 1 | Snapshot-then-assert | expect(await evaluate()).toBe(x) | await expect.poll(() => evaluate()).toBe(x) |
| 2 | Immediate count | const n = await loc.count(); expect(n).toBe(3) | await expect(loc).toHaveCount(3) |
| 3 | nextFrame after menu click | clickMenuItem(x); nextFrame() | clickMenuItem(x); contextMenu.waitForHidden() |
| 4 | Tight poll timeout | expect.poll(..., { timeout: 250 }) | ≥2000 ms; prefer default 5000 ms |
| 5 | Immediate evaluate after mutation | setSetting(k, v); expect(await evaluate()).toBe(x) | await expect.poll(() => evaluate()).toBe(x) |
| 6 | Screenshot without readiness | loadWorkflow(); nextFrame(); toHaveScreenshot() | Assert the expected node state with a retrying assertion first |
| 7 | Non-deterministic node order | getNodeRefsByType('X')[0] with >1 match | getNodeRefById(id) or guard toHaveLength(1) |
| 8 | Fake readiness helper | Helper clicks but doesn't assert state | Remove; poll the actual value |
| 9 | Immediate graph state after drop | expect(await getLinkCount()).toBe(1) | await expect.poll(() => getLinkCount()).toBe(1) |
| 10 | Immediate boundingBox/layout read | const box = await loc.boundingBox(); expect(box!.width) | await expect.poll(() => loc.boundingBox().then(b => b?.width)) |
toBeVisible(), toHaveText(), toHaveCount(), toHaveClass()expect.poll(() => asyncFn()).toBe(expected)expect(async () => { ... }).toPass()waitForTimeout() to hide a race.// ✅ Single value — use expect.poll
await expect
.poll(() => comfyPage.page.evaluate(() => window.app!.graph.links.length))
.toBe(3)
// ✅ Locator count — use toHaveCount
await expect(comfyPage.page.locator('.dom-widget')).toHaveCount(2)
// ✅ Multiple conditions — use toPass
await expect(async () => {
expect(await node1.getValue()).toBe('foo')
expect(await node2.getValue()).toBe('bar')
}).toPass({ timeout: 5000 })Visible is not always ready. Prefer user-facing assertions when possible; poll internal state only when there is no UI surface to assert on.
Vue-node tests must use @vue-nodes; the fixture enables the renderer and waits
for initial readiness. Never manually set Comfy.VueNodes.Enabled or call
comfyPage.vueNodes.waitForNodes() in tests.
Common readiness boundaries:
| After this action... | Wait for... |
|---|---|
| Canvas interaction (drag, click node) | await comfyPage.nextFrame() |
| Menu item click | await contextMenu.waitForHidden() |
| Workflow load | await comfyPage.workflow.loadWorkflow(...) (built-in wait) |
| Settings write | Poll the setting value with expect.poll() |
| Node pin/bypass/collapse toggle | await expect.poll(() => nodeRef.isPinned()).toBe(true) |
| Graph mutation (add/remove node, link) | Poll link/node count |
| Clipboard write | Poll pasted value |
| Screenshot | Assert expected node state with a retrying assertion |
When a helper returns a count via await loc.count(), callers can't use toHaveCount(). Expose the underlying Locator as a getter so callers choose between:
// Helper exposes locator
get domWidgets(): Locator {
return this.page.locator('.dom-widget')
}
// Caller uses retrying assertion
await expect(comfyPage.domWidgets).toHaveCount(2)Replace count methods with locator getters so callers can use retrying assertions directly.
// ❌ Race: count can change between check and waitFor
const count = await locator.count()
if (count > 0) {
await locator.waitFor({ state: 'hidden' })
}
// ✅ Direct: waitFor handles both cases
await locator.waitFor({ state: 'hidden' })force: true bypasses actionability checks, hiding real animation/visibility races. Remove it and fix the underlying timing issue.
// ❌ Hides the race
await closeButton.click({ force: true })
// ✅ Surfaces the real issue — fix with proper wait
await closeButton.click()
await dialog.waitForHidden()When getNodeRefsByType returns multiple nodes, the order is not guaranteed. Don't use index [0] blindly.
// ❌ Assumes order
const node = (await comfyPage.nodeOps.getNodeRefsByType('CLIPTextEncode'))[0]
// ✅ Find by ID or proximity
const nodes = await comfyPage.nodeOps.getNodeRefsByType('CLIPTextEncode')
let target = nodes[0]
for (const n of nodes) {
const pos = await n.getPosition()
if (Math.abs(pos.y - expectedY) < minDist) target = n
}Or guard the assumption:
const nodes = await comfyPage.nodeOps.getNodeRefsByType('CLIPTextEncode')
expect(nodes).toHaveLength(1)
const node = nodes[0]Some UI elements (e.g. LiteGraph's graphdialog) have built-in dismiss delays. Retry the entire dismiss action:
// ✅ Retry click+assert together
await expect(async () => {
await comfyPage.canvas.click({ position: { x: 10, y: 10 } })
await expect(dialog).toBeHidden({ timeout: 500 })
}).toPass({ timeout: 5000 })# Targeted rerun with repetition
pnpm test:browser:local -- browser_tests/tests/myFile.spec.ts --repeat-each 10
# Single test by line number (avoids grep quoting issues on Windows)
pnpm test:browser:local -- browser_tests/tests/myFile.spec.ts:42--repeat-each 10 for targeted flake verification (use 20 for single test cases).After pushing, use gh to monitor the E2E workflow:
# Find the run for the current branch
gh run list --workflow="CI: Tests E2E" --branch=$(git branch --show-current) --limit=1
# Watch it live (blocks until complete, streams logs)
gh run watch <run-id>
# One-liner: find and watch the latest E2E run for the current branch
gh run list --workflow="CI: Tests E2E" --branch=$(git branch --show-current) --limit=1 --json databaseId --jq ".[0].databaseId" | xargs gh run watchOn Windows (PowerShell):
# One-liner equivalent
gh run watch (gh run list --workflow="CI: Tests E2E" --branch=$(git branch --show-current) --limit=1 --json databaseId --jq ".[0].databaseId")After the run completes:
# Download the Playwright report artifact
gh run download <run-id> -n playwright-report
# View the run summary in browser
gh run view <run-id> --webAlso watch the unit test workflow in parallel if you changed helpers:
gh run list --workflow="CI: Tests Unit" --branch=$(git branch --show-current) --limit=1Before merging a flaky-test fix, confirm:
These are local distractions, not CI root causes:
EPERM while restoring the local browser-test user data directoryRules:
© Comfy-Org, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/hardening-flaky-e2e-tests of Comfy-Org/ComfyUI_frontend.
Open the folder on GitHubat commit f9be289
Hardening Flaky E2E Tests next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Hardening Flaky E2E Tests this skillComfy-Org/ComfyUI_frontend | 2.1k | — | ~2.8k | Automated safety check: Pass | GPL-3.0 | |
| Cucumber and Playwright E2E Testslanggenius/dify | 158k | — | ~682 | Automated safety check: Pass | Custom licence | |
| Studio E2E Testssupabase/supabase | 111k | — | ~2.8k | Automated safety check: Pass | Apache-2.0 | |
| Debug Playwrightquay/quay | 2.8k | — | ~1.2k | Automated safety check: Pass | Apache-2.0 | |
| Playwright Testingchongdashu/vibejam-starter-pack | 149 | — | ~2.1k | Automated safety check: Pass | None | |
| Playwright Testingchongdashu/vibejam-starter-pack | 149 | — | ~2.2k | Automated safety check: Pass | None |
langgenius/dify
Guides changes and reviews of the Cucumber and Playwright end-to-end suite under `e2e/`: feature files, step definitions, support code, tags, locators and assertions.
supabase/supabase
Write and run Playwright E2E tests for Supabase Studio (e2e/studio).
quay/quay
Debug Playwright E2E test failures from GitHub Actions CI runs.
chongdashu/vibejam-starter-pack
Plan, implement, and debug frontend tests: unit/integration/E2E/visual/a11y.
chongdashu/vibejam-starter-pack
Plan, implement, and debug frontend tests: unit/integration/E2E/visual/a11y.
sendou-ink/sendou.ink
Run, debug, and manage Playwright e2e tests. An agent skill from sendou-ink/sendou.ink.
Comfy-Org/ComfyUI_frontend
Adds deprecation warnings for renamed or removed properties/APIs.
Comfy-Org/ComfyUI_frontend
Replay recorded agent conversations as Playwright tests against the real chat panel and canvas.
Comfy-Org/ComfyUI_frontend
Transforms raw Playwright codegen output into ComfyUI convention-compliant tests.
Comfy-Org/ComfyUI_frontend
Dispatches the comment-sicko subagent to hunt gratuitous comments in a PR/diff, triages its raw findings, and posts a polite, professional writeup.
Comfy-Org/ComfyUI_frontend
Ships performance fixes with CI-proven improvement using stacked PRs.
Comfy-Org/ComfyUI_frontend
Publishes a new package from this monorepo to npm under @comfyorg and proves it is consumable from another repo.
Works with
Categories
Diagnoses and fixes flaky Playwright e2e tests by replacing race-prone patterns with retry-safe alternatives. Hardening Flaky E2E Tests is an agent skill from Comfy-Org/ComfyUI_frontend. Diagnoses and fixes flaky Playwright e2e tests by replacing race-prone patterns with retry-safe alternatives.
Hardening Flaky E2E Tests fits situations like: triaging CI flakes; hardening spec files; fixing timing races; asked to stabilize browser tests.
Run `npx skills add Comfy-Org/ComfyUI_frontend --skill hardening-flaky-e2e-tests -a claude-code`. Or copy the skill folder (.claude/skills/hardening-flaky-e2e-tests in Comfy-Org/ComfyUI_frontend) into .claude/skills/hardening-flaky-e2e-tests in your project. Claude Code loads it when a task matches its description.
Run `npx skills add Comfy-Org/ComfyUI_frontend --skill hardening-flaky-e2e-tests -a codex`. Or copy the skill folder (.claude/skills/hardening-flaky-e2e-tests in Comfy-Org/ComfyUI_frontend) into .agents/skills/hardening-flaky-e2e-tests in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Comfy-Org/ComfyUI_frontend --skill hardening-flaky-e2e-tests -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/hardening-flaky-e2e-tests, .gemini/skills/hardening-flaky-e2e-tests, .github/skills/hardening-flaky-e2e-tests and .opencode/skills/hardening-flaky-e2e-tests in your project.
Going by SKILL.md and its folder, Hardening Flaky E2E Tests needs the command-line tools its instructions call (gh, git and pnpm).
SKILL.md contains no URLs. Its commands use gh and git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Hardening Flaky E2E Tests is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Hardening Flaky E2E Tests: Cucumber and Playwright E2E Tests (langgenius/dify, 158k stars), Studio E2E Tests (supabase/supabase, 111k stars), Debug Playwright (quay/quay, 2.8k stars) and Playwright Testing (chongdashu/vibejam-starter-pack, 149 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Comfy-Org (a GitHub organization) maintains it in Comfy-Org/ComfyUI_frontend, which has 2,056 GitHub stars. The repository holds 22 skills in this directory. The repository was last updated on October 9, 2026.
Source: Comfy-Org/ComfyUI_frontend on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.