Agent skill

Ui4 Convert Tests

by payloadcms in payloadcms/payload

A skill your agent uses when UI changes are complete and e2e tests need updating.

MITAuto-check passedTesting & QA

Install Ui4 Convert Tests

skills CLI
$ npx skills add payloadcms/payload --skill ui4-convert-tests -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install payloadcms/payload ui4-convert-tests --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/payloadcms/payload.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/ui4-convert-tests .claude/skills/ui4-convert-tests && rm -rf skills-src

Use ~/.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/

Facts

Skill name
ui4-convert-tests
GitHub stars
45k
Token cost
~3.5k tokens
SKILL.md length
996 words
Files
1
Skills in repo
9
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when UI changes are complete and e2e tests need updating.

  • Works in 7 steps: Analyze What Changed → Find Affected Tests → Analyze Test Dependencies → …
  • UI changes are complete and e2e tests need updating
  • SKILL.md covers Overview, When to Use, Process and Common Patterns (Real Examples), plus 5 more sections
  • Calls pnpm, git and psql

What it does

Ui4 Convert Tests is an agent skill from payloadcms/payload. Use when UI changes are complete and e2e tests need updating. Analyzes what changed in UI components and systematically finds/fixes affected tests.

Its SKILL.md is about 3.5k 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. It works with Payload CMS. The repository describes itself as: Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a… The licence is MIT.

When your agent uses it

  • UI changes are complete and e2e tests need updating
  • Tasks that involve End-to-end testing

Example prompts

  • “/ui4-convert-tests”

Workflow steps

7 steps, taken from the step headings in SKILL.md.

  1. Analyze What Changed
  2. Find Affected Tests
  3. Analyze Test Dependencies
  4. Categorize Fixes Needed
  5. Run Affected Tests
  6. Apply Fixes
  7. Verify Fixes

What it can do on your machine

Read from SKILL.md and the folder at commit ed6a954. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    Shell commands in SKILL.md call:

    • pnpm
    • git
    • psql

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use pnpm and git, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Ui4 Convert Tests loads about 3.5k tokens when it runs. Until then it costs about 41 tokens; SKILL.md has 996 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~41
When it runs · the whole SKILL.md, loaded when a task matches
~3.5k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from payloadcms/payload at commit ed6a954, republished under its MIT licence (© payloadcms). 996 words, ~3,514 tokens.

