gbu-accessibility-package 1.5.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.js CHANGED
@@ -14,14 +14,19 @@ const args = process.argv.slice(2);
14
14
  const options = {
15
15
  directory: '.',
16
16
  language: 'ja',
17
- backupFiles: true,
17
+ backupFiles: true, // Default to true for safety
18
18
  dryRun: false,
19
19
  help: false,
20
20
  cleanupOnly: false,
21
- comprehensive: false,
21
+ comprehensive: false, // Keep for backward compatibility
22
22
  altOnly: false,
23
23
  langOnly: false,
24
- roleOnly: false
24
+ roleOnly: false,
25
+ formsOnly: false,
26
+ buttonsOnly: false,
27
+ linksOnly: false,
28
+ landmarksOnly: false,
29
+ headingsOnly: false
25
30
  };
26
31
 
27
32
  // Parse arguments
@@ -41,6 +46,9 @@ for (let i = 0; i < args.length; i++) {
41
46
  case '-l':
42
47
  options.language = args[++i];
43
48
  break;
49
+ case '--backup':
50
+ options.backupFiles = true;
51
+ break;
44
52
  case '--no-backup':
45
53
  options.backupFiles = false;
46
54
  break;
@@ -52,7 +60,7 @@ for (let i = 0; i < args.length; i++) {
52
60
  break;
53
61
  case '--comprehensive':
54
62
  case '--all':
55
- options.comprehensive = true;
63
+ options.comprehensive = true; // Keep for backward compatibility
56
64
  break;
57
65
  case '--alt-only':
58
66
  options.altOnly = true;
@@ -63,6 +71,21 @@ for (let i = 0; i < args.length; i++) {
63
71
  case '--role-only':
64
72
  options.roleOnly = true;
65
73
  break;
74
+ case '--forms-only':
75
+ options.formsOnly = true;
76
+ break;
77
+ case '--buttons-only':
78
+ options.buttonsOnly = true;
79
+ break;
80
+ case '--links-only':
81
+ options.linksOnly = true;
82
+ break;
83
+ case '--landmarks-only':
84
+ options.landmarksOnly = true;
85
+ break;
86
+ case '--headings-only':
87
+ options.headingsOnly = true;
88
+ break;
66
89
  default:
67
90
  if (!arg.startsWith('-')) {
68
91
  options.directory = arg;
@@ -80,25 +103,34 @@ Usage: node cli.js [options] [directory]
80
103
  Options:
81
104
  -d, --directory <path> Target directory (default: current directory)
82
105
  -l, --language <lang> Language for lang attribute (default: ja)
106
+ --backup Create backup files (default: enabled)
83
107
  --no-backup Don't create backup files
84
108
  --dry-run Preview changes without applying
85
- --comprehensive, --all Run all fixes including cleanup (recommended)
109
+ --comprehensive, --all Run comprehensive fixes (same as default)
86
110
  --cleanup-only Only cleanup duplicate role attributes
87
- --alt-only Only fix alt attributes for images
88
- --lang-only Only fix HTML lang attributes
89
- --role-only Only fix role attributes
111
+ --alt-only Fix alt attributes + cleanup
112
+ --lang-only Fix HTML lang attributes + cleanup
113
+ --role-only Fix role attributes + cleanup
114
+ --forms-only Fix form labels + cleanup
115
+ --buttons-only Fix button names + cleanup
116
+ --links-only Fix link names + cleanup
117
+ --landmarks-only Fix landmarks + cleanup
118
+ --headings-only Analyze heading structure (no auto-fix)
90
119
  -h, --help Show this help message
91
120
 
92
121
  Examples:
93
- node cli.js # Fix current directory (standard fixes)
94
- node cli.js --comprehensive # Run all fixes including cleanup
95
- node cli.js --alt-only # Only fix alt attributes
96
- node cli.js --lang-only # Only fix lang attributes
97
- node cli.js --role-only # Only fix role attributes
122
+ node cli.js # Comprehensive fixes (default mode)
123
+ node cli.js --comprehensive # Comprehensive fixes (same as default)
124
+ node cli.js --alt-only # Fix alt attributes + cleanup
125
+ node cli.js --forms-only # Fix form labels + cleanup
126
+ node cli.js --buttons-only # Fix button names + cleanup
127
+ node cli.js --links-only # Fix link names + cleanup
128
+ node cli.js --landmarks-only # Fix landmarks + cleanup
129
+ node cli.js --headings-only # Analyze heading structure only
98
130
  node cli.js --cleanup-only # Only cleanup duplicate roles
99
- node cli.js ./src # Fix src directory
100
- node cli.js -l en --dry-run ./dist # Preview fixes for dist directory in English
101
- node cli.js --no-backup ./public # Fix without creating backups
131
+ node cli.js ./src # Fix src directory (comprehensive)
132
+ node cli.js -l en --dry-run ./dist # Preview comprehensive fixes in English
133
+ node cli.js --no-backup ./public # Comprehensive fixes without backups
102
134
 
103
135
  Features:
104
136
  ✅ Alt attributes for images
@@ -110,6 +142,23 @@ Features:
110
142
  process.exit(0);
111
143
  }
112
144
 
145
+
146
+ // Helper function to show completion message with backup info
147
+ function showCompletionMessage(options, mode = 'fixes') {
148
+ if (options.dryRun) {
149
+ console.log(chalk.cyan('\n💡 This was a dry run. Use without --dry-run to apply changes.'));
150
+ } else {
151
+ console.log(chalk.green(`\n🎉 ${mode} completed successfully!`));
152
+ if (options.backupFiles) {
153
+ console.log(chalk.gray(' 📁 Backup files created with .backup extension'));
154
+ console.log(chalk.gray(' 💡 Use --no-backup to disable backups in future runs'));
155
+ } else {
156
+ console.log(chalk.yellow(' ⚠️ No backup files created (--no-backup was used)'));
157
+ console.log(chalk.gray(' 💡 Use --backup to enable backups for safety'));
158
+ }
159
+ }
160
+ }
161
+
113
162
  // Main function
114
163
  async function main() {
115
164
  console.log(chalk.blue('🚀 Starting Accessibility Fixer...'));
@@ -126,14 +175,30 @@ async function main() {
126
175
  });
127
176
 
128
177
  try {
129
- // Handle different modes
130
- if (options.comprehensive) {
131
- // Run comprehensive fix (all fixes including cleanup)
178
+ // Handle different modes - All modes now include cleanup
179
+ if (options.cleanupOnly || options.altOnly || options.langOnly || options.roleOnly ||
180
+ options.formsOnly || options.buttonsOnly || options.linksOnly || options.landmarksOnly || options.headingsOnly) {
181
+ // Individual modes - handle each separately, then run cleanup
182
+ } else {
183
+ // Default mode: Run comprehensive fix (all fixes including cleanup)
132
184
  console.log(chalk.blue('🎯 Running comprehensive accessibility fixes...'));
133
185
  const results = await fixer.fixAllAccessibilityIssues(options.directory);
134
186
 
135
187
  // Results already logged in the method
136
188
  return;
189
+ }
190
+
191
+ // Individual modes
192
+ if (options.cleanupOnly) {
193
+ // Only cleanup duplicate roles
194
+ console.log(chalk.blue('🧹 Running cleanup for duplicate role attributes...'));
195
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
196
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
197
+
198
+ console.log(chalk.green(`\n✅ Cleaned duplicate roles in ${cleanupFixed} files`));
199
+
200
+ showCompletionMessage(options, 'Cleanup');
201
+ return;
137
202
 
138
203
  } else if (options.cleanupOnly) {
139
204
  // Only cleanup duplicate roles
@@ -143,117 +208,147 @@ async function main() {
143
208
 
144
209
  console.log(chalk.green(`\n✅ Cleaned duplicate roles in ${cleanupFixed} files`));
145
210
 
146
- if (options.dryRun) {
147
- console.log(chalk.cyan('\n💡 This was a dry run. Use without --dry-run to apply changes.'));
148
- } else {
149
- console.log(chalk.green('\n🎉 Cleanup completed successfully!'));
150
- }
211
+ showCompletionMessage(options, 'Cleanup');
151
212
  return;
152
213
 
153
214
  } else if (options.altOnly) {
154
- // Only fix alt attributes
155
- console.log(chalk.blue('🖼️ Running alt attribute fixes only...'));
215
+ // Fix alt attributes + cleanup
216
+ console.log(chalk.blue('🖼️ Running alt attribute fixes + cleanup...'));
156
217
  const altResults = await fixer.fixEmptyAltAttributes(options.directory);
157
218
  const altFixed = altResults.filter(r => r.status === 'fixed').length;
158
219
  const totalAltIssues = altResults.reduce((sum, r) => sum + (r.issues || 0), 0);
159
220
 
160
221
  console.log(chalk.green(`\n✅ Fixed alt attributes in ${altFixed} files (${totalAltIssues} issues)`));
161
222
 
162
- if (options.dryRun) {
163
- console.log(chalk.cyan('\n💡 This was a dry run. Use without --dry-run to apply changes.'));
164
- } else {
165
- console.log(chalk.green('\n🎉 Alt attribute fixes completed successfully!'));
166
- }
223
+ // Run cleanup
224
+ console.log(chalk.blue('\n🧹 Running cleanup for duplicate role attributes...'));
225
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
226
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
227
+ console.log(chalk.green(`✅ Cleaned duplicate roles in ${cleanupFixed} files`));
228
+
229
+ showCompletionMessage(options, 'Alt attribute fixes + cleanup');
167
230
  return;
168
231
 
169
232
  } else if (options.langOnly) {
170
- // Only fix lang attributes
171
- console.log(chalk.blue('📝 Running HTML lang attribute fixes only...'));
233
+ // Fix lang attributes + cleanup
234
+ console.log(chalk.blue('📝 Running HTML lang attribute fixes + cleanup...'));
172
235
  const langResults = await fixer.fixHtmlLang(options.directory);
173
236
  const langFixed = langResults.filter(r => r.status === 'fixed').length;
174
237
 
175
238
  console.log(chalk.green(`\n✅ Fixed lang attributes in ${langFixed} files`));
176
239
 
177
- if (options.dryRun) {
178
- console.log(chalk.cyan('\n💡 This was a dry run. Use without --dry-run to apply changes.'));
179
- } else {
180
- console.log(chalk.green('\n🎉 Lang attribute fixes completed successfully!'));
181
- }
240
+ // Run cleanup
241
+ console.log(chalk.blue('\n🧹 Running cleanup for duplicate role attributes...'));
242
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
243
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
244
+ console.log(chalk.green(`✅ Cleaned duplicate roles in ${cleanupFixed} files`));
245
+
246
+ showCompletionMessage(options, 'Lang attribute fixes + cleanup');
182
247
  return;
183
248
 
184
249
  } else if (options.roleOnly) {
185
- // Only fix role attributes
186
- console.log(chalk.blue('🎭 Running role attribute fixes only...'));
250
+ // Fix role attributes + cleanup
251
+ console.log(chalk.blue('🎭 Running role attribute fixes + cleanup...'));
187
252
  const roleResults = await fixer.fixRoleAttributes(options.directory);
188
253
  const roleFixed = roleResults.filter(r => r.status === 'fixed').length;
189
254
  const totalRoleIssues = roleResults.reduce((sum, r) => sum + (r.issues || 0), 0);
190
255
 
191
256
  console.log(chalk.green(`\n✅ Fixed role attributes in ${roleFixed} files (${totalRoleIssues} issues)`));
192
257
 
193
- if (options.dryRun) {
194
- console.log(chalk.cyan('\n💡 This was a dry run. Use without --dry-run to apply changes.'));
195
- } else {
196
- console.log(chalk.green('\n🎉 Role attribute fixes completed successfully!'));
197
- }
258
+ // Run cleanup
259
+ console.log(chalk.blue('\n🧹 Running cleanup for duplicate role attributes...'));
260
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
261
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
262
+ console.log(chalk.green(`✅ Cleaned duplicate roles in ${cleanupFixed} files`));
263
+
264
+ showCompletionMessage(options, 'Role attribute fixes + cleanup');
265
+ return;
266
+
267
+ } else if (options.formsOnly) {
268
+ // Fix form labels + cleanup
269
+ console.log(chalk.blue('📋 Running form label fixes + cleanup...'));
270
+ const formResults = await fixer.fixFormLabels(options.directory);
271
+ const formFixed = formResults.filter(r => r.status === 'fixed').length;
272
+ const totalFormIssues = formResults.reduce((sum, r) => sum + (r.issues || 0), 0);
273
+
274
+ console.log(chalk.green(`\n✅ Fixed form labels in ${formFixed} files (${totalFormIssues} issues)`));
275
+
276
+ // Run cleanup
277
+ console.log(chalk.blue('\n🧹 Running cleanup for duplicate role attributes...'));
278
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
279
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
280
+ console.log(chalk.green(`✅ Cleaned duplicate roles in ${cleanupFixed} files`));
281
+
282
+ showCompletionMessage(options, 'Form label fixes + cleanup');
283
+ return;
284
+
285
+ } else if (options.buttonsOnly) {
286
+ // Fix button names + cleanup
287
+ console.log(chalk.blue('🔘 Running button name fixes + cleanup...'));
288
+ const buttonResults = await fixer.fixButtonNames(options.directory);
289
+ const buttonFixed = buttonResults.filter(r => r.status === 'fixed').length;
290
+ const totalButtonIssues = buttonResults.reduce((sum, r) => sum + (r.issues || 0), 0);
291
+
292
+ console.log(chalk.green(`\n✅ Fixed button names in ${buttonFixed} files (${totalButtonIssues} issues)`));
293
+
294
+ // Run cleanup
295
+ console.log(chalk.blue('\n🧹 Running cleanup for duplicate role attributes...'));
296
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
297
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
298
+ console.log(chalk.green(`✅ Cleaned duplicate roles in ${cleanupFixed} files`));
299
+
300
+ showCompletionMessage(options, 'Button name fixes + cleanup');
301
+ return;
302
+
303
+ } else if (options.linksOnly) {
304
+ // Fix link names + cleanup
305
+ console.log(chalk.blue('🔗 Running link name fixes + cleanup...'));
306
+ const linkResults = await fixer.fixLinkNames(options.directory);
307
+ const linkFixed = linkResults.filter(r => r.status === 'fixed').length;
308
+ const totalLinkIssues = linkResults.reduce((sum, r) => sum + (r.issues || 0), 0);
309
+
310
+ console.log(chalk.green(`\n✅ Fixed link names in ${linkFixed} files (${totalLinkIssues} issues)`));
311
+
312
+ // Run cleanup
313
+ console.log(chalk.blue('\n🧹 Running cleanup for duplicate role attributes...'));
314
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
315
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
316
+ console.log(chalk.green(`✅ Cleaned duplicate roles in ${cleanupFixed} files`));
317
+
318
+ showCompletionMessage(options, 'Link name fixes + cleanup');
319
+ return;
320
+
321
+ } else if (options.landmarksOnly) {
322
+ // Fix landmarks + cleanup
323
+ console.log(chalk.blue('🏛️ Running landmark fixes + cleanup...'));
324
+ const landmarkResults = await fixer.fixLandmarks(options.directory);
325
+ const landmarkFixed = landmarkResults.filter(r => r.status === 'fixed').length;
326
+ const totalLandmarkIssues = landmarkResults.reduce((sum, r) => sum + (r.issues || 0), 0);
327
+
328
+ console.log(chalk.green(`\n✅ Fixed landmarks in ${landmarkFixed} files (${totalLandmarkIssues} issues)`));
329
+
330
+ // Run cleanup
331
+ console.log(chalk.blue('\n🧹 Running cleanup for duplicate role attributes...'));
332
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
333
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
334
+ console.log(chalk.green(`✅ Cleaned duplicate roles in ${cleanupFixed} files`));
335
+
336
+ showCompletionMessage(options, 'Landmark fixes + cleanup');
337
+ return;
338
+
339
+ } else if (options.headingsOnly) {
340
+ // Analyze headings only (no fixes, no cleanup)
341
+ console.log(chalk.blue('📑 Running heading analysis only...'));
342
+ const headingResults = await fixer.analyzeHeadings(options.directory);
343
+ const totalSuggestions = headingResults.reduce((sum, r) => sum + (r.issues || 0), 0);
344
+
345
+ console.log(chalk.green(`\n✅ Analyzed headings in ${headingResults.length} files (${totalSuggestions} suggestions)`));
346
+ console.log(chalk.gray('💡 Heading issues require manual review and cannot be auto-fixed'));
347
+
348
+ showCompletionMessage(options, 'Heading analysis');
198
349
  return;
199
350
  }
200
351
 
201
- // Standard mode - run individual fixes
202
- // Fix HTML lang attributes
203
- console.log(chalk.yellow('📝 Step 1: Fixing HTML lang attributes...'));
204
- const langResults = await fixer.fixHtmlLang(options.directory);
205
- const langFixed = langResults.filter(r => r.status === 'fixed').length;
206
- console.log(chalk.green(`✅ Fixed lang attributes in ${langFixed} files`));
207
- console.log('');
208
-
209
- // Fix alt attributes
210
- console.log(chalk.yellow('🖼️ Step 2: Fixing alt attributes...'));
211
- const altResults = await fixer.fixEmptyAltAttributes(options.directory);
212
- const altFixed = altResults.filter(r => r.status === 'fixed').length;
213
- const totalAltIssues = altResults.reduce((sum, r) => sum + (r.issues || 0), 0);
214
- console.log(chalk.green(`✅ Fixed alt attributes in ${altFixed} files (${totalAltIssues} issues)`));
215
- console.log('');
216
-
217
- // Fix role attributes
218
- console.log(chalk.yellow('🎭 Step 3: Fixing role attributes...'));
219
- const roleResults = await fixer.fixRoleAttributes(options.directory);
220
- const roleFixed = roleResults.filter(r => r.status === 'fixed').length;
221
- const totalRoleIssues = roleResults.reduce((sum, r) => sum + (r.issues || 0), 0);
222
- console.log(chalk.green(`✅ Fixed role attributes in ${roleFixed} files (${totalRoleIssues} issues)`));
223
- console.log('');
224
-
225
- // Summary
226
- const totalFiles = new Set([
227
- ...langResults.map(r => r.file),
228
- ...altResults.map(r => r.file),
229
- ...roleResults.map(r => r.file)
230
- ]).size;
231
-
232
- const totalFixed = new Set([
233
- ...langResults.filter(r => r.status === 'fixed').map(r => r.file),
234
- ...altResults.filter(r => r.status === 'fixed').map(r => r.file),
235
- ...roleResults.filter(r => r.status === 'fixed').map(r => r.file)
236
- ]).size;
237
-
238
- const totalIssues = totalAltIssues + totalRoleIssues + langFixed;
239
-
240
- console.log(chalk.blue('📊 Summary:'));
241
- console.log(chalk.white(` Total files scanned: ${totalFiles}`));
242
- console.log(chalk.green(` Files fixed: ${totalFixed}`));
243
- console.log(chalk.yellow(` Total issues resolved: ${totalIssues}`));
244
-
245
- if (options.dryRun) {
246
- console.log(chalk.cyan('\n💡 This was a dry run. Use without --dry-run to apply changes.'));
247
- } else {
248
- console.log(chalk.green('\n🎉 All accessibility fixes completed successfully!'));
249
- if (options.backupFiles) {
250
- console.log(chalk.gray(' Backup files created with .backup extension'));
251
- }
252
- }
253
-
254
- // Suggest cleanup if not comprehensive mode
255
- console.log(chalk.blue('\n💡 Pro tip: Use --comprehensive to include duplicate role cleanup!'));
256
-
257
352
  } catch (error) {
258
353
  console.error(chalk.red('❌ Error occurred:'), error.message);
259
354
  process.exit(1);
@@ -0,0 +1,44 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Advanced Accessibility Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>Advanced Accessibility Test</h1>
9
+
10
+ <!-- Form issues -->
11
+ <form>
12
+ <input type="text" placeholder="Name">
13
+ <input type="email" id="email">
14
+ <input type="password">
15
+ <input type="submit">
16
+ </form>
17
+
18
+ <!-- Button issues -->
19
+ <button></button>
20
+ <button onclick="alert('test')"></button>
21
+ <input type="button">
22
+
23
+ <!-- Link issues -->
24
+ <a href="/home"></a>
25
+ <a href="/more">Click here</a>
26
+ <a href="/read">Read more</a>
27
+ <a href="/image"><img src="icon.png"></a>
28
+
29
+ <!-- Heading issues -->
30
+ <h3>Skipped h2</h3>
31
+ <h1>Second h1</h1>
32
+ <h4></h4>
33
+
34
+ <!-- Landmark issues -->
35
+ <div class="content">
36
+ <p>Main content without landmark</p>
37
+ </div>
38
+
39
+ <ul class="navigation">
40
+ <li><a href="/home">Home</a></li>
41
+ <li><a href="/about">About</a></li>
42
+ </ul>
43
+ </body>
44
+ </html>
@@ -0,0 +1,44 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Advanced Accessibility Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>Advanced Accessibility Test</h1>
9
+
10
+ <!-- Form issues -->
11
+ <form>
12
+ <input type="text" placeholder="Name">
13
+ <input type="email" id="email">
14
+ <input type="password">
15
+ <input type="submit">
16
+ </form>
17
+
18
+ <!-- Button issues -->
19
+ <button></button>
20
+ <button onclick="alert('test')"></button>
21
+ <input type="button">
22
+
23
+ <!-- Link issues -->
24
+ <a href="/home"></a>
25
+ <a href="/more">Click here</a>
26
+ <a href="/read">Read more</a>
27
+ <a href="/image"><img src="icon.png"></a>
28
+
29
+ <!-- Heading issues -->
30
+ <h3>Skipped h2</h3>
31
+ <h1>Second h1</h1>
32
+ <h4></h4>
33
+
34
+ <!-- Landmark issues -->
35
+ <div class="content">
36
+ <p>Main content without landmark</p>
37
+ </div>
38
+
39
+ <ul class="navigation">
40
+ <li><a href="/home">Home</a></li>
41
+ <li><a href="/about">About</a></li>
42
+ </ul>
43
+ </body>
44
+ </html>
@@ -0,0 +1,32 @@
1
+ <!DOCTYPE html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Aria Label Test</title>
7
+ </head>
8
+ <body>
9
+ <h1>Aria Label Test Cases</h1>
10
+
11
+ <!-- Test case 1: Image with alt but no aria-label -->
12
+ <img src="test1.jpg" alt="Test image 1" role="img" aria-label="Test image 1">
13
+
14
+ <!-- Test case 2: Image with alt and existing aria-label (should not change) -->
15
+ <img src="test2.jpg" alt="Test image 2" aria-label="Custom label" role="img">
16
+
17
+ <!-- Test case 3: Image with empty alt (should not add aria-label) -->
18
+ <img src="test3.jpg" alt="" role="img">
19
+
20
+ <!-- Test case 4: Image without alt (should generate alt and aria-label) -->
21
+ <img src="logo.png" role="img">
22
+
23
+ <!-- Test case 5: Picture with role and img with alt -->
24
+ <picture>
25
+ <source srcset="responsive.webp" type="image/webp">
26
+ <img src="responsive.jpg" alt="Responsive image" role="img" aria-label="Responsive image">
27
+ </picture>
28
+
29
+ <!-- Test case 6: Image with role but no aria-label -->
30
+ <img src="test6.jpg" alt="Test image 6" role="img" aria-label="Test image 6">
31
+ </body>
32
+ </html>
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Backup Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>Backup Test File</h1>
9
+
10
+ <!-- This will be fixed -->
11
+ <img src="test.jpg" alt="Test image" role="img" aria-label="Test image">
12
+
13
+ <!-- This will also be fixed -->
14
+ <a href="/home" role="link">Home Link</a>
15
+
16
+ <p>This file is used to test backup functionality.</p>
17
+ </body>
18
+ </html>
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>No Backup Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>No Backup Test File</h1>
9
+
10
+ <img src="test2.jpg" alt="Test image 2" role="img" aria-label="Test image 2">
11
+ <a href="/about" role="link">About Link</a>
12
+ </body>
13
+ </html>
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Explicit Backup Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>Explicit Backup Test File</h1>
9
+
10
+ <img src="test3.jpg" alt="Test image 3" role="img" aria-label="Test image 3">
11
+ </body>
12
+ </html>
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Comprehensive Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>Comprehensive Test File</h1>
9
+
10
+ <!-- Missing alt -->
11
+ <img src="test.jpg">
12
+
13
+ <!-- Missing role -->
14
+ <a href="/home">Home</a>
15
+
16
+ <!-- Duplicate roles -->
17
+ <img src="dup.jpg" alt="Duplicate" role="img" role="img">
18
+
19
+ <p>This tests comprehensive mode as default.</p>
20
+ </body>
21
+ </html>
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Comprehensive Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>Comprehensive Test File</h1>
9
+
10
+ <!-- Missing alt -->
11
+ <img src="test.jpg">
12
+
13
+ <!-- Missing role -->
14
+ <a href="/home">Home</a>
15
+
16
+ <!-- Duplicate roles -->
17
+ <img src="dup.jpg" alt="Duplicate" role="img" role="img">
18
+
19
+ <p>This tests comprehensive mode as default.</p>
20
+ </body>
21
+ </html>