* DOM traversal fallback - look for text in ancestors/siblings * High recall: will find question text even without semantic markup
(element)
| 286 | * High recall: will find question text even without semantic markup |
| 287 | */ |
| 288 | function findNearbyLabelText(element) { |
| 289 | let parent = element.parentElement; |
| 290 | let depth = 0; |
| 291 | |
| 292 | while (parent && depth < 5) { |
| 293 | // Check preceding siblings for text blocks |
| 294 | let sibling = parent.previousElementSibling; |
| 295 | let siblingDepth = 0; |
| 296 | |
| 297 | while (sibling && siblingDepth < 3) { |
| 298 | const text = sibling.textContent?.trim(); |
| 299 | // Must be substantial text (> 10 chars), not just "Yes"/"No" |
| 300 | if (text && text.length > 10 && text.length < 500) { |
| 301 | // Verify it's not another form field |
| 302 | if (!sibling.querySelector('input, select, textarea, button')) { |
| 303 | return text; |
| 304 | } |
| 305 | } |
| 306 | sibling = sibling.previousElementSibling; |
| 307 | siblingDepth++; |
| 308 | } |
| 309 | |
| 310 | // Check parent's first child if it looks like a label |
| 311 | const firstChild = parent.firstElementChild; |
| 312 | if (firstChild && !firstChild.contains(element)) { |
| 313 | const text = firstChild.textContent?.trim(); |
| 314 | if (text && text.length > 10 && text.length < 500) { |
| 315 | if (!firstChild.querySelector('input, select, textarea, button')) { |
| 316 | return text; |
| 317 | } |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | parent = parent.parentElement; |
| 322 | depth++; |
| 323 | } |
| 324 | |
| 325 | return ''; |
| 326 | } |
| 327 | |
| 328 | // Element assertion helpers for QA testing - checking element existence, values, etc. |
| 329 | export class ElementAssertions { |
no outgoing calls
no test coverage detected