Download SKILL.mdSave it as .claude/skills/ui4-convert-tests/SKILL.md (or your agent's skills folder).
name
ui4-convert-tests
description
Use when UI changes are complete and e2e tests need updating. Analyzes what changed in UI components and systematically finds/fixes affected tests.

UI4 Convert Tests

Overview

After completing UI changes, this skill systematically identifies and fixes affected e2e tests. It analyzes the diff to understand what kind of changes were made (not just which files), then finds tests that need updates.

When to Use

  • UI changes are finalized and ready for test fixes
  • CI is failing on tests due to your UI changes
  • Before opening a PR to ensure tests pass

Process

Step 1: Analyze What Changed

Goal: Understand the nature of your changes to predict test impact.

bash
# Get changed UI files
git diff main --name-only -- 'packages/ui/src/**/*.tsx' 'packages/ui/src/**/*.css'

For each changed file, categorize the changes:

A. Selector Changes (IDs, classes)
bash
git diff main -- <file> | grep -E '^\-.*className|^\-.*id=|^\+.*className|^\+.*id='
B. Structural Changes (elements moved)

Look for components being:

  • Moved INTO a popup, drawer, or dropdown
  • Wrapped in new parent elements
  • Made conditional
bash
git diff main -- <file> | grep -E 'Popup|PopupList|Drawer|Dropdown'
C. Text/Label Changes
bash
# Translation keys
git diff main -- <file> | grep -E "t\('|i18n\.t\("

# Hardcoded text
git diff main -- <file> | grep -E 'placeholder=|aria-label='

Build a change summary:

Change TypeWhat ChangedTest Impact
Selector.btn:has-text("Create") → #create-new-docUpdate locators
StructureButton moved into popupAdd popup open step
Text"Search by ID" → "Search"Update assertions
Step 2: Find Affected Tests

Search strategy: Cast a wide net, then narrow down.

bash
# Search for component name references (not just selectors)
grep -rn "QueryPreset\|query-preset\|preset" test/**/*.ts --include="*.spec.ts" --include="*.ts"

# Search for specific selectors from Step 1
grep -rn "\.list-header\|Create New\|#create-new" test/**/*.ts

Key test locations:

PatternWhere to Look
Component-specifictest/<feature>/e2e.spec.ts
Shared helperstest/<feature>/helpers/*.ts
Cross-cuttingtest/__helpers/e2e/*.ts
Multiple features using same componentSearch ALL test dirs

Don't just search for exact selectors! Also search for:

  • Component names (e.g., QueryPreset, ListHeader)
  • Feature names (e.g., preset, filter, search)
  • Text content that changed (e.g., "Create New", "Search by")
Step 3: Analyze Test Dependencies

Before fixing, understand the test:

  1. Read the full test - Understand what it's actually testing
  2. Check for helpers - Is there a shared helper that handles this selector?
  3. Look for patterns - Are multiple tests doing the same thing?

If multiple tests use the same selector, create/update a helper:

typescript
// test/<feature>/helpers/togglePreset.ts
export async function openCreatePreset(page: Page) {
  await page.click('#select-preset') // Open popup first
  await page.click('#create-new-preset')
}

This centralizes the fix and prevents future duplication.

Step 4: Categorize Fixes Needed
Change TypeFix Strategy
Selector renamedDirect string replacement
Element moved to popupAdd click to open popup before clicking element
Element moved to drawerAdd drawer open/close handling
Text simplifiedUpdate assertion to match new text
Element removedRework test logic or delete test
Props changedUpdate attribute assertions
Conditional renderingMay need to set up state before element appears
Step 5: Run Affected Tests

Run tests BEFORE making fixes to confirm they actually fail:

bash
# Use isolated port to avoid conflicts
PORT=3150 pnpm test:e2e <suite> --max-failures=1

# Run specific test by name
PORT=3150 pnpm test:e2e <suite> -g "test name" --max-failures=1

Document failure patterns:

  • Timeout waiting for locator('.old-selector') → Selector changed
  • locator resolved to 0 elements → Element moved or removed
  • expected "New Text" received "Old Text" → Text content changed
Step 6: Apply Fixes

Priority: Fix helpers first, then individual tests.

Pattern 1: Selector Renamed
typescript
// Before
await page.click('.list-header .btn:has-text("Create")')

// After - prefer IDs when available
await page.click('#create-new-doc')
Pattern 2: Element Moved Into Popup
typescript
// Before - direct click
await page.click('#edit-preset')

// After - open popup first
await page.click('#select-preset') // Opens the popup
await page.click('#edit-preset') // Now visible in popup
Pattern 3: Text Content Simplified
typescript
// Before - specific placeholder text
await expect(input).toHaveAttribute('placeholder', /(Search by ID)/)

// After - simplified text
await expect(input).toHaveAttribute('placeholder', 'Search')
Pattern 4: Create Reusable Helper

When the same interaction is needed in multiple tests:

typescript
// test/<feature>/helpers/interactions.ts
export async function openEditPreset(page: Page) {
  await page.click('#select-preset')
  await page.click('#edit-preset')
}

// In tests - import and use
import { openEditPreset } from './helpers/interactions.js'
await openEditPreset(page)
Step 7: Verify Fixes
bash
# Run same tests that failed
PORT=3150 pnpm test:e2e <suite> --max-failures=1

Only commit after tests pass.

Common Patterns (Real Examples)

Pattern: Buttons Moved Into Popup Menu

Symptom: Test times out waiting for button that used to be directly visible.

Detection: Check if buttons were wrapped in <Popup> or <PopupList>:

bash
git diff main -- <file> | grep -E 'PopupList|Popup'

Fix: Add popup trigger click before clicking the button:

typescript
// Before: Button was directly in toolbar
await page.click('#edit-preset')

// After: Button is now inside a popup
await page.click('#select-preset') // Opens popup
await page.click('#edit-preset') // Now visible

Bonus: If multiple tests need this, create a helper function.

Pattern: Class-Based Selector → ID Selector

Symptom: .some-class or :has-text("Button Text") no longer finds element.

Detection: Component added id= attribute:

bash
git diff main -- <file> | grep -E '^\+.*id='

Fix: Use the more stable ID:

typescript
// Before: Fragile class + text selector
await page.click('.list-header .btn:has-text("Create New")')

// After: Stable ID selector
await page.click('#create-new-doc')
Pattern: Placeholder/Label Text Simplified

Symptom: Assertion fails with expected "New Text" received "Old Text".

Detection: Translation key or hardcoded text changed:

bash
git diff main -- <file> | grep -E 'placeholder=|t\('

Fix: Update assertion to match new text:

typescript
// Before: Verbose placeholder
await expect(input).toHaveAttribute('placeholder', /(Search by ID, Title)/)

// After: Simplified
await expect(input).toHaveAttribute('placeholder', 'Search')
Pattern: Same Fix Needed Across Multiple Tests

Symptom: Several tests in different suites fail with similar selector issues.

Detection:

bash
# Find all tests using the old selector
grep -rn "old-selector\|.old-class" test/**/*.ts

Fix:

  1. Check if a helper already exists in test/<feature>/helpers/
  2. If yes, fix the helper (fixes all tests at once)
  3. If no, create one and refactor tests to use it
Show full SKILL.md (400 more words)Show less
Pattern: Tests in Different Suites Share Components

When you change a shared component (like ListControls, QueryPresetBar), multiple test suites may be affected.

Detection:

bash
# Find component name references across all tests
grep -rn "QueryPreset\|ListControl" test/**/*.ts | cut -d: -f1 | sort -u

Common cross-suite components:

  • ListControls → affects any list view tests
  • QueryPresetBar → query-presets, group-by, admin tests
  • Search → i18n, admin, most collection tests
  • Button → nearly everything

Quick Reference: Common Payload Test Selectors

ComponentCommon Selectors
Search.search-filter__input, #search-filter-input
List View.collection-list, tbody tr, .table-row
Popup.popup__content, .popup-button-list__button
Modaldialog, [id^=doc-drawer_], [id^=list-drawer_]
Buttons.btn, button[type="button"]
Query Presets#select-preset, .query-preset-bar__*

Test Commands Reference

bash
# Run all e2e tests for a test suite (auto-starts dev server)
PORT=3150 pnpm test:e2e <suite-name>

# Run specific test file
PORT=3150 pnpm test:e2e test/<suite>/e2e.spec.ts

# Run with headed browser (see what's happening)
PORT=3150 pnpm test:e2e:headed test/<suite>/e2e.spec.ts

# Run in debug mode (step through)
PORT=3150 pnpm test:e2e:debug test/<suite>/e2e.spec.ts

# Run specific test by name pattern
PORT=3150 pnpm test:e2e test/<suite>/e2e.spec.ts -g "test name pattern"

# Stop on first failure (useful during debugging)
PORT=3150 pnpm test:e2e test/<suite>/e2e.spec.ts --max-failures=1

Note: The pnpm test:e2e command automatically:

  1. Starts a dev server if the port is free
  2. Reuses an existing dev server if the port is in use
  3. Runs playwright tests against that port

Running Tests with Isolation

Quick Start: Isolated Test Run

Pick a unique port in the 3100-3199 range:

bash
# Run tests on an isolated port (MongoDB auto-starts its own in-memory server)
PORT=3150 pnpm test:e2e query-presets --max-failures=1

That's it for MongoDB (default). Each test run starts its own in-memory MongoDB server, so no database conflicts occur.

Postgres Isolation

For Postgres tests, use a unique database per worktree/repo:

bash
# Create a unique database for this worktree
PGPASSWORD=payload psql -h localhost -p 5433 -U payload -c "CREATE DATABASE payload_worktree1;"

# Run tests against that database
POSTGRES_URL="postgres://payload:payload@localhost:5433/payload_worktree1" \
  PORT=3150 pnpm test:e2e query-presets --max-failures=1

Or use the custom schema approach (no separate DB needed):

bash
# Tests will use a separate schema within the same database
PAYLOAD_DATABASE=postgres-custom-schema PORT=3150 pnpm test:e2e query-presets
Why Isolation Matters
ScenarioPort Conflict?DB Conflict?
MongoDB in-memoryYes (same port)No (each run has own server)
PostgresYes (same port)Yes (same tables)
Multiple worktreesYesYes (Postgres only)

Solution: Always set PORT to avoid port conflicts. For Postgres, also isolate the database.

Common Mistakes

Dev server not running or wrong port: Tests read PORT env var (default 3000). Two approaches:

Option A: Use isolated port (preferred for parallel test suites)

bash
# Run tests on custom port - script handles everything
PORT=3105 pnpm test:e2e test/query-presets/e2e.spec.ts

Option B: Kill existing ports and use default

bash
# Kill all dev server ports
lsof -ti:3000,3001,3002,3003,3004,3005,3006,3007,3008,3009 | xargs kill -9 2>/dev/null

# Tests use 3000 by default
pnpm test:e2e test/query-presets/e2e.spec.ts

Wrong test suite running: Each test suite (fields, query-presets, localization, etc.) has its own Payload config. Tests will fail or behave unexpectedly if the wrong dev server is running.

Not running tests before fixing: Always verify tests actually fail before making changes. If a test passes, don't change it.

Not checking helper files: Test helpers in test/*/helpers/ often contain shared selectors that affect multiple tests.

Missing popup interactions: When elements move into popups, tests need to open the popup first.

Forgetting confirmation dialogs: Delete actions often add confirmation modals - tests need to handle the confirm step.

Placeholder text changes: Search placeholders, button labels, and other text content may change.

Modal slug mismatches: When deleting/confirming actions, the modal slug may change. Check the component code for the actual slug prop passed to <Modal> or drawer components.

Example: QueryPresetBar Changes

Old structure (chips):

typescript
// Direct buttons visible
await page.click('#create-new-preset')
await page.click('#edit-preset')
await page.click('#delete-preset')
await page.click('.chip__remove') // clear

New structure (popup dropdown):

typescript
// Open popup first
await page.click('#select-preset')
// Then click menu items
await page.click('.popup-button-list__button:has-text("Create New")')
await page.click('.popup-button-list__button:has-text("Edit")')
await page.click('.popup-button-list__button:has-text("Delete")')
// Clear uses dedicated button
await page.click('.query-preset-bar__clear')

© payloadcms, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/ui4-convert-tests of payloadcms/payload.

Open the folder on GitHubat commit ed6a954

Compare with similar skills

Ui4 Convert 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.

Ui4 Convert Tests compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Ui4 Convert Tests this skillpayloadcms/payload45k—~3.5kAutomated safety check: PassMIT
Web Application Testinganthropics/skills180k51 repos~966Automated safety check: PassApache-2.0
TDD WorkflowhellangleZ/burn-in-cceverywhere-ralph11211 repos~2.4kAutomated safety check: PassNone
Uloop Replay Inputkurotu/VRCQuestTools3733 repos~615Automated safety check: PassMIT
E2Estackia/rtp2httpd2.2k—~517Automated safety check: PassGPL-2.0
Moav E2EMotherofallVPNs/MoaV448—~1.9kAutomated safety check: NotesMIT

Similar skills

  • Web Application Testing

    anthropics/skills

    Official

    Tests local web applications with Python Playwright scripts, checking frontend behavior, capturing screenshots and reading browser console logs.

    180k GitHub starsUsed in 51 repos~966 tokens
    Testing & QAAuto-check passed
  • TDD Workflow

    hellangleZ/burn-in-cceverywhere-ralph

    A skill your agent uses when writing new features, fixing bugs, or refactoring code.

    112 GitHub starsUsed in 11 repos~2.4k tokens
    Testing & QAAuto-check passed
  • Uloop Replay Input

    kurotu/VRCQuestTools

    Replay recorded PlayMode keyboard and mouse input. An agent skill from kurotu/VRCQuestTools.

    373 GitHub starsUsed in 3 repos~615 tokens
    Testing & QAAuto-check passed
  • E2E

    stackia/rtp2httpd

    Write, run, review, or debug rtp2httpd E2E tests and their harness in e2e/ and scripts/run-e2e.sh.

    2.2k GitHub stars~517 tokensUpdated 5 days ago
    Testing & QAAuto-check passed
  • Moav E2E

    MotherofallVPNs/MoaV

    Run and debug MoaV's end-to-end tests — real protocol connectivity (client-test.sh) and the moav CLI smoke test — against a LIVE server, via the self-hosted e2e workflow or a local test VPS.

    448 GitHub stars~1.9k tokensUpdated yesterday
    Testing & QAAuto-check: notes
  • Web Gui Tester

    BytePioneer-AI/codex-host

    Verify web frontend behavior through real GUI interactions, read-only page inspection, and screenshots.

    2.7k GitHub starsUsed in 1 repo~4.1k tokens
    Testing & QAAuto-check passed

More from payloadcms/payload

All 9 skills in this repo
  • Record PR Demo

    payloadcms/payload

    A skill your agent uses when a Payload pull request needs a concise visual walkthrough for reviewers.

    45k GitHub stars~1k tokensUpdated today
    Auto-check passed
  • Payload

    payloadcms/payload

    A skill your agent uses when working with Payload projects (payload.config.ts, collections, fields, hooks, access control, Payload API).

    45k GitHub starsUsed in 5 repos~6.2k tokens
    Auto-check passed
  • Audit Dependencies

    payloadcms/payload

    A skill your agent uses when fixing dependency vulnerabilities, running pnpm audit, or when the audit-dependencies CI check fails

    45k GitHub stars~2.8k tokensUpdated today
    Auto-check passed
  • Generate Translations

    payloadcms/payload

    A skill your agent uses when new translation keys are added to packages to generate new translations strings

    45k GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Triage CI Flake

    payloadcms/payload

    A skill your agent uses when CI tests fail on main branch after PR merge, when investigating flaky test failures, or when user provides a PR URL/number to aggregate all failing tests

    45k GitHub stars~4.4k tokensUpdated today
    Auto-check passed
  • Payload Accessibility

    payloadcms/payload

    A skill your agent uses when changing or reviewing rendered Payload UI, interaction or focus behavior, semantic markup, accessibility tests, or WCAG/VPAT evidence.

    45k GitHub stars~808 tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about Ui4 Convert Tests

What does Ui4 Convert Tests do?

A skill your agent uses when UI changes are complete and e2e tests need updating. Ui4 Convert Tests is an agent skill from payloadcms/payload. Use when UI changes are complete and e2e tests need updating.

When should I use Ui4 Convert Tests?

Ui4 Convert Tests fits situations like: UI changes are complete and e2e tests need updating; tasks that involve End-to-end testing.

How do I install Ui4 Convert Tests in Claude Code?

Run `npx skills add payloadcms/payload --skill ui4-convert-tests -a claude-code`. Or copy the skill folder (.agents/skills/ui4-convert-tests in payloadcms/payload) into .claude/skills/ui4-convert-tests in your project. Claude Code loads it when a task matches its description.

How do I install Ui4 Convert Tests in Codex?

Run `npx skills add payloadcms/payload --skill ui4-convert-tests -a codex`. Or copy the skill folder (.agents/skills/ui4-convert-tests in payloadcms/payload) into .agents/skills/ui4-convert-tests in your project. Codex loads it when a task matches its description.

Can I use Ui4 Convert Tests in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add payloadcms/payload --skill ui4-convert-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/ui4-convert-tests, .gemini/skills/ui4-convert-tests, .github/skills/ui4-convert-tests and .opencode/skills/ui4-convert-tests in your project.

What does Ui4 Convert Tests need to run?

Going by SKILL.md and its folder, Ui4 Convert Tests needs the command-line tools its instructions call (pnpm, git and psql).

Does Ui4 Convert Tests access the network?

SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Ui4 Convert Tests safe to install?

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.

What licence does Ui4 Convert Tests use?

Ui4 Convert Tests is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Ui4 Convert Tests use?

About 3.5k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Ui4 Convert Tests?

Skills that share tags, products or a category with Ui4 Convert Tests: Web Application Testing (anthropics/skills, 180k stars), TDD Workflow (hellangleZ/burn-in-cceverywhere-ralph, 112 stars), Uloop Replay Input (kurotu/VRCQuestTools, 373 stars) and E2E (stackia/rtp2httpd, 2.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Ui4 Convert Tests?

payloadcms (a GitHub organization) maintains it in payloadcms/payload, which has 45,120 GitHub stars. The repository holds 9 skills in this directory. The repository was last updated on October 7, 2026.

Source: payloadcms/payload on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.