Testing Blocks
Guide for testing code changes in AEM Edge Delivery projects including blocks, scripts, and styles. Use this skill after making code changes and before opening a pull request to validate functionality. Covers unit testing for utilities and logic, browser testing with Playwright/Puppeteer, linting, performance validation, and guidance on which tests to maintain vs use as throwaway validation.
Best use case
Testing Blocks is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Guide for testing code changes in AEM Edge Delivery projects including blocks, scripts, and styles. Use this skill after making code changes and before opening a pull request to validate functionality. Covers unit testing for utilities and logic, browser testing with Playwright/Puppeteer, linting, performance validation, and guidance on which tests to maintain vs use as throwaway validation.
Teams using Testing Blocks should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/testing-blocks/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How Testing Blocks Compares
| Feature / Agent | Testing Blocks | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Guide for testing code changes in AEM Edge Delivery projects including blocks, scripts, and styles. Use this skill after making code changes and before opening a pull request to validate functionality. Covers unit testing for utilities and logic, browser testing with Playwright/Puppeteer, linting, performance validation, and guidance on which tests to maintain vs use as throwaway validation.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
Related Guides
SKILL.md Source
# Testing Blocks
This skill guides you through testing code changes in AEM Edge Delivery Services projects. Testing follows a value-versus-cost philosophy: create and maintain tests when the value they bring exceeds the cost of creation and maintenance.
## Related Skills
- **content-driven-development**: Test content created during CDD serves as the basis for testing
- **building-blocks**: This skill is automatically invoked after block implementation
- **block-collection-and-party**: May provide reference test patterns from similar blocks
## When to Use This Skill
Use this skill:
- ✅ After implementing or modifying blocks
- ✅ After changes to core scripts (scripts.js, delayed.js, aem.js)
- ✅ After style changes (styles.css, lazy-styles.css)
- ✅ After configuration changes that affect functionality
- ✅ Before opening any pull request with code changes
This skill should be automatically invoked by the **building-blocks** skill after implementation is complete.
## Testing Philosophy: Value vs Cost
**The Principle:** Create and maintain tests when the value they bring exceeds the cost of creation and maintenance.
### Keeper Tests (High Value, Worth Maintaining)
✅ **Write unit tests for:**
- Logic-heavy utility functions used across multiple blocks
- Data processing and transformation logic
- API integrations and external service interactions
- Complex algorithms or business logic
- Shared libraries and helper functions
These tests provide lasting value because they catch regressions in reused code, serve as living documentation, and are fast and easy to maintain.
### Throwaway Tests (Lower Value, Use Once)
⚠️ **Use browser tests for:**
- Block decoration logic (DOM transformations)
- Specific DOM structures or UI layouts
- Visual appearance validation
- Block-specific rendering behavior
These tests are better done in a browser because DOM structures change frequently, visual validation requires human judgment, and maintaining UI tests is expensive relative to their value.
**Important:** Even throwaway tests have value! Use them to:
1. Validate your implementation works correctly
2. Take screenshots to evaluate visual correctness
3. Show screenshots to humans for feedback
4. Include screenshots in PRs to aid review
**Organization:** Keep throwaway tests in `test/tmp/` and test content in `drafts/tmp/`. Both directories should be gitignored so temporary test artifacts aren't committed.
## Testing Checklist
Before opening a pull request, complete ALL of the following:
- [ ] **Existing tests pass** - All keeper tests still pass with your changes
- [ ] **Unit tests written** - New keeper tests for any logic-heavy utilities or data processing
- [ ] **Browser validation** - Feature tested in local dev server, screenshots captured
- [ ] **All variants tested** - Each variant/configuration of blocks validated
- [ ] **Responsive behavior** - Tested on mobile, tablet, desktop viewports
- [ ] **Linting passes** - `npm run lint` completes without errors
- [ ] **Branch pushed** - Code committed and pushed to feature branch
- [ ] **GitHub checks verified** - Use `gh checks` to confirm all CI checks pass
## Testing Methods Overview
### 1. Unit Tests (KEEPER TESTS)
**When to use:** Logic-heavy functions, utilities, data processing, API integrations
**Quick start:**
```bash
# Verify test setup (see resources/vitest-setup.md if not configured)
npm test
# Write test for utility function
# test/utils/my-utility.test.js
import { describe, it, expect } from 'vitest';
import { myUtility } from '../../scripts/utils/my-utility.js';
describe('myUtility', () => {
it('should transform input correctly', () => {
expect(myUtility('input')).toBe('OUTPUT');
});
});
# Run tests during development
npm run test:watch
```
**Detailed guide:** See `resources/unit-testing.md`
### 2. Browser Testing (THROWAWAY TESTS)
**When to use:** Block decoration, visual validation, DOM structure, responsive design
**Organization:**
- Test scripts: `test/tmp/test-{block}-browser.js`
- Test content: `drafts/tmp/{block}.html`
- Screenshots: `test/tmp/screenshots/`
- Both `test/tmp/` and `drafts/tmp/` should be gitignored
**Quick start:**
```bash
# Install Playwright
npm install --save-dev playwright
npx playwright install chromium
# Create test content
# drafts/tmp/my-block.html (copy head.html content, add test markup)
# Start dev server with drafts folder
aem up --html-folder drafts
# Create throwaway test script in test/tmp/
# test/tmp/test-my-block.js
import { chromium } from 'playwright';
import { mkdir } from 'fs/promises';
async function test() {
await mkdir('./test/tmp/screenshots', { recursive: true });
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
await page.goto('http://localhost:3000/drafts/tmp/my-block');
await page.waitForSelector('.my-block');
await page.screenshot({
path: './test/tmp/screenshots/my-block.png',
fullPage: true
});
await browser.close();
}
test().catch(console.error);
# Run the test
node test/tmp/test-my-block.js
# Clean up when done (optional - gitignored either way)
rm -rf test/tmp/*
```
**Detailed guide:** See `resources/browser-testing.md`
### 3. Linting (ALWAYS)
**When to use:** Before every commit
**Quick start:**
```bash
# Run linting
npm run lint
# Auto-fix issues
npm run lint:fix
```
**Linting MUST pass before opening a PR.** Non-negotiable.
### 4. Performance Testing (AUTOMATED)
**When to use:** After pushing branch, automatically via GitHub checks
**Quick start:**
```bash
# Push branch
git push -u origin your-branch
# Create PR with test link
# PR description MUST include:
# Preview: https://branch--repo--owner.aem.page/path/to/test
# Monitor checks
gh pr checks --watch
```
Performance tests run automatically when you include a test link in your PR description.
## Complete Workflow
For detailed step-by-step workflow, see `resources/testing-workflow.md`.
**Quick summary:**
### During Development
1. Write unit tests for new utilities
2. Run `npm run test:watch`
3. Manually test in browser
### Before Committing
4. Run `npm test` - all tests pass
5. Run `npm run lint` - linting passes
6. Write throwaway browser test in `test/tmp/`
7. Create test content in `drafts/tmp/`
8. Review screenshots from `test/tmp/screenshots/`
9. Manual validation in browser
### Before Opening PR
10. Commit and push to feature branch (test/tmp/ won't be included)
11. Verify branch preview loads
12. Run `gh checks`
13. Create PR with test link
14. Monitor `gh pr checks`
### After PR Review
15. Address feedback
16. Re-test
17. Verify checks pass
## Troubleshooting
For detailed troubleshooting guide, see `resources/troubleshooting.md`.
**Common issues:**
### Tests fail
- Read error message carefully
- Run single test: `npm test -- path/to/test.js`
- Fix code or update test
### Linting fails
- Run `npm run lint:fix`
- Manually fix remaining issues
### GitHub checks fail
- Ensure PR has test link
- Check `gh pr checks` for details
- Fix performance issues if PSI fails
### Browser tests fail
- Verify dev server running: `aem up --html-folder drafts`
- Check test content exists in `drafts/tmp/`
- Verify URL uses `/tmp/` path: `http://localhost:3000/drafts/tmp/my-block`
- Add waits: `await page.waitForSelector('.block')`
## Resources
- **Unit Testing:** `resources/unit-testing.md` - Complete guide to writing and maintaining unit tests
- **Browser Testing:** `resources/browser-testing.md` - Playwright/Puppeteer workflows and best practices
- **Testing Workflow:** `resources/testing-workflow.md` - Step-by-step workflow from dev to PR
- **Troubleshooting:** `resources/troubleshooting.md` - Solutions to common testing issues
- **Vitest Setup:** `resources/vitest-setup.md` - One-time configuration guide
## Integration with Building Blocks Skill
The **building-blocks** skill automatically invokes this skill after implementation.
**Expected flow:**
1. Building blocks completes implementation
2. Invokes **testing-blocks** skill
3. This skill guides testing process
4. Returns control when testing complete
**Building blocks provides:**
- Block name being tested
- Test content URL from CDD process
- Any variants that need testing
**This skill returns:**
- Confirmation all tests pass
- Screenshots from browser testing (if requested)
- Any issues discovered during testing
## Summary
Testing in AEM Edge Delivery follows a pragmatic value-versus-cost approach:
**Create keeper tests for:**
- Logic-heavy utilities
- Data processing and transformations
- API integrations
- Shared libraries
**Use throwaway browser tests for:**
- Block decoration validation
- Visual appearance
- DOM structure
- Interactive behavior
**Always do:**
- Run linting before commits
- Test manually in browser
- Verify GitHub checks pass
- Include test links in PRs
**Remember:** The goal is confidence that your code works correctly, not achieving 100% test coverage. Write tests that provide value, and validate everything else in a browser.Related Skills
webapp-testing
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
jupyter-notebook-testing
Create and manage Jupyter notebooks for testing Adobe Edge Delivery Services (EDS) blocks interactively in the browser using the ipynb-viewer block. Interactive JavaScript execution, overlay previews with backdrop, direct ES6 imports. Use when creating notebooks, testing blocks with ipynb files in browser, generating overlay previews, or creating executable documentation.
eds-block-testing
Guide for testing EDS blocks using test.html files and the development server. Covers test file structure, EDS core integration, testing patterns, and debugging workflows for Adobe Edge Delivery Services blocks.
Building Blocks
Guide for creating new AEM Edge Delivery blocks or modifying existing blocks. Use this skill whenever you are creating a new block from scratch or making significant changes to existing blocks that involve JavaScript decoration, CSS styling, or content model changes.
theme-factory
Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.
template-skill
Replace with description of the skill and when Claude should use it.
slack-gif-creator
Toolkit for creating animated GIFs optimized for Slack, with validators for size constraints and composable animation primitives. This skill applies when users request animated GIFs or emoji animations for Slack from descriptions like "make me a GIF for Slack of X doing Y".
skill-developer
Create and manage Claude Code skills following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns, file paths, content patterns), enforcement levels (block, suggest, warn), hook mechanisms (UserPromptSubmit, PreToolUse), session tracking, and the 500-line rule.
skill-creator
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
scrape-webpage
Scrape webpage content, extract metadata, download images, and prepare for import/migration to AEM Edge Delivery Services. Returns analysis JSON with paths, metadata, cleaned HTML, and local images.
preview-import
Preview and verify imported content in local AEM Edge Delivery Services dev server. Validates rendering, compares with original page, and troubleshoots common issues.
page-import
Import a single webpage from any URL to structured HTML content for authoring in AEM Edge Delivery Services. Scrapes the page, analyzes structure, maps to existing blocks, and generates HTML for immediate local preview. Also triggered by terms like "migrate", "migration", or "migrating".