Parent
#576
What to build
Decide and implement how the listbox component should resolve its view children, which are currently unreachable, then un-skip the tests parked on the defect.
listbox.component.html wraps its entire body in <ng-container *ngTemplateOutlet="listTemplate">. Three @ViewChild(..., { static: true }) queries — srOnly, checkboxList/checkboxListElement, and FieldsetWrapper — target nodes that only exist inside that embedded view. Static queries resolve before ngOnInit and never see content created by an outlet, so all three are permanently undefined.
This is not only a test-observability problem. srOnly is guarded before use, but checkboxListElement.nativeElement is dereferenced unguarded in the screen-reader announcement path and in the arrow-key scroll handling, so those paths throw as soon as they are reached. Four it.skip tests in listbox.component.spec.ts are parked on exactly this behavior ("should disable", arrow up/down keypresses, and the two boundary cases).
This slice is HITL: the fix is a design decision, not a mechanical change. Options to weigh — hoist the markup out of the *ngTemplateOutlet so the queries resolve normally; switch the queries to non-static and add guards or ngAfterViewInit handling; or restructure so the template is projected rather than outlet-rendered. *ngTemplateOutlet here appears to be indirection with no consumer-facing purpose, so removing it is worth considering first, but it needs a look at whether anything depends on the current structure. Whichever route is chosen, note it on this issue before implementing.
Out of scope for the earlier spec PRs by design — #660 deliberately left this alone and called it out as a deeper architectural issue.
Acceptance criteria
Blocked by
None - can start immediately
Parent
#576
What to build
Decide and implement how the listbox component should resolve its view children, which are currently unreachable, then un-skip the tests parked on the defect.
listbox.component.htmlwraps its entire body in<ng-container *ngTemplateOutlet="listTemplate">. Three@ViewChild(..., { static: true })queries —srOnly,checkboxList/checkboxListElement, andFieldsetWrapper— target nodes that only exist inside that embedded view. Static queries resolve beforengOnInitand never see content created by an outlet, so all three are permanentlyundefined.This is not only a test-observability problem.
srOnlyis guarded before use, butcheckboxListElement.nativeElementis dereferenced unguarded in the screen-reader announcement path and in the arrow-key scroll handling, so those paths throw as soon as they are reached. Fourit.skiptests inlistbox.component.spec.tsare parked on exactly this behavior ("should disable", arrow up/down keypresses, and the two boundary cases).This slice is HITL: the fix is a design decision, not a mechanical change. Options to weigh — hoist the markup out of the
*ngTemplateOutletso the queries resolve normally; switch the queries to non-static and add guards orngAfterViewInithandling; or restructure so the template is projected rather than outlet-rendered.*ngTemplateOutlethere appears to be indirection with no consumer-facing purpose, so removing it is worth considering first, but it needs a look at whether anything depends on the current structure. Whichever route is chosen, note it on this issue before implementing.Out of scope for the earlier spec PRs by design — #660 deliberately left this alone and called it out as a deeper architectural issue.
Acceptance criteria
it.skiptests inlistbox.component.spec.tsare un-skipped and pass unmodified, or their assertions are updated with a note explaining why the original expectation was wrongnpm run coverage:check,npm run lint,npm run format:check, and thetest-appbuild all pass;coverage-floor.jsonis not modified (see AGENTS.md — floor bumps land via Lock coverage-floor gate at 90% QASP target (epic top-off) #637)Blocked by
None - can start immediately