-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy patherror-check.js
More file actions
349 lines (292 loc) · 10.9 KB
/
error-check.js
File metadata and controls
349 lines (292 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
// Comprehensive Error Check Script for Nashr Foundation Website
// Run this in the browser console to check for potential issues
console.log('Starting comprehensive error check...');
// Check for missing images
function checkMissingImages() {
console.log('Checking for missing images...');
const images = document.querySelectorAll('img');
const missingImages = [];
images.forEach(img => {
// Count only images that have finished attempting to load and failed
if (img.complete && img.naturalWidth === 0) {
missingImages.push({
src: img.src,
alt: img.alt,
element: img
});
} else {
// Attach one-time error logger for late-loading images
img.addEventListener('error', () => {
console.warn('❌ Image failed to load:', { src: img.src, alt: img.alt });
}, { once: true });
}
});
if (missingImages.length > 0) {
console.warn('⚠️ Missing or broken images:', missingImages);
// Attempt graceful fallback to logo for broken images
missingImages.forEach(item => {
try {
if (item.element && item.element.src !== location.origin + '/logo.webp') {
item.element.src = 'logo.webp';
}
} catch (e) {}
});
return false;
} else {
console.log('✅ All images loaded successfully');
return true;
}
}
// Check for JavaScript errors
function checkJavaScriptErrors() {
console.log('⚡ Checking for JavaScript errors...');
// Feature-aware checks per page content
const requiredFunctions = [];
// Require Chart only if charts are present
if (document.getElementById('donations-chart') || document.getElementById('payment-methods-chart')) {
requiredFunctions.push('Chart');
}
// Require AOS only if elements declare data-aos
if (document.querySelector('[data-aos]')) {
requiredFunctions.push('AOS');
}
// Require gtag only if GTM is included
if (document.querySelector('script[src*="googletagmanager.com"]')) {
// Treat presence of GTM script or dataLayer as sufficient
if (!(window.dataLayer && Array.isArray(window.dataLayer))) {
requiredFunctions.push('gtag');
}
}
const missingFunctions = requiredFunctions.filter(func => {
if (func === 'gtag') return typeof window.gtag === 'undefined';
return typeof window[func] === 'undefined';
});
if (missingFunctions.length > 0) {
console.warn('⚠️ Missing JavaScript functions:', missingFunctions);
return false;
} else {
console.log('✅ All required JavaScript functions available');
return true;
}
}
// Check for CSS issues
function checkCSSIssues() {
console.log('Checking for CSS issues...');
// Check if critical CSS is loaded
const criticalCSS = document.querySelector('style');
if (!criticalCSS) {
console.warn('⚠️ Critical CSS not found');
return false;
}
// Check if main CSS is loaded
const mainCSS = document.querySelector('link[href*="styles.css"]');
if (!mainCSS) {
console.warn('⚠️ Main CSS not loaded');
return false;
}
console.log('✅ CSS loaded successfully');
return true;
}
// Check for accessibility issues
function checkAccessibility() {
console.log('♿ Checking accessibility...');
let issues = 0;
// Check for alt text on images
const imagesWithoutAlt = document.querySelectorAll('img:not([alt])');
if (imagesWithoutAlt.length > 0) {
console.warn('⚠️ Images without alt text:', imagesWithoutAlt.length);
issues++;
}
// Check for proper heading hierarchy
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
let prevLevel = 0;
headings.forEach(heading => {
const level = parseInt(heading.tagName.charAt(1));
if (level > prevLevel + 1) {
console.warn('⚠️ Skipped heading level:', heading);
issues++;
}
prevLevel = level;
});
// Check for skip navigation
const skipLink = document.querySelector('.skip-link');
if (!skipLink) {
console.warn('⚠️ Skip navigation link not found');
issues++;
}
if (issues === 0) {
console.log('✅ Accessibility checks passed');
return true;
} else {
console.warn(`⚠️ Found ${issues} accessibility issues`);
return false;
}
}
// Check for performance issues
function checkPerformance() {
console.log('Checking performance...');
// Check for large images
const images = document.querySelectorAll('img');
const largeImages = [];
images.forEach(img => {
if (img.naturalWidth > 1920 || img.naturalHeight > 1080) {
largeImages.push({
src: img.src,
width: img.naturalWidth,
height: img.naturalHeight
});
}
});
if (largeImages.length > 0) {
console.warn('⚠️ Large images detected (consider optimization):', largeImages);
}
// Check for external resources
const externalScripts = document.querySelectorAll('script[src^="http"]');
const externalStyles = document.querySelectorAll('link[href^="http"]');
console.log(`External resources: ${externalScripts.length} scripts, ${externalStyles.length} stylesheets`);
return true;
}
// Check for mobile responsiveness
function checkMobileResponsiveness() {
console.log('Checking mobile responsiveness...');
// Use matchMedia to respect CSS media queries
const isMobile = window.matchMedia && window.matchMedia('(max-width: 768px)').matches;
// Check if mobile menu toggle is visible
const mobileToggle = document.querySelector('.mobile-menu-toggle');
if (mobileToggle && isMobile) {
const computedStyle = window.getComputedStyle(mobileToggle);
// Reduce false positives: consider it an issue only if it's not displayed AND not interactable in layout
const notDisplayed = computedStyle.display === 'none';
const notInLayout = mobileToggle.offsetParent === null;
if (notDisplayed && notInLayout) {
console.info('ℹ️ Mobile menu toggle appears hidden; verify CSS @media for .mobile-menu-toggle');
}
}
console.log('✅ Mobile responsiveness check completed');
return true;
}
// Check for SEO elements
function checkSEO() {
console.log('Checking SEO elements...');
let issues = 0;
// Check meta description
const metaDescription = document.querySelector('meta[name="description"]');
if (!metaDescription || !metaDescription.content) {
console.warn('⚠️ Meta description missing or empty');
issues++;
}
// Check title
const title = document.title;
if (!title || title.length < 10 || title.length > 60) {
console.warn('⚠️ Title length issue:', title.length, 'characters');
issues++;
}
// Check canonical URL
const canonical = document.querySelector('link[rel="canonical"]');
if (!canonical) {
console.warn('⚠️ Canonical URL missing');
issues++;
}
// Check Open Graph tags
const ogTags = document.querySelectorAll('meta[property^="og:"]');
if (ogTags.length === 0) {
console.warn('⚠️ Open Graph tags missing');
issues++;
}
if (issues === 0) {
console.log('✅ SEO elements check passed');
return true;
} else {
console.warn(`⚠️ Found ${issues} SEO issues`);
return false;
}
}
// Check for security headers (if possible)
function checkSecurity() {
console.log('Checking security...');
// Check for HTTPS
if (location.protocol !== 'https:' && location.hostname !== 'localhost') {
console.warn('⚠️ Not using HTTPS');
return false;
}
// Check for CSP (Content Security Policy)
const cspMeta = document.querySelector('meta[http-equiv="Content-Security-Policy"]');
if (!cspMeta) {
console.log('ℹ️ CSP meta tag not found (may be set via headers)');
}
console.log('✅ Security checks passed');
return true;
}
// Check for PWA features
function checkPWA() {
console.log('Checking PWA features...');
let features = 0;
// Check manifest
const manifest = document.querySelector('link[rel="manifest"]');
if (manifest) {
console.log('✅ Web App Manifest found');
features++;
}
// Check service worker
if ('serviceWorker' in navigator) {
console.log('✅ Service Worker API available');
features++;
}
// Check for offline capability
if ('caches' in window) {
console.log('✅ Cache API available');
features++;
}
console.log(`PWA features: ${features}/3 available`);
return features > 0;
}
// Main error check function
function runComprehensiveCheck() {
console.log('Starting comprehensive website check...\n');
const results = {
images: checkMissingImages(),
javascript: checkJavaScriptErrors(),
css: checkCSSIssues(),
accessibility: checkAccessibility(),
performance: checkPerformance(),
mobile: checkMobileResponsiveness(),
seo: checkSEO(),
security: checkSecurity(),
pwa: checkPWA()
};
console.log('\nCHECK RESULTS SUMMARY:');
console.log('========================');
Object.entries(results).forEach(([category, result]) => {
const status = result ? '✅ PASS' : '❌ FAIL';
console.log(`${category.toUpperCase()}: ${status}`);
});
const passedChecks = Object.values(results).filter(Boolean).length;
const totalChecks = Object.keys(results).length;
console.log(`\nOverall Score: ${passedChecks}/${totalChecks} (${Math.round((passedChecks/totalChecks)*100)}%)`);
if (passedChecks === totalChecks) {
console.log('All checks passed! Your website is ready for production.');
} else {
console.log('⚠️ Some checks failed. Please review the warnings above.');
}
return results;
}
// Auto-run if this script is loaded
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', runComprehensiveCheck);
} else {
runComprehensiveCheck();
}
// Export for manual use
window.websiteErrorCheck = {
run: runComprehensiveCheck,
checkImages: checkMissingImages,
checkJavaScript: checkJavaScriptErrors,
checkCSS: checkCSSIssues,
checkAccessibility: checkAccessibility,
checkPerformance: checkPerformance,
checkMobile: checkMobileResponsiveness,
checkSEO: checkSEO,
checkSecurity: checkSecurity,
checkPWA: checkPWA
};
console.log('🔧 Error check script loaded. Use window.websiteErrorCheck.run() to run manually.');