@afixt/test-utils 2.0.0 → 2.0.1
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/package.json +1 -1
- package/src/stringUtils.js +35 -0
- package/test/stringUtils.test.js +60 -0
package/package.json
CHANGED
package/src/stringUtils.js
CHANGED
|
@@ -174,6 +174,40 @@ const stringUtils = (function () {
|
|
|
174
174
|
return (element.textContent || '').trim();
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Checks if an accessible name contains the visible text as a whole-word phrase.
|
|
179
|
+
* Prevents false positives where aria-label is a superset of visible text
|
|
180
|
+
* (e.g. "Report a Concern Opens in new window" contains "Report a Concern").
|
|
181
|
+
* Uses word-boundary matching to avoid partial matches
|
|
182
|
+
* (e.g. "Homepage" does NOT contain "Home" as a whole word).
|
|
183
|
+
* @param {string} accessibleName - The accessible name (e.g. aria-label value)
|
|
184
|
+
* @param {string} visibleText - The visible text content of the element
|
|
185
|
+
* @returns {boolean} True if the accessible name contains the visible text at word boundaries
|
|
186
|
+
*/
|
|
187
|
+
function containsVisibleText(accessibleName, visibleText) {
|
|
188
|
+
if (!accessibleName || !visibleText) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
const haystack = accessibleName.toLowerCase().replace(/\s+/g, ' ').trim();
|
|
192
|
+
const needle = visibleText.toLowerCase().replace(/\s+/g, ' ').trim();
|
|
193
|
+
if (!needle) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
const index = haystack.indexOf(needle);
|
|
197
|
+
if (index === -1) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
// Check word boundaries
|
|
201
|
+
if (index > 0 && /\w/.test(haystack.charAt(index - 1))) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
const endIndex = index + needle.length;
|
|
205
|
+
if (endIndex < haystack.length && /\w/.test(haystack.charAt(endIndex))) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
|
|
177
211
|
/**
|
|
178
212
|
* Checks if text contains a warning about new window/tab behavior.
|
|
179
213
|
* @param {string} text - The text to check
|
|
@@ -211,6 +245,7 @@ const stringUtils = (function () {
|
|
|
211
245
|
isGenericTitle,
|
|
212
246
|
isGenericLinkText,
|
|
213
247
|
getActualVisibleText,
|
|
248
|
+
containsVisibleText,
|
|
214
249
|
hasNewWindowWarning,
|
|
215
250
|
};
|
|
216
251
|
})();
|
package/test/stringUtils.test.js
CHANGED
|
@@ -436,6 +436,66 @@ describe('stringUtils', () => {
|
|
|
436
436
|
});
|
|
437
437
|
});
|
|
438
438
|
|
|
439
|
+
describe('containsVisibleText', () => {
|
|
440
|
+
it('should return true when accessible name exactly matches visible text', () => {
|
|
441
|
+
expect(stringUtils.containsVisibleText('Home', 'Home')).toBe(true);
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
it('should return true when accessible name is a superset of visible text', () => {
|
|
445
|
+
expect(
|
|
446
|
+
stringUtils.containsVisibleText(
|
|
447
|
+
'Report a Concern Opens in new window',
|
|
448
|
+
'Report a Concern'
|
|
449
|
+
)
|
|
450
|
+
).toBe(true);
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
it('should be case-insensitive', () => {
|
|
454
|
+
expect(stringUtils.containsVisibleText('REPORT A CONCERN', 'Report a Concern')).toBe(
|
|
455
|
+
true
|
|
456
|
+
);
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
it('should return false when visible text is a partial word match', () => {
|
|
460
|
+
expect(stringUtils.containsVisibleText('Homepage', 'Home')).toBe(false);
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
it('should return false when accessible name does not contain visible text', () => {
|
|
464
|
+
expect(
|
|
465
|
+
stringUtils.containsVisibleText('Click here for more information', 'Learn more')
|
|
466
|
+
).toBe(false);
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
it('should return false for null/undefined inputs', () => {
|
|
470
|
+
expect(stringUtils.containsVisibleText(null, 'text')).toBe(false);
|
|
471
|
+
expect(stringUtils.containsVisibleText('text', null)).toBe(false);
|
|
472
|
+
expect(stringUtils.containsVisibleText(undefined, undefined)).toBe(false);
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
it('should return false for empty visible text', () => {
|
|
476
|
+
expect(stringUtils.containsVisibleText('some name', '')).toBe(false);
|
|
477
|
+
expect(stringUtils.containsVisibleText('some name', ' ')).toBe(false);
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
it('should normalize whitespace before matching', () => {
|
|
481
|
+
expect(stringUtils.containsVisibleText('Report a Concern', 'Report a Concern')).toBe(
|
|
482
|
+
true
|
|
483
|
+
);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('should match visible text at the end of accessible name', () => {
|
|
487
|
+
expect(stringUtils.containsVisibleText('Click here to Search', 'Search')).toBe(true);
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
it('should not match across word boundaries at end', () => {
|
|
491
|
+
expect(stringUtils.containsVisibleText('Searching', 'Search')).toBe(false);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
it('should handle visible text that is the entire accessible name', () => {
|
|
495
|
+
expect(stringUtils.containsVisibleText('Buy now', 'Buy now')).toBe(true);
|
|
496
|
+
});
|
|
497
|
+
});
|
|
498
|
+
|
|
439
499
|
describe('hasNewWindowWarning', () => {
|
|
440
500
|
it('should return true for text containing "new window"', () => {
|
|
441
501
|
expect(stringUtils.hasNewWindowWarning('Opens in a new window')).toBe(true);
|