Generate E2E tests for Salesforce Commerce Cloud storefront using CodeceptJS with AI-powered features. Specializes in commerce-specific test patterns, page objects, and interactive development workflows.
Instalação
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Generate E2E tests for Salesforce Commerce Cloud storefront using CodeceptJS with AI-powered features. Specializes in commerce-specific test patterns, page objects, and interactive development workflows.
Generate Storefront E2E Test
Systematically create end-to-end tests for Salesforce Commerce Cloud storefront using CodeceptJS Framework with AI-powered features. This skill focuses on commerce-specific test patterns and leverages DOM-driven AI capabilities.
Prerequisites
Before starting, ensure you understand the storefront context:
view CLAUDE.md # in current package directory
Workflow
1. Define Test Requirements
Understand the commerce scenario:
Identify storefront functionality to test (search, cart, checkout, etc.)
List specific test cases for commerce flows
IMPORTANT: Always ask clarifying questions about the test scope
IMPORTANT: Focus on actual storefront, NOT demo/workbench environments
Example questions:
"Should this test cover both desktop and mobile views?"
"Do you want to test guest checkout or authenticated user flow?"
"Should we validate SFCC cookies and session management?"
"Which product categories or search terms should we use?"
1.5. Audit Existing Unit Tests and Storybook Stories
Review existing tests before writing E2E scenarios to understand what's already covered and ensure E2E tests focus on integration value.
Key principle: E2E tests should validate flows that require real authentication, routing, cross-component interactions, or live API data — not duplicate component-isolated unit tests or Storybook play functions.
2. Verify Storefront Context
Check storefront implementation to understand:
Environment Configuration:
Verify .env exists (gitignored, maintained by developers/CI)
If .env doesn't exist, copy from .env.sample
Confirm BASE_URL points to actual storefront (not demo)
Check SITE_ID configuration for cookie validation
Existing Page Objects:
view src/pages/**/*.page.ts
Look for reusable page objects (storefrontPage, cartPage, etc.)
Identify if new page objects are needed
Existing Tests:
view src/specs/**/*.spec.ts
Review existing test patterns and tags
Ensure no duplication of test scenarios
3. Get User Approval
Present test plan to user:
List specific test scenarios you'll create
Explain commerce flows to be covered
Confirm AI features to be demonstrated (pause(), I.askForPageObject())
Specify tags and organization strategy
Wait for approval before proceeding to implementation.
4. Implement Tests with AI Features
Create tests using Scenario-Mocha style:
Feature('Storefront Commerce Tests').tag('@commerce');
const { I, storefrontPage, cartPage } = inject();
import { expect } from'chai';
Scenario('Search and add product to cart', async () => {
storefrontPage.navigate();
storefrontPage.searchForProduct('shoes');
storefrontPage.clickFirstProduct();
// Example of interactive AI development// pause(); // Uncomment to try: "Add product to cart and verify"
cartPage.addToCart();
cartPage.validateItemAdded();
}).tag('@search').tag('@cart');
export {};
Key Requirements:
Use Feature() and Scenario() structure
Add meaningful tags for filtering
Include export {}; at end
Import page objects via inject()
Import Chai expect for value assertions: import { expect } from 'chai';
Use Chai expect() assertions for validating retrieved values (counts, text, URLs, etc.)
Use CodeceptJS page object methods for UI interactions
Focus on commerce-specific flows
CRITICAL: Never call I.* methods directly inside a Scenario — all I.* usage (I.click, I.amOnPage, I.seeElement, etc.) must live in page objects or flows. Scenarios only call page object / flow methods and Chai assertions.
CRITICAL: Each scenario must be independent — create necessary test data within the scenario, never depend on other scenarios running first or in specific order
CRITICAL: Wrap all test-authored paths in buildSitePath() before passing to I.amOnPage() — import from ../utils/url-utils (or ../../utils/url-utils from specs). Do NOT apply buildSitePath() to URLs extracted from the page DOM (they already contain the url prefix).
5. Generate Page Objects with AI
Use AI-powered page object generation:
import { buildSitePath } from'../../utils/url-utils';
Scenario('Generate product page object', async () => {
I.amOnPage(buildSitePath('/product/sample-product'));
pause();
// In console: I.askForPageObject("productDetail")// AI reads runtime DOM and generates complete page object
}).tag('@page-object-generation');
Multi-site note: All I.amOnPage() calls with test-authored paths must use buildSitePath() to prepend the optional /{siteAlias}/{locale} prefix. See CLAUDE.md "Multi-site URL Prefixing" for details.
Locator Strategy:
Playwright's recommended priority is user-facing attributes first, data-testid last:
getByRole / [role] + accessible name — closest to how users and screen readers perceive the page
getByLabel / associated <label> — preferred for form fields
getByText / .withText() — visible text content
getByPlaceholder, getByAltText, getByTitle — other user-facing attributes
data-testid — last resort; resilient but not user-facing
Rule of thumb: if locate('[role="button"]').withText('Add to Cart') uniquely identifies the element, prefer it. If there are multiple matches, reach for data-testid.
No good locator? Add one. If no semantic attribute or data-testid exists on the element, add data-testid directly to the source component in the template. Don't settle for a brittle CSS class or positional selector — a two-minute source edit produces a stable, self-documenting locator.
// ✅ Add data-testid to the source component
<button data-testid="add-to-cart-button" onClick={handleAddToCart}>
Add to Cart
</button>
// Then reference it in the page objectaddToCartButton: locate('[data-testid="add-to-cart-button"]').as('Add to Cart Button'),
⚠️ Avoid UI-Only Classes:
NEVER use styling classes (Tailwind utilities like text-muted-foreground, text-destructive, bg-*, flex, etc.) as locators — they're non-semantic and match multiple elements.
// ❌ Bad: UI-only classeslocate('p.text-muted-foreground').as('Subtitle')
locate('.text-destructive').as('Error')
// ✅ Better: Add semantic context or use data attributeslocate('[data-slot="card"] p.text-muted-foreground').first().as('Subtitle')
locate('[role="dialog"] .text-destructive').as('Form Error')
locate('[role="alert"]').as('Error Message')
The steps.d.ts file is automatically updated with new page object registrations.
7.5. Update Self-Healing Recipes
REQUIRED: When creating page objects, adding new locators, or modifying existing locator selectors, always update helpers/self-healing/recipes.ts to keep healing recipes in sync.
Purpose: Healing recipes provide fallback selectors for AI self-healing when primary locators break. They help the AI understand context and suggest alternative selectors.
Process:
Extract locators from the new/updated page object
Create a HealingRecipe for each important locator:
exportconstnewLocatorRecipe: HealingRecipe = {
name: 'locatorName', // Match the page object locator namedescription: 'Human-readable description of the element',
selectors: [
'primary-selector', // From page object locators'semantic-selector', // Semantic HTML fallback'[aria-label*="text" i]', // Accessibility fallback'location-based-selector', // Context-aware selector
],
context: 'Where the element appears and its purpose',
fallbackStrategy: 'What to look for if primary selector fails',
};
// ❌ WRONG: Don't use manual throw new Error()if (productCount === 0) {
thrownewError('Expected to see product tiles');
}
// ✅ CORRECT: Use Chai expect insteadexpect(productCount, 'Should have product tiles on homepage').to.be.greaterThan(0);
Scenario('Add multiple products to cart', async () => {
storefrontPage.navigate();
// Add first product
storefrontPage.searchForProduct('shirt');
storefrontPage.clickFirstProduct();
await productPage.selectSize('M');
productPage.addToCart();
// Navigate back and add second product
storefrontPage.goBackToResults();
storefrontPage.clickProductAtIndex(1);
await productPage.selectSize('L');
productPage.addToCart();
// Verify cart
cartPage.goToCart();
const cartCount = await cartPage.getCartCount();
expect(cartCount, 'Cart should contain 2 items').to.equal(2);
}).tag('@cart').tag('@multi-product');
Rule: Scenarios must never call I.* methods directly. All browser interactions belong inside page objects or flows. If you need an action that doesn't exist on a page object, add a method to the appropriate page object rather than calling I.* inline.
10. Interactive Development Examples
Include examples of AI-powered development:
Scenario('Interactive test development demo', async () => {
storefrontPage.navigate();
// Uncomment to try interactive AI features:// pause();// Try these in the pause console:// > "Search for winter jackets and filter by size Large"// > "Add the first product to cart and continue to checkout"// > I.askForPageObject("checkout")
storefrontPage.validatePageLoaded();
}).tag('@interactive').tag('@demo');
pnpm e2e --grep "@search"# Run search tests
pnpm e2e --ai --grep "@search"# Run with AI self-healing
pnpm e2e --grep "(?=.*@cart)(?!.*@mobile)"# Desktop cart tests
12. Update Self-Healing Recipes
CRITICAL: When creating page objects, adding new locators, or modifying existing locator selectors, always update helpers/self-healing/recipes.ts.
For each new or modified locator in page objects:
Create a HealingRecipe with:
name: Matches the locator name from page object
description: Human-readable description
selectors: Array starting with primary selector, then fallbacks (semantic HTML, ARIA, context-based)
context: Where element appears and its purpose
fallbackStrategy: Guidance for AI when all selectors fail
Add recipe to healingRecipes array export
Example:
// Page object: cartIcon: locate('[data-testid*="cart"]').as('Cart Icon')exportconstcartIconRecipe: HealingRecipe = {
name: 'cartIcon',
description: 'Shopping cart icon in header navigation',
selectors: [
'[data-testid*="cart"]', // Primary'a[href*="/cart"]', // Semantic fallback'button[aria-label*="cart" i]', // Accessibility'header [class*="cart"]', // Context-based
],
context: 'Located in header, shows cart item count badge',
fallbackStrategy: 'Look for clickable element in header with cart-related attributes',
};
Reference: See existing recipes in helpers/self-healing/recipes.ts for patterns.
13. Final Checklist
Before completing, verify:
Existing unit tests and Storybook stories audited — E2E tests add integration value beyond component-level coverage
Tests follow Scenario-Mocha structure
Each scenario is independent — can run individually, in any order, or in parallel without depending on other scenarios
No I.* calls in Scenarios — all browser interactions are in page objects or flows
Chai expect() assertions used for value validation (counts, text, URLs)
CodeceptJS page object methods used for UI interactions
All page objects use semantic locators with .as('Name') — prefer user-facing attributes (role, label, text) over data-testid where the element is unambiguous
All I.amOnPage() calls with test-authored paths use buildSitePath() (DOM-extracted URLs excluded)
Page objects registered in src/pages/index.ts (or flows in src/flows/index.ts)
Self-healing recipes updated for all new or modified page object locators
Commerce-specific flows are covered (search, cart, checkout, multi-currency)
Currency assertions use locale-aware patterns (TEST_LOCALE_CURRENCIES.currencyPattern), never hardcoded $
After generating tests, remind the user to run them manually in the terminal to verify the behaviors with their own eyes. This is the key advantage E2E tests have over unit tests — users can watch the actual interactions happen in the browser.
Suggested command to provide:
pnpm e2e --grep "@your-test-tag"
Commerce Test Scenarios
Essential Storefront Tests
Homepage Loading
Page loads successfully
SFCC cookies are set
Product tiles are displayed
Product Search
Search returns relevant results
Filters work correctly
No results handling
Product Detail
Product information displays
Size/color selection works
Add to cart functionality
Shopping Cart
Items are added correctly
Quantity updates work
Remove items functionality
Checkout Flow
Guest checkout works
Form validation
Payment integration (if applicable)
User Account
Registration process
Login/logout
Account management
Advanced Commerce Scenarios
Multi-Product Workflows
Add multiple items to cart
Cross-selling/upselling
Wishlist functionality
Multi-Currency Checkout
Place order in different currencies (USD, GBP, EUR, etc.)
Verify currency symbols in order summary and confirmation
Data-driven tests via TEST_LOCALE_CURRENCIES in checkout.data.ts
Use direct locale-prefixed URLs (/{siteAlias}/{locale}/path) instead of buildSitePath()
Mobile Commerce
Touch interactions
Mobile-specific UI elements
Responsive behavior
Performance Scenarios
Page load times
Search response times
Cart update performance
AI Feature Integration
Interactive Console Usage
// In any test, add pause() to open interactive consolepause();
// Try these commands in the console:// > "Navigate to the product page for running shoes"// > "Add the product to cart and verify the cart count increases"// > "Fill out the checkout form with test customer data"
Page Object Generation
import { buildSitePath } from'../../utils/url-utils';
// Navigate to any page and generate page object
I.amOnPage(buildSitePath('/checkout'));
pause();
// > I.askForPageObject("checkout")// AI analyzes DOM and creates complete page object
Self-Healing Tests
# Enable AI self-healing with --ai flag
pnpm e2e --ai --grep "@your-test"# AI automatically fixes broken locators during test execution
This skill ensures comprehensive storefront E2E test coverage while leveraging CodeceptJS AI capabilities for efficient test development and maintenance.