Sami
Sync changes - automated commit
53873ca
// 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;
}