Skill
UI Validation
A skill from the agentic-best-practices ecosystem designed to test visual stress and ensure consistency in modern web interfaces.
The UI Validation skill was designed to handle the common problem where Artificial Intelligences change the project’s CSS and indirectly break layouts, due to their native inability to visualize the exact rendering of modern CSS.
What Does the Skill Do?
The skill (.claude/skills/ui-validation/SKILL.md) forces the AI agent to follow a strict workflow before confirming any visual change:
- Test Environment Generation: If the Kitchen Sink page (
style-guide-test.md) does not exist, the Agent builds it automatically, populating it with tables, blockquotes, KaTeX formulas, and nested code blocks to test the CSS to its limits (Stress Test). - Playwright & Axe-core Setup: The skill ensures the installation of DOM inspection tools and automated accessibility validation (to check color contrast in Light and Dark Themes).
- Design Lint Execution: Whenever a style change occurs, the agent must trigger the
npm run lint:designcommand, validating heuristics listed ingoogle-labs-code/design.md. - Error Resolution: The agent corrects the code and automatically re-runs the validation when finding contrast failures or corrupted DOM.
How to Configure CLAUDE.md
To fluently activate the skill in your repository without cluttering the AI’s master instructions, you should keep your CLAUDE.md focused solely on the trigger.
In the CLAUDE.md file, under the Specific Guides section or equivalent, add ONLY the following line:
## Specific Guides
- **UI Validation:** Whenever changing CSS or asked to validate visual styles, you must follow the process dictated by the `UI Validation` skill and the heuristics in `google-labs-code/design.md`.
With this, whenever you mention “Styles”, “CSS”, or “Validate UI”, the agent will automatically invoke the .claude/skills/ui-validation/SKILL.md directory, pulling all the validation logic into its current context, keeping token cost and bot cognitive overload low when you are focused on writing Backend or another task unrelated to the front-end!
The Code behind the Magic (Snippets)
For technical reference, below are the codes that make up the engine of this visual automation:
1. The SKILL.md File (The robot’s brain)
Located at .claude/skills/ui-validation/SKILL.md:
---
name: Validação de Interface (UI Validation)
description: Rigorous workflow for validating CSS styles, visual rendering, color contrast testing, and using Playwright. Triggered when changes occur in CSS, styles, or when the user requests visual validation.
---
# UI Validation Skill
This skill documents the complete and mandatory flow to validate any visual or design alteration (e.g., in `style.css`).
## 1. Prerequisites (Setup)
If the project is not configured with the UI test environment, you MUST execute the steps below:
1. **Style Guide**: Verify if the `src/notas/style-guide-test.md` page exists. If it doesn't, you must create it.
2. **Playwright and Axe**: Ensure `@playwright/cli` and `@axe-core/playwright` are installed.
3. **Lint Scripts**: The `package.json` must contain `"lint:design": "node test-a11y.js"`.
## 2. Aesthetic Standards (Mandatory)
Always base aesthetic decisions (Colors, Typography, Spacings) on the `google-labs-code/design.md` document.
## 3. The Validation Flow
Whenever the CSS is modified:
1. Render the `style-guide-test/` page.
2. Run the visual lint command using `npm run lint:design`.
3. This script executes automatic tests in **Light Mode** and **Dark Mode**.
4. Any contrast error (Exit Code 1) must be fixed immediately.
2. The Axe-Core Test Script
Located at test-a11y.js and run via npm run lint:design:
const { chromium } = require("playwright");
const AxeBuilder = require("@axe-core/playwright").default;
(async () => {
console.log("Iniciando validação de constraste de design (Axe-core)...");
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
const url = "http://localhost:5500/notas/style-guide-test/";
try {
await page.goto(url);
console.log("Testando Tema Claro (Light Mode)...");
await page.evaluate(() =>
document.documentElement.setAttribute("data-theme", "light"),
);
let results = await new AxeBuilder({ page }).withRules("color-contrast").analyze();
if (results.violations.length > 0) {
console.error("❌ Falha de contraste no Tema Claro");
process.exitCode = 1;
}
console.log("Testando Tema Escuro (Dark Mode)...");
await page.evaluate(() => document.documentElement.removeAttribute("data-theme"));
results = await new AxeBuilder({ page }).withRules("color-contrast").analyze();
if (results.violations.length > 0) {
console.error("❌ Falha de contraste no Tema Escuro");
process.exitCode = 1;
}
} catch (error) {
process.exitCode = 1;
} finally {
await browser.close();
}
})();
Related: agentic-best-practices · frontend-testing-practices