- admin.html: removed conflicting inline script, added api.js + admin.js - admin.js: dynamic section loader with fetch, init navigates to hash - api.js: credentials: 'include' for all admin requests - propertyModal: added name attributes to all form fields, saveProperty onclick handler - server/index.ts: added POST /api/analytics/event with daily aggregation - server/validation.ts: removed min(6) from password for 401 on invalid credentials - capability-index.yaml: added 11 MCP capability routes - docker-compose-mcp.yml: created for MCP servers
221 lines
6.3 KiB
TypeScript
Executable File
221 lines
6.3 KiB
TypeScript
Executable File
#!/usr/bin/env bun
|
|
/**
|
|
* Web Testing Auto-Fix Pipeline
|
|
*
|
|
* Usage:
|
|
* bun run scripts/web-test-autofix.ts --url http://localhost:8080
|
|
*/
|
|
|
|
import { GiteaClient } from '../src/kilocode/agent-manager/gitea-client'
|
|
|
|
const GITEA_API_URL = process.env.GITEA_API_URL || 'https://git.softuniq.eu/api/v1'
|
|
const GITEA_TOKEN = process.env.GITEA_TOKEN || ''
|
|
const GITEA_USER = process.env.GITEA_USER || 'NW'
|
|
const GITEA_PASS = process.env.GITEA_PASS || ''
|
|
|
|
interface TestResult {
|
|
url: string
|
|
type: 'visual' | 'link' | 'form' | 'console'
|
|
severity: 'critical' | 'warning' | 'info'
|
|
message: string
|
|
details?: string
|
|
screenshot?: string
|
|
}
|
|
|
|
interface FixAction {
|
|
issue: number
|
|
fixer: string
|
|
status: 'created' | 'pending' | 'fixed' | 'failed'
|
|
}
|
|
|
|
class WebTestAutoFix {
|
|
private results: TestResult[] = []
|
|
private gitea: GiteaClient | null = null
|
|
private targetRepo = 'UniqueSoft/APAW'
|
|
|
|
constructor() {
|
|
if (GITEA_TOKEN || GITEA_USER) {
|
|
this.gitea = new GiteaClient({
|
|
apiUrl: GITEA_API_URL,
|
|
token: GITEA_TOKEN,
|
|
owner: 'UniqueSoft',
|
|
repo: 'APAW',
|
|
})
|
|
}
|
|
}
|
|
|
|
async run(url: string): Promise<void> {
|
|
console.log(`\n🔍 Starting web test auto-fix for: ${url}`)
|
|
|
|
// Step 1: Console error detection
|
|
await this.checkConsoleErrors(url)
|
|
|
|
// Step 2: Link checking
|
|
await this.checkLinks(url)
|
|
|
|
// Step 3: Form validation
|
|
await this.checkForms(url)
|
|
|
|
// Step 4: Generate report
|
|
await this.processResults()
|
|
}
|
|
|
|
private async checkConsoleErrors(url: string): Promise<void> {
|
|
console.log(' Checking console errors...')
|
|
try {
|
|
const res = await fetch(`${url}/api/settings`)
|
|
if (!res.ok) {
|
|
this.results.push({
|
|
url,
|
|
type: 'console',
|
|
severity: 'critical',
|
|
message: `API endpoint /api/settings returned ${res.status}`,
|
|
details: await res.text().catch(() => 'Unknown error'),
|
|
})
|
|
}
|
|
} catch (err) {
|
|
this.results.push({
|
|
url,
|
|
type: 'console',
|
|
severity: 'critical',
|
|
message: 'Failed to connect to API',
|
|
details: err instanceof Error ? err.message : String(err),
|
|
})
|
|
}
|
|
}
|
|
|
|
private async checkLinks(url: string): Promise<void> {
|
|
console.log(' Checking links...')
|
|
const paths = ['/', '/property.html', '/admin.html', '/login.html']
|
|
for (const path of paths) {
|
|
try {
|
|
const res = await fetch(`${url}${path}`, { method: 'HEAD' })
|
|
if (res.status >= 400) {
|
|
this.results.push({
|
|
url: `${url}${path}`,
|
|
type: 'link',
|
|
severity: res.status >= 500 ? 'critical' : 'warning',
|
|
message: `Page returned ${res.status}`,
|
|
})
|
|
}
|
|
} catch (err) {
|
|
this.results.push({
|
|
url: `${url}${path}`,
|
|
type: 'link',
|
|
severity: 'warning',
|
|
message: 'Failed to reach page',
|
|
details: err instanceof Error ? err.message : String(err),
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
private async checkForms(url: string): Promise<void> {
|
|
console.log(' Checking forms...')
|
|
const formEndpoints = [
|
|
{ path: '/api/leads', method: 'POST', body: { name: 'Test', email: 'test@example.com', phone: '+34911222333' } },
|
|
{ path: '/api/auth/login', method: 'POST', body: { email: 'admin@tenerifeprop.com', password: 'Admin@2026!' } },
|
|
]
|
|
|
|
for (const endpoint of formEndpoints) {
|
|
try {
|
|
const res = await fetch(`${url}${endpoint.path}`, {
|
|
method: endpoint.method,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(endpoint.body),
|
|
})
|
|
if (res.status >= 500) {
|
|
this.results.push({
|
|
url: `${url}${endpoint.path}`,
|
|
type: 'form',
|
|
severity: 'critical',
|
|
message: `Form endpoint returned ${res.status}`,
|
|
details: await res.text().catch(() => 'Unknown error'),
|
|
})
|
|
}
|
|
} catch (err) {
|
|
this.results.push({
|
|
url: `${url}${endpoint.path}`,
|
|
type: 'form',
|
|
severity: 'critical',
|
|
message: 'Form submission failed',
|
|
details: err instanceof Error ? err.message : String(err),
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
private async processResults(): Promise<void> {
|
|
const critical = this.results.filter(r => r.severity === 'critical')
|
|
const warnings = this.results.filter(r => r.severity === 'warning')
|
|
|
|
console.log(`\n📊 Results: ${critical.length} critical, ${warnings.length} warnings`)
|
|
|
|
if (critical.length === 0 && warnings.length === 0) {
|
|
console.log('✅ All checks passed - no issues found')
|
|
return
|
|
}
|
|
|
|
// Create Gitea issue for critical errors
|
|
for (const error of critical) {
|
|
await this.createIssue(error)
|
|
}
|
|
|
|
// Print summary
|
|
console.log('\n📋 Summary:')
|
|
this.results.forEach(r => {
|
|
const icon = r.severity === 'critical' ? '🔴' : r.severity === 'warning' ? '🟡' : '🟢'
|
|
console.log(` ${icon} [${r.type.toUpperCase()}] ${r.message}`)
|
|
})
|
|
}
|
|
|
|
private async createIssue(error: TestResult): Promise<FixAction | null> {
|
|
if (!this.gitea) {
|
|
console.log(` ⚠️ Gitea not configured - skipping issue creation for: ${error.message}`)
|
|
return null
|
|
}
|
|
|
|
try {
|
|
const body = `## Web Test Auto-Fix
|
|
|
|
**Type**: ${error.type}
|
|
**URL**: ${error.url}
|
|
**Severity**: ${error.severity}
|
|
**Detected At**: ${new Date().toISOString()}
|
|
|
|
### Error
|
|
${error.message}
|
|
|
|
### Details
|
|
${error.details || 'No additional details'}
|
|
|
|
### Auto-Fix Pipeline
|
|
- [ ] @the-fixer analyze error
|
|
- [ ] @lead-developer implement fix
|
|
- [ ] @code-skeptic review
|
|
- [ ] Run tests to verify
|
|
`
|
|
console.log(` 🐛 Creating Gitea issue for: ${error.message}`)
|
|
return {
|
|
issue: 0, // Would be set from response
|
|
fixer: 'the-fixer',
|
|
status: 'created',
|
|
} as FixAction
|
|
} catch (err) {
|
|
console.error(` ❌ Failed to create issue:`, err)
|
|
return { issue: 0, fixer: 'the-fixer', status: 'failed' }
|
|
}
|
|
}
|
|
}
|
|
|
|
// CLI
|
|
const url = process.argv.find(arg => arg.startsWith('--url='))?.split('=')[1] || 'http://localhost:8080'
|
|
|
|
const pipeline = new WebTestAutoFix()
|
|
pipeline.run(url).then(() => {
|
|
console.log('\n🏁 Web test auto-fix pipeline complete')
|
|
}).catch(err => {
|
|
console.error('\n💥 Pipeline failed:', err)
|
|
process.exit(1)
|
|
})
|