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.