Skip to content

Commit 8a26400

Browse files
committed
ci: Enhance logging for troubleshooting test failures not due to broken links
1 parent 4ae1dec commit 8a26400

File tree

2 files changed

+319
-51
lines changed

2 files changed

+319
-51
lines changed

cypress/e2e/content/article-links.cy.js

Lines changed: 172 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ describe('Article', () => {
4747
cy.wrap(Promise.all(urlPromises)).then((urls) => {
4848
subjects = urls;
4949

50-
cy.log(`📊 Cache Analysis: ${results.cacheStats.hitRate}% hit rate`);
50+
cy.log(
51+
`📊 Cache Analysis: ${results.cacheStats.hitRate}% hit rate`
52+
);
5153
cy.log(
5254
`🔄 Testing ${subjects.length} pages (${results.cacheStats.cacheHits} cached)`
5355
);
@@ -60,7 +62,23 @@ describe('Article', () => {
6062
})
6163
.catch((error) => {
6264
cy.log('❌ Error during incremental validation task: ' + error.message);
63-
Cypress.fail('Incremental validation task failed. See logs for details.');
65+
66+
// Provide more debugging information for validation failures
67+
cy.log('🔍 Validation Error Details:');
68+
cy.log(` • Error Type: ${error.name || 'Unknown'}`);
69+
cy.log(` • Error Message: ${error.message}`);
70+
if (error.stack) {
71+
const stackLines = error.stack.split('\n').slice(0, 3);
72+
cy.log(` • Stack Trace: ${stackLines.join(' -> ')}`);
73+
}
74+
cy.log(
75+
'💡 This error occurred during cache analysis or file validation setup'
76+
);
77+
cy.log(' Check that all files exist and are readable');
78+
79+
Cypress.fail(
80+
`Incremental validation task failed: ${error.message}. Check logs for details.`
81+
);
6482
});
6583
});
6684

@@ -170,30 +188,99 @@ describe('Article', () => {
170188
}
171189

172190
// Test implementation for subjects
191+
// Add debugging information about test subjects
192+
it('Test Setup Validation', function () {
193+
cy.log(`📋 Test Configuration:`);
194+
cy.log(` • Test subjects count: ${subjects.length}`);
195+
cy.log(` • Validation strategy: ${validationStrategy || 'Not set'}`);
196+
197+
if (subjects.length === 0) {
198+
cy.log('⚠️ No test subjects found - this may indicate:');
199+
cy.log(' • All files were cached and skipped');
200+
cy.log(' • No files matched the test criteria');
201+
cy.log(' • File mapping failed during setup');
202+
203+
// Don't fail if this is expected (cache hit scenario)
204+
const testSubjectsData = Cypress.env('test_subjects_data');
205+
if (testSubjectsData) {
206+
cy.log(
207+
'ℹ️ Test subjects data is available, cache optimization likely active'
208+
);
209+
} else {
210+
cy.log('❌ No test subjects data available - potential setup issue');
211+
}
212+
} else {
213+
cy.log(`✅ Ready to test ${subjects.length} pages`);
214+
subjects.slice(0, 5).forEach((subject) => cy.log(` • ${subject}`));
215+
if (subjects.length > 5) {
216+
cy.log(` ... and ${subjects.length - 5} more pages`);
217+
}
218+
}
219+
});
220+
173221
subjects.forEach((subject) => {
174222
it(`${subject} has valid internal links`, function () {
175-
cy.visit(`${subject}`, { timeout: 20000 });
223+
// Add error handling for page visit failures
224+
cy.visit(`${subject}`, { timeout: 20000 })
225+
.then(() => {
226+
cy.log(`✅ Successfully loaded page: ${subject}`);
227+
})
228+
.catch((error) => {
229+
cy.log(`❌ Failed to load page: ${subject}`);
230+
cy.log(` • Error: ${error.message}`);
231+
cy.log('💡 This could indicate:');
232+
cy.log(' • Hugo server not running or crashed');
233+
cy.log(' • Invalid URL or routing issue');
234+
cy.log(' • Network connectivity problems');
235+
throw error; // Re-throw to fail the test properly
236+
});
176237

177238
// Test internal links
178-
cy.get('article, .api-content').then(($article) => {
179-
// Find links without failing the test if none are found
180-
const $links = $article.find('a[href^="/"]');
181-
if ($links.length === 0) {
182-
cy.log('No internal links found on this page');
183-
return;
184-
}
239+
cy.get('article, .api-content')
240+
.then(($article) => {
241+
// Find links without failing the test if none are found
242+
const $links = $article.find('a[href^="/"]');
243+
if ($links.length === 0) {
244+
cy.log('No internal links found on this page');
245+
return;
246+
}
185247

186-
// Now test each link
187-
cy.wrap($links).each(($a) => {
188-
const href = $a.attr('href');
189-
const linkText = $a.text().trim();
190-
testLink(href, linkText, subject);
248+
cy.log(`🔍 Testing ${$links.length} internal links on ${subject}`);
249+
250+
// Now test each link
251+
cy.wrap($links).each(($a) => {
252+
const href = $a.attr('href');
253+
const linkText = $a.text().trim();
254+
255+
try {
256+
testLink(href, linkText, subject);
257+
} catch (error) {
258+
cy.log(`❌ Error testing link ${href}: ${error.message}`);
259+
throw error; // Re-throw to fail the test
260+
}
261+
});
262+
})
263+
.catch((error) => {
264+
cy.log(`❌ Error finding article content on ${subject}`);
265+
cy.log(` • Error: ${error.message}`);
266+
cy.log('💡 This could indicate:');
267+
cy.log(' • Page structure changed (missing article/.api-content)');
268+
cy.log(' • Page failed to render properly');
269+
cy.log(' • JavaScript errors preventing DOM updates');
270+
throw error;
191271
});
192-
});
193272
});
194273

195274
it(`${subject} has valid anchor links`, function () {
196-
cy.visit(`${subject}`);
275+
cy.visit(`${subject}`)
276+
.then(() => {
277+
cy.log(`✅ Successfully loaded page for anchor testing: ${subject}`);
278+
})
279+
.catch((error) => {
280+
cy.log(`❌ Failed to load page for anchor testing: ${subject}`);
281+
cy.log(` • Error: ${error.message}`);
282+
throw error;
283+
});
197284

198285
// Define selectors for anchor links to ignore, such as behavior triggers
199286
const ignoreLinks = ['.tabs a[href^="#"]', '.code-tabs a[href^="#"]'];
@@ -208,6 +295,8 @@ describe('Article', () => {
208295
return;
209296
}
210297

298+
cy.log(`🔗 Testing ${$anchorLinks.length} anchor links on ${subject}`);
299+
211300
cy.wrap($anchorLinks).each(($a) => {
212301
const href = $a.prop('href');
213302
const linkText = $a.text().trim();
@@ -250,48 +339,82 @@ describe('Article', () => {
250339
return;
251340
}
252341

253-
cy.visit(`${subject}`);
342+
cy.visit(`${subject}`)
343+
.then(() => {
344+
cy.log(
345+
`✅ Successfully loaded page for external link testing: ${subject}`
346+
);
347+
})
348+
.catch((error) => {
349+
cy.log(
350+
`❌ Failed to load page for external link testing: ${subject}`
351+
);
352+
cy.log(` • Error: ${error.message}`);
353+
throw error;
354+
});
254355

255356
// Define allowed external domains to test
256357
const allowedExternalDomains = ['github.com', 'kapa.ai'];
257358

258359
// Test external links
259-
cy.get('article, .api-content').then(($article) => {
260-
// Find links without failing the test if none are found
261-
const $links = $article.find('a[href^="http"]');
262-
if ($links.length === 0) {
263-
cy.log('No external links found on this page');
264-
return;
265-
}
360+
cy.get('article, .api-content')
361+
.then(($article) => {
362+
// Find links without failing the test if none are found
363+
const $links = $article.find('a[href^="http"]');
364+
if ($links.length === 0) {
365+
cy.log('No external links found on this page');
366+
return;
367+
}
266368

267-
// Filter links to only include allowed domains
268-
const $allowedLinks = $links.filter((_, el) => {
269-
const href = el.getAttribute('href');
270-
try {
271-
const url = new URL(href);
272-
return allowedExternalDomains.some(
273-
(domain) =>
274-
url.hostname === domain || url.hostname.endsWith(`.${domain}`)
369+
cy.log(
370+
`🔍 Found ${$links.length} total external links on ${subject}`
371+
);
372+
373+
// Filter links to only include allowed domains
374+
const $allowedLinks = $links.filter((_, el) => {
375+
const href = el.getAttribute('href');
376+
try {
377+
const url = new URL(href);
378+
return allowedExternalDomains.some(
379+
(domain) =>
380+
url.hostname === domain || url.hostname.endsWith(`.${domain}`)
381+
);
382+
} catch (urlError) {
383+
cy.log(`⚠️ Invalid URL found: ${href}`);
384+
return false;
385+
}
386+
});
387+
388+
if ($allowedLinks.length === 0) {
389+
cy.log('No links to allowed external domains found on this page');
390+
cy.log(
391+
` • Allowed domains: ${allowedExternalDomains.join(', ')}`
275392
);
276-
} catch (e) {
277-
return false;
393+
return;
278394
}
279-
});
280395

281-
if ($allowedLinks.length === 0) {
282-
cy.log('No links to allowed external domains found on this page');
283-
return;
284-
}
285-
286-
cy.log(
287-
`Found ${$allowedLinks.length} links to allowed external domains to test`
288-
);
289-
cy.wrap($allowedLinks).each(($a) => {
290-
const href = $a.attr('href');
291-
const linkText = $a.text().trim();
292-
testLink(href, linkText, subject);
396+
cy.log(
397+
`🌐 Testing ${$allowedLinks.length} links to allowed external domains`
398+
);
399+
cy.wrap($allowedLinks).each(($a) => {
400+
const href = $a.attr('href');
401+
const linkText = $a.text().trim();
402+
403+
try {
404+
testLink(href, linkText, subject);
405+
} catch (error) {
406+
cy.log(
407+
`❌ Error testing external link ${href}: ${error.message}`
408+
);
409+
throw error;
410+
}
411+
});
412+
})
413+
.catch((error) => {
414+
cy.log(`❌ Error processing external links on ${subject}`);
415+
cy.log(` • Error: ${error.message}`);
416+
throw error;
293417
});
294-
});
295418
});
296419
});
297420
});

0 commit comments

Comments
 (0)