
seo-llm-optimizer-tests
by mikkelkrogsholm
SKILL.md
name: seo-llm-optimizer-tests description: Test specifications for SEO & LLM Optimizer WordPress plugin. Use when testing the SEO & LLM Optimizer plugin, verifying Copy for AI functionality, or checking markdown/RAG export features.
SEO & LLM Optimizer - Test Specification
This Skill defines comprehensive test procedures for the SEO & LLM Optimizer WordPress plugin.
Plugin Overview
Plugin Name: SEO & LLM Optimizer Plugin Slug: seo-llm-optimizer Version: 1.0.0 Purpose: Convert WordPress content to AI-friendly formats (Markdown, RAG-ready chunks)
Key Features:
- Frontend "Copy for AI" button on posts/pages
- 3 chunking strategies (hierarchical, fixed-size, semantic)
- REST API with 8 endpoints
- Multiple export formats (Universal, LangChain, LlamaIndex)
- Rate limiting and caching
- Settings page for configuration
Test Environment Setup
Required Content: Create at least one published post for frontend testing:
cd /Users/mikkelfreltoftkrogsholm/Projekter/wp-plugins && ./test.sh wp post create \
--post_title="AI-Optimized Test Post" \
--post_content="<h2>Introduction</h2><p>This is a test post for the SEO & LLM Optimizer plugin. It contains multiple paragraphs and headings for proper chunk testing.</p><h2>Main Content</h2><p>The plugin should convert this content to markdown format and create chunks based on the selected strategy.</p><h3>Subheading</h3><p>This paragraph tests hierarchical chunking.</p>" \
--post_status=publish
Plugin Activation:
cd /Users/mikkelfreltoftkrogsholm/Projekter/wp-plugins && ./test.sh activate seo-llm-optimizer
Test Suite
1. Plugin Activation Verification
Objective: Verify plugin activates without errors
Steps:
- Check plugin status:
./test.sh plugins - Verify "seo-llm-optimizer" shows as "active"
- Check WordPress debug log for PHP errors:
./test.sh debug - Verify no fatal errors or warnings
Expected Result:
- Plugin status shows "active"
- No PHP errors in debug log
- WordPress admin accessible
Category: Installation
2. Admin Menu Presence
Objective: Verify plugin adds admin menu item
Steps:
- Login to WordPress admin
- Take snapshot of admin sidebar
- Look for "SEO & LLM Optimizer" menu item
- Click menu item
- Verify settings page loads
Expected Result:
- Menu item "SEO & LLM Optimizer" appears in admin sidebar
- Clicking menu navigates to plugin settings page
- URL matches pattern:
/wp-admin/admin.php?page=seo-llm-optimizer
Category: UI - Admin
3. Settings Page Rendering
Objective: Verify settings page renders correctly
Steps:
- Navigate to plugin settings:
/wp-admin/admin.php?page=seo-llm-optimizer - Take snapshot of settings page
- Take screenshot for documentation
- Verify presence of settings sections:
- Chunking Strategy
- Export Format
- Rate Limiting
- Caching
- Check console for JavaScript errors
- Verify submit button present
Expected Result:
- Settings page loads without errors
- All settings sections visible
- Form fields render correctly
- No JavaScript console errors
- Save button present with proper styling
Category: UI - Admin
4. Settings Save Functionality
Objective: Verify settings can be saved
Steps:
- Navigate to settings page
- Change chunking strategy (select different option)
- Change export format (select different option)
- Click "Save Settings" button
- Wait for success message
- Reload page
- Verify settings persisted
Expected Result:
- Save button triggers form submission
- Success message appears
- Settings persist after page reload
- No console errors during save
Category: Functionality - Admin
5. Frontend "Copy for AI" Button - Presence
Objective: Verify button appears on published posts
Steps:
- Navigate to published post URL (get from test content creation)
- Take snapshot of post page
- Scroll through page content
- Look for "Copy for AI" button
- Take screenshot showing button location
- Verify button styling matches theme
Expected Result:
- "Copy for AI" button visible on post page
- Button has appropriate styling (not broken CSS)
- Button appears in logical location (below content or in sidebar)
Element Identifiers to Look For:
- Button text: "Copy for AI" or "Copy Markdown" or similar
- Possible IDs:
copy-for-ai-button,seo-llm-copy-button - Possible classes:
copy-ai-btn,seo-llm-button
Category: UI - Frontend
6. Frontend "Copy for AI" Button - Click Interaction
Objective: Verify button click triggers expected behavior
Steps:
- Navigate to published post
- Locate "Copy for AI" button
- Click button
- Check for modal/dialog appearing
- OR check for clipboard action (success message)
- Verify expected UI response
Expected Result:
- Button click triggers action (no 404 or console error)
- Modal appears with markdown content, OR
- Clipboard copy success message appears, OR
- Download of markdown file initiates
- No JavaScript errors in console
Category: Functionality - Frontend
7. JavaScript Asset Loading
Objective: Verify plugin JavaScript loads correctly
Steps:
- Navigate to published post
- Open network requests:
list_network_requests(resourceTypes: ["script"]) - Look for plugin JavaScript files
- Verify all plugin JS files return 200 status
- Check console for any script errors
Expected Plugin Assets:
- May include:
copy-for-ai.js,seo-llm-optimizer.js, or similar - Should load from
/wp-content/plugins/seo-llm-optimizer/assets/js/
Expected Result:
- All plugin JavaScript files load successfully (200)
- No 404 errors for plugin assets
- No console errors related to missing scripts
Category: Assets - Frontend
8. CSS Asset Loading
Objective: Verify plugin styles load correctly
Steps:
- Navigate to published post
- Open network requests:
list_network_requests(resourceTypes: ["stylesheet"]) - Look for plugin CSS files
- Verify all plugin CSS files return 200 status
- Inspect button styling to confirm CSS applied
Expected Plugin Assets:
- May include:
copy-for-ai.css,seo-llm-optimizer.css, or similar - Should load from
/wp-content/plugins/seo-llm-optimizer/assets/css/
Expected Result:
- All plugin CSS files load successfully (200)
- Button has proper styling (not default browser button)
- No broken/missing styles
Category: Assets - Frontend
9. REST API - Endpoint Availability
Objective: Verify REST API endpoints are registered
Steps:
- Use evaluate_script to discover endpoints:
async () => {
const response = await fetch('/wp-json/');
const data = await response.json();
return data.routes;
}
- Look for plugin namespace:
/seo-llm/v1 - Verify expected endpoints present
Expected Endpoints:
/wp-json/seo-llm/v1/content/{id}/markdown/wp-json/seo-llm/v1/content/{id}/chunks/wp-json/seo-llm/v1/content/{id}/export- Additional endpoints as documented
Expected Result:
- Plugin namespace
/seo-llm/v1present in API routes - All documented endpoints registered
- Endpoints return proper route definitions
Category: API
10. REST API - Get Markdown Endpoint
Objective: Verify markdown conversion endpoint works
Steps:
- Get ID of test post (from post creation or use 1)
- Use evaluate_script to call endpoint:
async () => {
const response = await fetch('/wp-json/seo-llm/v1/content/1/markdown');
const data = await response.json();
return {
status: response.status,
ok: response.ok,
contentType: response.headers.get('content-type'),
data: data
};
}
- Verify response structure
Expected Result:
- Response status: 200
- Content-Type: application/json
- Response contains markdown content
- Markdown includes post title and content
- HTML properly converted to markdown (headings, paragraphs)
Category: API
11. REST API - Get Chunks Endpoint
Objective: Verify content chunking endpoint works
Steps:
- Use evaluate_script to call chunks endpoint:
async () => {
const response = await fetch('/wp-json/seo-llm/v1/content/1/chunks');
const data = await response.json();
return {
status: response.status,
chunks: data.chunks ? data.chunks.length : 0,
data: data
};
}
- Verify response contains chunks array
Expected Result:
- Response status: 200
- Response contains
chunksarray - Each chunk has expected properties (text, metadata)
- Number of chunks > 0 for test content
Category: API
12. REST API - Error Handling (Invalid Post ID)
Objective: Verify API returns proper errors for invalid requests
Steps:
- Use evaluate_script to call endpoint with invalid ID:
async () => {
const response = await fetch('/wp-json/seo-llm/v1/content/99999/markdown');
const data = await response.json();
return {
status: response.status,
data: data
};
}
Expected Result:
- Response status: 404 (Not Found)
- Response contains error message
- Error message is meaningful (not generic PHP error)
Category: API - Error Handling
13. REST API - Rate Limiting
Objective: Verify rate limiting protects API
Steps:
- Use evaluate_script to make multiple rapid requests:
async () => {
const results = [];
for (let i = 0; i < 20; i++) {
const response = await fetch('/wp-json/seo-llm/v1/content/1/markdown');
results.push({
attempt: i + 1,
status: response.status
});
}
return results;
}
- Check if rate limiting kicks in
Expected Result:
- First several requests succeed (200)
- After threshold, requests return 429 (Too Many Requests)
- OR all requests succeed if rate limit is high for testing
Note: Rate limit behavior depends on plugin configuration
Category: API - Security
14. Settings - Chunking Strategy Options
Objective: Verify different chunking strategies work
Steps:
- Navigate to settings page
- Verify chunking strategy options present:
- Hierarchical (based on headings)
- Fixed-size (by character count)
- Semantic (by content meaning)
- Select each strategy and save
- Call chunks API endpoint
- Verify chunks differ based on strategy
Expected Result:
- All three strategies available in settings
- Strategy selection saves correctly
- API chunks endpoint respects selected strategy
- Different strategies produce different chunk boundaries
Category: Functionality - Settings
15. Settings - Export Format Options
Objective: Verify export format options work
Steps:
- Navigate to settings page
- Verify export format options present:
- Universal (generic JSON)
- LangChain (LangChain format)
- LlamaIndex (LlamaIndex format)
- Select each format and save
- Call export endpoint
- Verify format matches selection
Expected Result:
- All export formats available in settings
- Format selection saves correctly
- Export endpoint returns data in selected format
- Different formats have distinct structures
Category: Functionality - Settings
16. Console Error Sweep
Objective: Comprehensive check for JavaScript errors
Steps:
- Navigate to admin settings page
- Check console:
list_console_messages(types: ["error"]) - Navigate to frontend post page
- Check console:
list_console_messages(types: ["error"]) - Click "Copy for AI" button
- Check console again
- Document any errors found
Expected Result:
- Zero JavaScript errors on admin page
- Zero JavaScript errors on frontend page
- Zero JavaScript errors after button interaction
- Any errors are documented with context
Category: Quality Assurance
17. Network Performance Check
Objective: Verify reasonable network performance
Steps:
- Navigate to frontend post page
- List all network requests:
list_network_requests() - Count total requests
- Check for slow requests (over 1 second)
- Verify no duplicate requests
Expected Result:
- Reasonable request count (under 50 for simple page)
- Plugin assets load quickly (under 500ms)
- No duplicate/redundant requests
- No excessive API calls
Category: Performance
18. Mobile Responsiveness (Optional)
Objective: Verify button works on mobile viewport
Steps:
- Resize page to mobile:
resize_page(width: 375, height: 667) - Navigate to post page
- Take screenshot
- Verify button visible and usable
- Test button click on mobile size
Expected Result:
- Button visible on mobile viewport
- Button tap target is adequate (not too small)
- Button functionality works on mobile
Category: UI - Responsive
19. Accessibility - Keyboard Navigation
Objective: Verify button is keyboard accessible
Steps:
- Navigate to post page
- Use press_key to tab to button:
press_key(key: "Tab") - Verify button receives focus
- Press Enter to activate:
press_key(key: "Enter") - Verify button action triggers
Expected Result:
- Button is reachable via keyboard navigation
- Button shows focus indicator
- Enter key activates button
- Functionality works without mouse
Category: Accessibility
20. Security - Nonce Verification (Settings Form)
Objective: Verify settings form uses security nonces
Steps:
- Navigate to settings page
- Take snapshot with verbose mode:
take_snapshot(verbose: true) - Look for hidden input fields with name containing "nonce" or "_wpnonce"
- Verify nonce field present
Expected Result:
- Settings form contains WordPress nonce field
- Nonce field name ends with "_wpnonce" or similar
- Nonce value is non-empty random string
Category: Security
Test Execution Order
Recommended test sequence:
-
Setup Phase:
- Plugin Activation Verification (Test 1)
- Create test content
-
Admin Interface Phase:
- Admin Menu Presence (Test 2)
- Settings Page Rendering (Test 3)
- Settings Save Functionality (Test 4)
- Settings - Chunking Strategy Options (Test 14)
- Settings - Export Format Options (Test 15)
-
Frontend Interface Phase:
- Frontend "Copy for AI" Button - Presence (Test 5)
- JavaScript Asset Loading (Test 7)
- CSS Asset Loading (Test 8)
- Frontend "Copy for AI" Button - Click Interaction (Test 6)
-
API Testing Phase:
- REST API - Endpoint Availability (Test 9)
- REST API - Get Markdown Endpoint (Test 10)
- REST API - Get Chunks Endpoint (Test 11)
- REST API - Error Handling (Test 12)
- REST API - Rate Limiting (Test 13)
-
Quality Assurance Phase:
- Console Error Sweep (Test 16)
- Network Performance Check (Test 17)
- Mobile Responsiveness (Test 18)
- Accessibility - Keyboard Navigation (Test 19)
- Security - Nonce Verification (Test 20)
Common Issues and Debugging
Issue: "Copy for AI" Button Not Visible
Possible Causes:
- JavaScript not enqueued on frontend
- CSS not loaded
- Button only shows for logged-in users
- Button only shows on certain post types
Debugging Steps:
- Check network tab for JS/CSS 404s
- Check console for JavaScript errors
- Try logging in before viewing post
- Check if post type is 'post' (not 'page')
- Inspect DOM source to see if button element exists but hidden
Issue: REST API Endpoints Return 404
Possible Causes:
- Permalinks not flushed after plugin activation
- REST API route registration failed
- Namespace mismatch
Debugging Steps:
- Flush permalinks:
./test.sh wp rewrite flush - Check if any REST endpoints work:
/wp-json/ - Check plugin code for REST route registration
- Check debug.log for PHP errors during init
Issue: Button Click Does Nothing
Possible Causes:
- JavaScript event handler not attached
- JavaScript error preventing execution
- Missing dependency (jQuery, etc.)
Debugging Steps:
- Check console for errors after click
- Verify JavaScript loaded successfully
- Use evaluate_script to test if event handler exists
- Check if button has onclick attribute or event listener
Issue: Chunks API Returns Empty Array
Possible Causes:
- Post content is too short
- Chunking strategy issue
- Content parsing failed
Debugging Steps:
- Verify post has substantial content
- Try different chunking strategies
- Check if markdown endpoint works (test text extraction)
- Check debug.log for PHP warnings during chunking
Success Criteria
Minimum passing requirements:
- Plugin activates without errors (Test 1)
- Admin menu appears (Test 2)
- Settings page loads (Test 3)
- Frontend button appears (Test 5)
- At least one REST API endpoint works (Tests 9-10)
- No critical JavaScript errors (Test 16)
Full pass requirements:
- All 20 tests pass
- Zero JavaScript errors
- All API endpoints functional
- Security measures in place (nonces, rate limiting)
- Acceptable performance metrics
Test Report Template
When reporting results, include:
- Total tests executed
- Pass/fail counts
- Screenshots of failures
- Console errors (if any)
- Network issues (if any)
- Recommendations for fixes
- Next steps
See wp-plugin-tester agent's JSON output format for structured reporting.
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon