From 2e50b226673f9dc064d61e1404f9d5b88b3f0771 Mon Sep 17 00:00:00 2001 From: Jason Stirnaman Date: Wed, 7 Jan 2026 12:01:22 -0600 Subject: [PATCH] chore(skills): add Cypress E2E testing skill and update related skills (#6709) - Add new cypress-e2e-testing skill with: - Hugo server management guidance (port 1315, auto-start) - Test execution patterns and quick reference - API reference test prerequisites - Failure analysis and debugging strategies - Error pattern categorization - Update docs-cli-workflow skill with related skills section - Streamline hugo-template-dev skill content --- .claude/skills/cypress-e2e-testing/SKILL.md | 329 ++++++++++++++++++++ .claude/skills/docs-cli-workflow/SKILL.md | 6 + .claude/skills/hugo-template-dev/SKILL.md | 197 +++--------- 3 files changed, 376 insertions(+), 156 deletions(-) create mode 100644 .claude/skills/cypress-e2e-testing/SKILL.md diff --git a/.claude/skills/cypress-e2e-testing/SKILL.md b/.claude/skills/cypress-e2e-testing/SKILL.md new file mode 100644 index 000000000..2d1c734d3 --- /dev/null +++ b/.claude/skills/cypress-e2e-testing/SKILL.md @@ -0,0 +1,329 @@ +--- +name: cypress-e2e-testing +description: Run, validate, and analyze Cypress E2E tests for the InfluxData documentation site. Covers Hugo server management, test execution modes, and failure analysis. +author: InfluxData +version: "1.0" +--- + +# Cypress E2E Testing Skill + +## Purpose + +This skill guides agents through running Cypress end-to-end tests for the documentation site, including understanding when Hugo starts automatically vs. manually, interpreting test results, and debugging failures. + +For comprehensive testing documentation, see **[DOCS-TESTING.md](../../../DOCS-TESTING.md)**. + +## Key Insight: Hugo Server Management + +**The test runner (`run-e2e-specs.js`) automatically manages Hugo.** + +- **Port 1315** is used for testing (not 1313) +- If port 1315 is free → starts Hugo automatically +- If port 1315 is in use → checks if it's a working Hugo server and reuses it +- Hugo logs written to `/tmp/hugo_server.log` + +**You do NOT need to start Hugo separately** unless you want to keep it running between test runs for faster iteration. + +## Quick Reference + +| Task | Command | +| ------------------------------- | ------------------------------------------------------------------------------------------------------- | +| Test content file | `node cypress/support/run-e2e-specs.js content/path/to/file.md` | +| Test with specific spec | `node cypress/support/run-e2e-specs.js --spec "cypress/e2e/content/spec.cy.js" content/path/to/file.md` | +| Functionality test (no content) | `node cypress/support/run-e2e-specs.js --spec "cypress/e2e/page-context.cy.js" --no-mapping` | +| Test shortcode examples | `yarn test:shortcode-examples` | + +## Prerequisites + +```bash +# Install dependencies (required) +yarn install + +# Verify Cypress is available +yarn cypress --version +``` + +### API Reference Tests: Additional Prerequisites + +**API reference pages require generation before testing.** The pages don't exist until you run: + +```bash +# Generate API documentation content from OpenAPI specs +yarn build:api-docs +``` + +This step: + +- Processes OpenAPI specs in `api-docs/` directories +- Generates Hugo content pages in `content/*/api/` +- Creates operation pages, tag pages, and index pages + +**Without this step**, all API reference tests will fail with 404 errors. + +**Quick check** - verify API content exists: + +```bash +# Should list generated API content directories +ls content/influxdb3/core/api/ + +# If "No such file or directory", run: yarn build:api-docs +``` + +### Markdown Validation Tests: Additional Prerequisites + +**Markdown validation tests require generated markdown files.** Run: + +```bash +# Build Hugo site first (generates HTML in public/) +npx hugo --quiet + +# Generate LLM-friendly markdown from HTML +yarn build:md +``` + +This creates `.md` files in the `public/` directory that the markdown validation tests check. + +**Without this step**, markdown validation tests will fail with missing file errors. + +## Test Execution Modes + +### Mode 1: Content-Specific Tests (Default) + +Tests specific content files by mapping them to URLs. + +```bash +# Single file +node cypress/support/run-e2e-specs.js content/influxdb3/core/_index.md + +# Multiple files +node cypress/support/run-e2e-specs.js content/influxdb3/core/_index.md content/influxdb3/enterprise/_index.md + +# With specific test spec +node cypress/support/run-e2e-specs.js \ + --spec "cypress/e2e/content/api-reference.cy.js" \ + content/influxdb3/core/reference/api/_index.md +``` + +**What happens:** + +1. Maps content files to URLs (e.g., `content/influxdb3/core/_index.md` → `/influxdb3/core/`) +2. Starts Hugo on port 1315 (if not running) +3. Runs Cypress tests against mapped URLs +4. Stops Hugo when done + +### Mode 2: Functionality Tests (`--no-mapping`) + +Tests UI functionality without requiring content file paths. + +```bash +# Run functionality test +node cypress/support/run-e2e-specs.js \ + --spec "cypress/e2e/page-context.cy.js" \ + --no-mapping +``` + +**Use when:** Testing JavaScript components, theme switching, navigation, or other UI behavior not tied to specific content. + +### Mode 3: Reusing an Existing Hugo Server + +For faster iteration during development: + +```bash +# Terminal 1: Start Hugo manually on port 1315 +npx hugo server --port 1315 --environment testing --noHTTPCache + +# Terminal 2: Run tests (will detect and reuse existing server) +node cypress/support/run-e2e-specs.js \ + --spec "cypress/e2e/content/api-reference.cy.js" \ + content/influxdb3/core/reference/api/_index.md +``` + +## Available Test Specs + +| Spec File | Purpose | +| ------------------------------------------------------- | --------------------------------------------- | +| `cypress/e2e/content/api-reference.cy.js` | API reference pages (RapiDoc, layouts, links) | +| `cypress/e2e/content/index.cy.js` | General content validation | +| `cypress/e2e/content/markdown-content-validation.cy.js` | LLM markdown generation | +| `cypress/e2e/page-context.cy.js` | Page context and navigation | + +## Understanding Test Output + +### Success Output + +``` +✅ e2e tests completed successfully +📊 Detailed Test Results: + â€ĸ Total Tests: 25 + â€ĸ Tests Passed: 25 + â€ĸ Tests Failed: 0 +``` + +### Failure Output + +``` +â„šī¸ Note: 3 test(s) failed. +📊 Detailed Test Results: + â€ĸ Total Tests: 25 + â€ĸ Tests Passed: 22 + â€ĸ Tests Failed: 3 + +📋 Failed Spec Files: + â€ĸ cypress/e2e/content/api-reference.cy.js + - Failures: 3 + - Failed Tests: + * has API info + Error: Expected to find element '.article--description' +``` + +### Common Failure Patterns + +| Error | Likely Cause | Solution | +| ----------------------------------- | ----------------------------------- | -------------------------------- | +| All API tests fail with 404 | API content not generated | Run `yarn build:api-docs` first | +| `Expected to find element 'X'` | Selector changed or element removed | Update test or fix template | +| `Timed out waiting for element` | Page load issue or JS error | Check Hugo logs, browser console | +| `cy.request() failed` | Broken link or 404 | Fix the link in content | +| `Hugo server died during execution` | Build error or memory issue | Check `/tmp/hugo_server.log` | + +## Debugging Failures + +### Step 1: Check Hugo Logs + +```bash +cat /tmp/hugo_server.log | tail -50 +``` + +Look for: + +- Template errors (`error calling partial`) +- Build failures +- Missing data files + +### Step 2: Run Test in Interactive Mode + +```bash +# Start Hugo manually +npx hugo server --port 1315 --environment testing + +# In another terminal, open Cypress interactively +yarn cypress open +``` + +### Step 3: Inspect the Page + +Visit `http://localhost:1315/path/to/page/` in a browser and: + +- Open DevTools Console for JavaScript errors +- Inspect elements to verify selectors +- Check Network tab for failed requests + +### Step 4: Run Single Test with Verbose Output + +```bash +DEBUG=cypress:* node cypress/support/run-e2e-specs.js \ + --spec "cypress/e2e/content/api-reference.cy.js" \ + content/influxdb3/core/reference/api/_index.md +``` + +## Test Configuration + +The test runner uses these settings: + +```javascript +{ + browser: 'chrome', + baseUrl: 'http://localhost:1315', + video: false, // Disabled in CI + defaultCommandTimeout: 10000, // 15000 in CI + pageLoadTimeout: 30000, // 45000 in CI +} +``` + +## Writing New Tests + +### Basic Test Structure + +```javascript +describe('Feature Name', () => { + beforeEach(() => { + cy.visit('/path/to/page/'); + }); + + it('validates expected behavior', () => { + cy.get('.selector').should('exist'); + cy.get('.selector').should('be.visible'); + cy.get('.selector').contains('Expected text'); + }); +}); +``` + +### Testing Components + +```javascript +describe('Component Name', () => { + it('initializes correctly', () => { + cy.visit('/path/with/component/'); + + // Wait for component initialization + cy.get('[data-component="my-component"]', { timeout: 5000 }) + .should('be.visible'); + + // Verify component rendered expected elements + cy.get('[data-component="my-component"] .child-element') + .should('have.length.at.least', 1); + }); +}); +``` + +### Testing Links + +```javascript +it('contains valid internal links', () => { + cy.get('body').then(($body) => { + if ($body.find('a[href^="/"]').length === 0) { + cy.log('No internal links found'); + return; + } + + cy.get('a[href^="/"]').each(($a) => { + cy.request($a.attr('href')).its('status').should('eq', 200); + }); + }); +}); +``` + +## CI/CD Considerations + +In CI environments: + +- Video recording is disabled to save resources +- Timeouts are increased (15s command, 45s page load) +- Memory management is enabled +- Only 1 test kept in memory at a time + +## Related Files + +- **Test runner**: `cypress/support/run-e2e-specs.js` +- **Hugo server helper**: `cypress/support/hugo-server.js` +- **URL mapper**: `cypress/support/map-files-to-urls.js` +- **Config**: `cypress.config.js` +- **Comprehensive docs**: `DOCS-TESTING.md` + +## Checklist for Test Validation + +Before concluding test analysis: + +- [ ] For API tests: Verify `yarn build:api-docs` was run (check `ls content/*/api/`) +- [ ] All tests passed, or failures are understood +- [ ] Hugo logs checked for build errors +- [ ] Failed selectors verified against current templates +- [ ] Broken links identified and reported +- [ ] JavaScript console errors investigated (if relevant) + +## Related Skills + +- **hugo-template-dev** - For Hugo template syntax, data access patterns, and runtime testing +- **docs-cli-workflow** - For creating/editing documentation content with CLI tools +- **ts-component-dev** (agent) - TypeScript component behavior and interactivity +- **hugo-ui-dev** (agent) - Hugo templates and SASS/CSS styling diff --git a/.claude/skills/docs-cli-workflow/SKILL.md b/.claude/skills/docs-cli-workflow/SKILL.md index a5d6e9866..37b0d77fb 100644 --- a/.claude/skills/docs-cli-workflow/SKILL.md +++ b/.claude/skills/docs-cli-workflow/SKILL.md @@ -131,3 +131,9 @@ npx docs edit --list # List files without opening ``` For full CLI documentation, run `npx docs --help`. + +## Related Skills + +- **hugo-template-dev** - For Hugo template syntax, data access patterns, and runtime testing +- **cypress-e2e-testing** - For running and debugging Cypress E2E tests +- **ts-component-dev** (agent) - TypeScript component behavior and interactivity diff --git a/.claude/skills/hugo-template-dev/SKILL.md b/.claude/skills/hugo-template-dev/SKILL.md index 7139074f0..2c2d7336a 100644 --- a/.claude/skills/hugo-template-dev/SKILL.md +++ b/.claude/skills/hugo-template-dev/SKILL.md @@ -2,7 +2,7 @@ name: hugo-template-dev description: Hugo template development skill for InfluxData docs-v2. Enforces proper build and runtime testing to catch template errors that build-only validation misses. author: InfluxData -version: "1.0" +version: "1.1" --- # Hugo Template Development Skill @@ -23,9 +23,10 @@ Template errors like accessing undefined fields, nil values, or incorrect type a After modifying files in `layouts/`, `layouts/partials/`, or `layouts/shortcodes/`: +**Step 1: Start Hugo server and capture output** + ```bash -# Step 1: Start Hugo server and capture output -npx hugo server --port 1314 2>&1 | head -50 +npx hugo server --port 1315 2>&1 | head -50 ``` **Success criteria:** @@ -33,20 +34,37 @@ npx hugo server --port 1314 2>&1 | head -50 - No `error calling partial` messages - No `can't evaluate field` errors - No `template: ... failed` messages -- Server shows "Web Server is available at " +- Server shows "Web Server is available at " **If errors appear:** Fix the template and repeat Step 1 before proceeding. +**Step 2: Verify the page renders** + ```bash -# Step 2: Verify the page renders (only after Step 1 passes) -curl -s -o /dev/null -w "%{http_code}" http://localhost:1314/PATH/TO/PAGE/ +curl -s -o /dev/null -w "%{http_code}" http://localhost:1315/PATH/TO/PAGE/ ``` **Expected:** HTTP 200 status code +**Step 3: Browser testing (if MCP browser tools available)** + +If `mcp__claude-in-chrome__*` tools are available, use them for visual inspection: + +``` +# Navigate and screenshot +mcp__claude-in-chrome__navigate({ url: "http://localhost:1315/PATH/", tabId: ... }) +mcp__claude-in-chrome__computer({ action: "screenshot", tabId: ... }) + +# Check for JavaScript errors +mcp__claude-in-chrome__read_console_messages({ tabId: ..., onlyErrors: true }) +``` + +This catches runtime JavaScript errors that template changes may introduce. + +**Step 4: Stop the test server** + ```bash -# Step 3: Stop the test server -pkill -f "hugo server --port 1314" +pkill -f "hugo server --port 1315" ``` ### Quick Test Command @@ -54,7 +72,7 @@ pkill -f "hugo server --port 1314" Use this one-liner to test and get immediate feedback: ```bash -timeout 15 npx hugo server --port 1314 2>&1 | grep -E "(error|Error|ERROR|fail|FAIL)" | head -20; pkill -f "hugo server --port 1314" 2>/dev/null +timeout 15 npx hugo server --port 1315 2>&1 | grep -E "(error|Error|ERROR|fail|FAIL)" | head -20; pkill -f "hugo server --port 1315" 2>/dev/null ``` If output is empty, no errors were detected. @@ -335,24 +353,6 @@ The **only** acceptable inline scripts are minimal initialization that MUST run Everything else belongs in `assets/js/`. -### File Organization for Components - -``` -assets/ -├── js/ -│ ├── main.js # Entry point, component registry -│ ├── components/ -│ │ ├── api-nav.ts # API navigation behavior -│ │ ├── api-toc.ts # Table of contents -│ │ ├── api-tabs.ts # Tab switching (if needed beyond CSS) -│ │ └── api-scalar.ts # Scalar/RapiDoc integration -│ └── utils/ -│ └── dom-helpers.ts # Shared DOM utilities -└── styles/ - └── layouts/ - └── _api-layout.scss # API-specific styles -``` - ### TypeScript Component Checklist When creating a new interactive feature: @@ -363,15 +363,14 @@ When creating a new interactive feature: 4. [ ] Register in `main.js` componentRegistry 5. [ ] Add `data-component` attribute to HTML element 6. [ ] Pass data via `data-*` attributes (not inline JS) -7. [ ] Write Cypress tests for the component -8. [ ] **NO inline `