Spaces:
Running
Running
// Website Validation Script | |
const validateWebsite = { | |
// Critical paths that must exist and be accessible | |
criticalPaths: [ | |
'/', | |
'/projects', | |
'/papers', | |
'/proposals', | |
'/docs' | |
], | |
// Project paths | |
projectPaths: [ | |
'/projects/automedical', | |
'/projects/analytics', | |
'/projects/autoglaucoma' | |
], | |
// Paper paths | |
paperPaths: [ | |
'/papers/fermed-vlm', | |
'/papers/archive/research', | |
'/papers/archive/publications' | |
], | |
// Proposal paths | |
proposalPaths: [ | |
'/proposals/nhs/main', | |
'/proposals/nhs/detailed', | |
'/proposals/nhs/formal' | |
], | |
// Documentation paths | |
docPaths: [ | |
'/docs/main', | |
'/docs/api', | |
'/docs/deployment' | |
], | |
// Validate all links | |
async validateLinks() { | |
const results = { | |
working: [], | |
redirects: [], | |
broken: [] | |
}; | |
const allPaths = [ | |
...this.criticalPaths, | |
...this.projectPaths, | |
...this.paperPaths, | |
...this.proposalPaths, | |
...this.docPaths | |
]; | |
for (const path of allPaths) { | |
try { | |
const response = await fetch(path); | |
if (response.ok) { | |
if (response.redirected) { | |
results.redirects.push({ | |
path, | |
redirectTo: response.url | |
}); | |
} else { | |
results.working.push(path); | |
} | |
} else { | |
results.broken.push({ | |
path, | |
status: response.status | |
}); | |
} | |
} catch (error) { | |
results.broken.push({ | |
path, | |
error: error.message | |
}); | |
} | |
} | |
return results; | |
}, | |
// Validate navigation consistency | |
validateNavigation() { | |
const results = { | |
consistent: true, | |
errors: [] | |
}; | |
// Check if all pages have navigation | |
document.querySelectorAll('nav').forEach(nav => { | |
const links = nav.querySelectorAll('a'); | |
const requiredLinks = ['Home', 'Projects', 'Papers', 'Proposals', 'Documentation']; | |
const missingLinks = requiredLinks.filter(required => | |
![...links].some(link => | |
link.textContent.trim().toLowerCase() === required.toLowerCase() | |
) | |
); | |
if (missingLinks.length > 0) { | |
results.consistent = false; | |
results.errors.push({ | |
page: window.location.pathname, | |
missingLinks | |
}); | |
} | |
}); | |
return results; | |
}, | |
// Validate breadcrumbs | |
validateBreadcrumbs() { | |
const results = { | |
valid: true, | |
errors: [] | |
}; | |
document.querySelectorAll('.breadcrumb').forEach(breadcrumb => { | |
const links = breadcrumb.querySelectorAll('a'); | |
const currentPath = window.location.pathname; | |
const pathParts = currentPath.split('/').filter(Boolean); | |
// First link should always be Home | |
if (links[0]?.getAttribute('href') !== '/') { | |
results.valid = false; | |
results.errors.push({ | |
page: currentPath, | |
error: 'Missing home link in breadcrumb' | |
}); | |
} | |
// Check if breadcrumb matches current path | |
pathParts.forEach((part, index) => { | |
const link = links[index + 1]; | |
if (!link || !link.getAttribute('href').includes(part)) { | |
results.valid = false; | |
results.errors.push({ | |
page: currentPath, | |
error: `Invalid breadcrumb path at level ${index + 1}` | |
}); | |
} | |
}); | |
}); | |
return results; | |
}, | |
// Generate validation report | |
async generateReport() { | |
const linkResults = await this.validateLinks(); | |
const navResults = this.validateNavigation(); | |
const breadcrumbResults = this.validateBreadcrumbs(); | |
return { | |
timestamp: new Date().toISOString(), | |
links: { | |
total: linkResults.working.length + linkResults.redirects.length + linkResults.broken.length, | |
working: linkResults.working.length, | |
redirects: linkResults.redirects.length, | |
broken: linkResults.broken.length, | |
details: linkResults | |
}, | |
navigation: { | |
consistent: navResults.consistent, | |
errors: navResults.errors | |
}, | |
breadcrumbs: { | |
valid: breadcrumbResults.valid, | |
errors: breadcrumbResults.errors | |
} | |
}; | |
} | |
}; | |
// Export for use in Node.js environments | |
if (typeof module !== 'undefined' && module.exports) { | |
module.exports = validateWebsite; | |
} | |
// For browser use | |
if (typeof window !== 'undefined') { | |
window.validateWebsite = validateWebsite; | |
} |