Feature Testing Guide¶
Vectra QA includes 6 specialized feature testing modules that can be used directly via MCP tools or spawned as dedicated agents.
Authentication Testing (test_auth_flow)¶
Test login/logout flows with security validation.
Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
login_url |
string | ✅ | URL of the login page |
username |
string | ❌ | Username for login test |
password |
string | ❌ | Password for login test |
logout_url |
string | ❌ | URL of the logout page |
Security Checks¶
- HTTPS Enforcement: Flags login pages served over HTTP
- Password Field Detection: Verifies password inputs use
type="password" - Autocomplete Prevention: Checks for
autocomplete="current-password" - Session Cookie Security: Validates
HttpOnly,Secure,SameSiteattributes - Token Storage: Detects authentication tokens in
localStorage
Example¶
from mcp_server.tools import execute_tool
result = execute_tool("test_auth_flow", {
"login_url": "https://example.com/login",
"username": "test@example.com",
"password": "password123",
"logout_url": "https://example.com/logout"
})
print(f"Status: {result['status']}")
print(f"Findings: {len(result['findings'])}")
for finding in result['findings']:
print(f" [{finding['severity']}] {finding['title']}: {finding['description']}")
Agent Usage¶
result = execute_tool("spawn_agent", {
"role": "auth_tester",
"objective": "Test login flow at https://example.com/login with username 'test@example.com' and password 'password123'",
"memory_node": "Runs/Auth_Test.md"
})
Visual Regression Testing (test_visual_regression)¶
Compare current page screenshots against baselines.
Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | ✅ | URL to capture and compare |
name |
string | ❌ | Name for baseline identification |
How It Works¶
- First Run: Captures baseline screenshot and saves to
obsidian_vault/Baselines/ - Subsequent Runs: Compares current screenshot against baseline
- Pixel Difference: Calculates percentage of changed pixels
- Threshold: Fails if difference exceeds configurable threshold
Example¶
result = execute_tool("test_visual_regression", {
"url": "https://example.com",
"name": "homepage"
})
if result["status"] == "pass":
print("✅ No visual changes detected")
elif result["status"] == "warning":
print(f"⚠️ Visual difference: {result['metrics']['pixel_difference_percent']:.2f}%")
else:
print(f"❌ Baseline not found - created new baseline")
Agent Usage¶
result = execute_tool("spawn_agent", {
"role": "visual_regression_tester",
"objective": "Compare https://example.com against baseline 'homepage'",
"memory_node": "Runs/Visual_Test.md"
})
Performance Testing (test_performance)¶
Measure Core Web Vitals and page performance metrics.
Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | ✅ | URL to test |
thresholds |
object | ❌ | Custom thresholds (see below) |
Default Thresholds (Core Web Vitals)¶
| Metric | Threshold | Description |
|---|---|---|
lcp_ms |
2500ms | Largest Contentful Paint |
fid_ms |
100ms | First Input Delay |
cls |
0.1 | Cumulative Layout Shift |
ttfb_ms |
600ms | Time to First Byte |
fcp_ms |
1800ms | First Contentful Paint |
tbt_ms |
200ms | Total Blocking Time |
Metrics Collected¶
- Navigation Timing:
responseStart,requestStart,domComplete - Paint Metrics: First Contentful Paint (FCP), Largest Contentful Paint (LCP)
- Layout Stability: Cumulative Layout Shift (CLS)
- Resource Loading: Total transfer size, resource count
- Page Size: Flag if total size exceeds 5MB
Example¶
result = execute_tool("test_performance", {
"url": "https://example.com",
"thresholds": {
"lcp_ms": 2000, # Stricter LCP
"ttfb_ms": 400 # Stricter TTFB
}
})
print(f"TTFB: {result['metrics']['ttfb_ms']}ms")
print(f"FCP: {result['metrics']['fcp_ms']}ms")
print(f"Total Size: {result['metrics']['total_transfer_size_bytes'] / 1024:.1f}KB")
if result['status'] == 'pass':
print("✅ All metrics within thresholds")
else:
for finding in result['findings']:
print(f"❌ {finding['title']}: {finding['description']}")
Lighthouse CI Integration¶
If lighthouse is installed globally, performance tests automatically include Lighthouse scores:
Agent Usage¶
result = execute_tool("spawn_agent", {
"role": "performance_tester",
"objective": "Test performance of https://example.com with strict thresholds: lcp_ms=2000, ttfb_ms=400",
"memory_node": "Runs/Performance_Test.md"
})
API Contract Testing (test_api_contract)¶
Validate API responses against OpenAPI schemas.
Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
base_url |
string | ✅ | Base URL of the API |
endpoint |
string | ✅ | API endpoint path (e.g., /api/v1/users) |
method |
string | ✅ | HTTP method (GET, POST, PUT, DELETE, PATCH) |
schema_path |
string | ❌ | Path to OpenAPI schema file |
body |
object | ❌ | Request body for POST/PUT |
Validation Checks¶
- Status Code: Validates HTTP status matches schema
- Content-Type: Checks
application/jsonheader - Response Body: Validates JSON structure against schema
- Required Fields: Ensures all required fields present
- Type Checking: Validates field types (string, integer, boolean, etc.)
Example¶
result = execute_tool("test_api_contract", {
"base_url": "https://api.example.com",
"endpoint": "/api/v1/users",
"method": "GET",
"schema_path": "./openapi.json"
})
print(f"Status: {result['status']}")
print(f"HTTP Status: {result['metrics']['http_status']}")
if result['status'] == 'pass':
print("✅ API contract validated")
else:
for finding in result['findings']:
print(f"❌ {finding['title']}: {finding['description']}")
Agent Usage¶
result = execute_tool("spawn_agent", {
"role": "api_contract_tester",
"objective": "Validate GET /api/v1/users against schema at ./openapi.json",
"memory_node": "Runs/API_Test.md"
})
Accessibility Testing (test_accessibility)¶
Run accessibility checks using axe-core with manual fallback.
Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | ✅ | URL to test |
standard |
string | ❌ | WCAG standard: wcag2a, wcag2aa (default), wcag21aa |
Checks Performed¶
Automated (axe-core)¶
- Color contrast ratios
- ARIA usage and validity
- Form label associations
- Focus management
- Heading hierarchy
Manual Fallback¶
- Images without
alttext - Form inputs without labels
- Missing
langattribute - Missing
<h1>heading
Example¶
result = execute_tool("test_accessibility", {
"url": "https://example.com",
"standard": "wcag2aa"
})
print(f"Status: {result['status']}")
print(f"Findings: {len(result['findings'])}")
for finding in result['findings']:
severity = finding['severity']
icon = "🔴" if severity == "critical" else "🟠" if severity == "high" else "🟡"
print(f"{icon} [{severity.upper()}] {finding['title']}")
print(f" {finding['description']}")
Agent Usage¶
result = execute_tool("spawn_agent", {
"role": "accessibility_tester",
"objective": "Test accessibility of https://example.com against WCAG 2.1 AA",
"memory_node": "Runs/Accessibility_Test.md"
})
Multi-Browser Testing (test_multi_browser)¶
Run smoke tests across Chromium, Firefox, and WebKit.
Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | ✅ | URL to test |
How It Works¶
- Launches each browser (Chromium, Firefox, WebKit)
- Navigates to the URL
- Verifies page loads successfully
- Collects basic metrics (HTTP status, load time)
- Closes browser and reports results
Results Format¶
{
"chromium": {
"status": "pass",
"metrics": {"http_status": 200},
"findings": []
},
"firefox": {
"status": "pass",
"metrics": {"http_status": 200},
"findings": []
},
"webkit": {
"status": "pass",
"metrics": {"http_status": 200},
"findings": []
}
}
Example¶
result = execute_tool("test_multi_browser", {
"url": "https://example.com"
})
for browser, data in result.items():
status_icon = "✅" if data["status"] == "pass" else "❌"
print(f"{status_icon} {browser.title()}: {data['status']}")
Agent Usage¶
result = execute_tool("spawn_agent", {
"role": "multi_browser_tester",
"objective": "Test https://example.com across all supported browsers",
"memory_node": "Runs/Multi_Browser_Test.md"
})
Complete Test Suite Example¶
Run all feature tests in sequence:
from mcp_server.tools import execute_tool
url = "https://example.com"
# 1. Auth Test
auth_result = execute_tool("test_auth_flow", {
"login_url": f"{url}/login",
"username": "test@example.com",
"password": "password123"
})
# 2. Performance Test
perf_result = execute_tool("test_performance", {
"url": url,
"thresholds": {"lcp_ms": 2500, "ttfb_ms": 600}
})
# 3. Accessibility Test
a11y_result = execute_tool("test_accessibility", {
"url": url,
"standard": "wcag2aa"
})
# 4. Visual Regression
visual_result = execute_tool("test_visual_regression", {
"url": url,
"name": "homepage"
})
# 5. Multi-Browser
browser_result = execute_tool("test_multi_browser", {
"url": url
})
# Compile results
results = {
"auth": auth_result,
"performance": perf_result,
"accessibility": a11y_result,
"visual": visual_result,
"browsers": browser_result
}
# Save to vault
from mcp_server.tools import get_vault
vault = get_vault()
vault.write_node(
"Runs/Full_Test_Suite.md",
content=f"# Full Test Suite Results\n\n```json\n{json.dumps(results, indent=2)}\n```",
frontmatter={"status": "completed", "url": url}
)
Environment Variables¶
Configure feature testers via environment variables:
# Browser settings
HEADLESS=true # Run browsers headless
# Performance thresholds (override defaults)
PERFORMANCE_LCP_MS=2500
PERFORMANCE_TTFB_MS=600
PERFORMANCE_FCP_MS=1800
# Accessibility standard
ACCESSIBILITY_STANDARD=wcag2aa
# Visual regression
VISUAL_REGRESSION_THRESHOLD=0.1 # 10% pixel difference threshold