plugins/aem/edge-delivery-services/skills/testing-blocks/SKILL.md
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, linting, and guidance on what to test and how
npx skillsauth add adobe/skills testing-blocksInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.
CRITICAL: Browser validation is MANDATORY. You cannot complete this skill without providing proof of functional testing in a real browser environment.
Use this skill:
This skill is typically invoked by the building-blocks skill during Step 5 (Test Implementation).
Track your progress:
Run linting first to catch code quality issues:
npm run lint
If linting fails:
npm run lint:fix
Manually fix remaining issues that auto-fix couldn't handle.
Success criteria:
Mark complete when: npm run lint passes with no errors
CRITICAL: You must test in a real browser and provide proof.
Load test content URL(s) in browser and validate:
Choose the method that makes most sense given your available tools:
Option 1: Browser/Playwright MCP (Recommended)
If you have MCP browser or Playwright tools available, use them directly:
Option 2: Playwright automation
Write one (or more) temporary test scripts to validate functionality with playwright and capture snapshots/screenshots for inspection and validation.
// test-my-block.js (temporary - don't commit)
import { chromium } from 'playwright';
async function test() {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
// Navigate and wait for block
await page.goto('http://localhost:3000/path/to/test');
await page.waitForSelector('.my-block');
// Inspect accessibility tree (useful for validating structure)
const accessibilityTree = await page.accessibility.snapshot();
console.log('Accessibility tree:', JSON.stringify(accessibilityTree, null, 2));
// Optionally save to file for easier analysis
await require('fs').promises.writeFile(
'accessibility-tree.json',
JSON.stringify(accessibilityTree, null, 2)
);
// Test viewports and take screenshots
await page.setViewportSize({ width: 375, height: 667 });
await page.screenshot({ path: 'mobile.png', fullPage: true });
await page.locator('.my-block').screenshot({ path: 'mobile-block.png' });
await page.setViewportSize({ width: 768, height: 1024 });
await page.screenshot({ path: 'tablet.png', fullPage: true });
await page.locator('.my-block').screenshot({ path: 'tablet-block.png' });
await page.setViewportSize({ width: 1200, height: 800 });
await page.screenshot({ path: 'desktop.png', fullPage: true });
await page.locator('.my-block').screenshot({ path: 'desktop-block.png' });
// Check for console errors
page.on('console', msg => console.log('Browser:', msg.text()));
await browser.close();
}
test().catch(console.error);
Run: node test-my-block.js then delete the script and analyze the resulting artifacts.
Option 3: Manual browser testing
Use a standard web browser with dev tools:
http://localhost:3000/path/to/test/contentIf acceptance criteria provided (from CDD Step 2):
If design/mockup screenshots provided:
You must provide:
Success criteria:
Mark complete when: Browser testing complete with screenshots as proof
Determine if unit tests are needed for this change.
Write unit tests when:
Skip unit tests when:
For guidance on what to test: See references/testing-philosophy.md
If unit tests needed:
# Verify test setup (see references/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');
});
});
For detailed unit testing guidance: See references/unit-testing.md
Success criteria:
npm testMark complete when: Unit tests written and passing, or determined not needed
Verify your changes don't break existing functionality:
npm test
If tests fail:
npm test -- path/to/test.jsSuccess criteria:
Mark complete when: npm test passes with no failures
For detailed troubleshooting guide, see references/troubleshooting.md.
Common issues:
npm test -- path/to/test.jsnpm run lint:fixaem up --html-folder draftsdrafts/tmp//tmp/ path: http://localhost:3000/drafts/tmp/my-blockawait page.waitForSelector('.block')The building-blocks skill invokes this skill during Step 5 (Test Implementation).
Inputs received from building-blocks:
Expected outputs to return to building-blocks:
development
Start AEM Workflows on AEM as a Cloud Service using all available triggering mechanisms. Use when starting workflows manually via the Timeline UI, programmatically via WorkflowSession.startWorkflow(), via the HTTP Workflow API, through Manage Publication, or passing initial metadata and payload to a workflow instance.
development
Single entry point for all AEM as a Cloud Service Workflow skills. Covers workflow model design, custom process step and participant chooser development, launcher configuration, workflow triggering, and production support including debugging stuck/failed workflows, triaging incidents with Cloud Manager logs, thread pool analysis, and Sling Job diagnostics for the Granite Workflow Engine.
development
[BETA] Implement custom AEM Workflow Java components on AEM as a Cloud Service. This skill is in beta. Verify all outputs before applying them to production projects. Use when writing WorkflowProcess steps, ParticipantStepChooser implementations, registering services via OSGi DS R6 annotations, reading step arguments from MetaDataMap, accessing JCR payload via WorkflowSession adapter, reading and writing workflow metadata and variables, and handling errors with WorkflowException for retry behavior.
development
Start AEM Workflows on AEM 6.5 LTS using all available triggering mechanisms. Use when starting workflows manually via the Timeline UI, programmatically via WorkflowSession.startWorkflow(), via the HTTP Workflow API, through Manage Publication, through replication triggers, or passing initial metadata and payload to a workflow instance.