Skip to main content

Testing

It Is Wise to Perform Accessibility Tests During Integration Testing

Performing accessibility (a11y) tests during integration testing provides a more complete and reliable validation of how users experience the real application.

Full Screen Rendering Enables Accurate Testing​

When running accessibility checks at the integration-test level, the entire screen is rendered. This ensures:

  • All UI sections are present and loaded.
  • Heading hierarchy (H1, H2, H3) is validated in its full context.
  • Landmark roles (e.g., main, nav, header, footer) can be tested consistently.
  • Dynamic content, routing, and lazy-loaded modules are visible to the test framework.

By contrast, testing only at the component level can hide structural issues because:

  • Components are often tested in isolation without real layout.
  • Heading order may appear correct inside a component but becomes incorrect when combined with other components.
  • Duplicate IDs or missing ARIA labels only show up in integrated views.

Example​

A component may contain an <h1> tag, which seems fine in isolation. But in the full view, another component might also contain an <h1>, resulting in multiple H1 headings, which is invalid for accessibility.

Integration testing would detect this (component testing would not).

Common Accessibility Issues in Angular and How to Avoid Them​

Incorrect Heading Hierarchy​

Problem: Components each define their own headings, unaware of the page structure.

Prevention: - Define heading levels at the page/screen level. - Pass heading level as an @Input() so components can adapt.

@Component({
selector: 'app-section-title',
template: '<h{{ level }}>{{ title }}</h{{ level }}>',
})
export class SectionTitleComponent {
@Input() level = 2;
@Input() title = '';
}

Missing or Incorrect ARIA Labels​

Problem: Inputs, buttons, or icons without textual labels.

Prevention: - Use Angular Material components where possible --- they include many ARIA attributes out of the box. - For icon-only buttons, add aria-label:

<button aria-label="Open settings">
<mat-icon>settings</mat-icon>
</button>

Improper Focus Management After Navigation​

Problem: Focus stays in the wrong place after route changes, harming keyboard users.

Prevention: - Use Angular's cdkFocusInitial and cdkFocusRegionStart. - Programmatically set focus on page load:

constructor(private focus: FocusMonitor, private el: ElementRef) {}

ngAfterViewInit() {
this.el.nativeElement.querySelector('h1')?.focus();
}

Low Color Contrast​

Problem: CSS that does not meet WCAG contrast ratios.

Prevention: - Use a design system with validated contrast. - Run automated contrast checks in integration tests using tools like axe-core.

Elements Not Keyboard Accessible​

Problem: Custom controls without proper keyboard events.

Prevention: - Pair keydown.enter and keydown.space with click handlers:

<div role="button" tabindex="0"
(click)="open()"
(keydown.enter)="open()"
(keydown.space)="open()">
Open panel
</div>

Why Integration Testing Catches These Issues​

Integration tests allow accessibility tooling to analyze:

  • Full DOM structure
  • Real routing and screen transitions
  • Combined headings and landmarks
  • Real user interactions
  • Live ARIA attributes

These give a much more accurate representation of what a user experiences.

Summary​

Testing accessibility at the (integration-test level) ensures your Angular application:

  • Renders the full, real UI structure.
  • Enforces the correct heading hierarchy.
  • Avoids duplicate IDs and missing ARIA labels.
  • Validates dynamic content and navigation.
  • Produces a more inclusive and compliant user experience.