Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions test/fixtures/directory-path-links-test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Directory Path Links Test</title>
<link rel="canonical" href="http://example.com/directory-path-links-test">
</head>
<body>
<h1>Testing Directory Path Links</h1>
<p>This page tests various directory link scenarios:</p>
<ul>
<li><a href="directory-with-no-index">directory-with-no-index (should be broken)</a></li>
<li><a href="directory-with-no-index/">directory-with-no-index/ (should be broken)</a></li>
<li><a href="directory-with-no-index/index">directory-with-no-index/index (should be broken)</a></li>
<li><a href="directory-with-index">directory-with-index (should be broken)</a></li>
<li><a href="directory-with-index/">directory-with-index/ (should be OK)</a></li>
<li><a href="directory-with-index/index">directory-with-index/index (should be OK)</a></li>
<li><a href="directory-with-no-index-with-twin">directory-with-no-index-with-twin (should be OK)</a></li>
<li><a href="directory-with-no-index-with-twin/">directory-with-no-index-with-twin/ (should be broken)</a></li>
<li>
<a href="directory-with-no-index-with-twin/index">directory-with-no-index-with-twin/index (should be broken)</a>
</li>
</ul>
</body>
</html>
12 changes: 12 additions & 0 deletions test/fixtures/directory-with-index/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Directory Index</title>
<link rel="canonical" href="http://example.com/directory-with-index/">
</head>
<body>
<h1>Directory Index Page</h1>
<p>This is the index page for a directory that has an index.html file.</p>
</body>
</html>
12 changes: 12 additions & 0 deletions test/fixtures/directory-with-no-index-with-twin.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Twin File</title>
<link rel="canonical" href="http://example.com/directory-with-no-index-with-twin.html">
</head>
<body>
<h1>Twin File</h1>
<p>This is the twin HTML file for the directory-with-no-index-with-twin directory.</p>
</body>
</html>
12 changes: 12 additions & 0 deletions test/fixtures/directory-with-no-index-with-twin/some-page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Some Page in Twin Directory</title>
<link rel="canonical" href="http://example.com/directory-with-no-index-with-twin/some-page.html">
</head>
<body>
<h1>Some Page in Directory with No Index but Has Twin</h1>
<p>This is a page in a directory that has no index.html file but has a twin HTML file at the same level.</p>
</body>
</html>
12 changes: 12 additions & 0 deletions test/fixtures/directory-with-no-index/some-page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Some Page</title>
<link rel="canonical" href="http://example.com/directory-with-no-index/some-page.html">
</head>
<body>
<h1>Some Page in Directory with No Index</h1>
<p>This is a page in a directory that has no index.html file.</p>
</body>
</html>
62 changes: 62 additions & 0 deletions test/fixtures/required-results.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,67 @@
"selector": "html > body > img",
"ruleUrl": "https://html-validate.org/rules/wcag/h37.html"
}
],
"test/fixtures/directory-path-links-test.html": [
{
"ruleId": "pacific-medical-training/internal-links",
"severity": 2,
"message": "internal link \"directory-with-no-index\" is broken.",
"offset": 367,
"line": 12,
"column": 44,
"size": 1,
"selector": "html > body > ul > li:nth-child(1) > a"
},
{
"ruleId": "pacific-medical-training/internal-links",
"severity": 2,
"message": "internal link \"directory-with-no-index/\" is broken.",
"offset": 464,
"line": 13,
"column": 45,
"size": 1,
"selector": "html > body > ul > li:nth-child(2) > a"
},
{
"ruleId": "pacific-medical-training/internal-links",
"severity": 2,
"message": "internal link \"directory-with-no-index/index\" is broken.",
"offset": 567,
"line": 14,
"column": 50,
"size": 1,
"selector": "html > body > ul > li:nth-child(3) > a"
},
{
"ruleId": "pacific-medical-training/internal-links",
"severity": 2,
"message": "internal link \"directory-with-index\" is broken.",
"offset": 666,
"line": 15,
"column": 41,
"size": 1,
"selector": "html > body > ul > li:nth-child(4) > a"
},
{
"ruleId": "pacific-medical-training/internal-links",
"severity": 2,
"message": "internal link \"directory-with-no-index-with-twin/\" is broken.",
"offset": 1068,
"line": 19,
"column": 55,
"size": 1,
"selector": "html > body > ul > li:nth-child(8) > a"
},
{
"ruleId": "pacific-medical-training/internal-links",
"severity": 2,
"message": "internal link \"directory-with-no-index-with-twin/index\" is broken.",
"offset": 1200,
"line": 21,
"column": 58,
"size": 1,
"selector": "html > body > ul > li:nth-child(9) > a"
}
]
}
2 changes: 1 addition & 1 deletion test/plugin.html-validate.https-links.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default class EnsureHttpsRules extends Rule {
const curlOutput = execSync(curlCommand, { encoding: "utf-8" });

// If the link is accessible via HTTPS, report it as insecure
if (curlOutput.includes("HTTP/2 200")) {
if (curlOutput.includes("200")) {
this.db.prepare("REPLACE INTO urls (url, found, time) VALUES (?, 1, unixepoch())").run(url);
const insecureRow = this.db.prepare("SELECT found, time FROM urls WHERE url = ?").get(url);
this.report({
Expand Down
32 changes: 20 additions & 12 deletions test/plugin.html-validate.internal-links.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default class CheckInternalLinks extends Rule {
return this.fileExistsCache.get(path);
}

const exists = fs.existsSync(path);
const exists = fs.existsSync(path) && fs.lstatSync(path).isFile();
this.fileExistsCache.set(path, exists);
return exists;
}
Expand All @@ -60,17 +60,25 @@ export default class CheckInternalLinks extends Rule {
const basePath = path.dirname(element.location.filename);
let resolvedPath = path.resolve(basePath, resolvedLink);

// If it's a directory, append the index file
if (fs.existsSync(resolvedPath) && fs.lstatSync(resolvedPath).isDirectory()) {
resolvedPath = path.join(resolvedPath, this.indexFile);
}

// Pass if the URL matches a file or an alternative extension
if (
this.doesFileExist(resolvedPath) ||
this.alternativeExtensions.some((ext) => this.doesFileExist(`${resolvedPath}${ext}`))
) {
return;
// Handle links ending with "/" - these should only work if directory has index file
if (internalLink.endsWith("/")) {
if (fs.existsSync(resolvedPath) && fs.lstatSync(resolvedPath).isDirectory()) {
resolvedPath = path.join(resolvedPath, this.indexFile);
if (this.doesFileExist(resolvedPath)) {
return;
}
}
} else {
// Handle links not ending with "/" - first check for file with extensions
if (
this.doesFileExist(resolvedPath) ||
this.alternativeExtensions.some((ext) => this.doesFileExist(`${resolvedPath}${ext}`))
) {
return;
}

// Do NOT automatically check directories for links not ending with "/"
// This ensures bare directory names like "directory-with-index" are treated as broken
}

// Report an error with the resolved path
Expand Down
Loading