Tools for testing Angular applications and debugging browser-specific functionality, including element selection predicates, performance profiling, and testing infrastructure support.
Predicate functions for querying DebugElement instances in Angular tests, providing powerful element selection capabilities.
/**
* Predicates for use with DebugElement's query functions.
* Provides static methods for creating element selection predicates.
*/
class By {
/**
* Match all nodes in the debug tree
* @returns Predicate function that matches any DebugNode
*/
static all(): Predicate<DebugNode>;
/**
* Match elements by the given CSS selector
* @param selector - CSS selector string to match against elements
* @returns Predicate function that matches elements by CSS selector
*/
static css(selector: string): Predicate<DebugElement>;
/**
* Match nodes that have the given directive present
* @param type - The directive class to match
* @returns Predicate function that matches nodes with the specified directive
*/
static directive(type: Type<any>): Predicate<DebugNode>;
}Usage Examples:
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { By } from "@angular/platform-browser";
import { DebugElement } from "@angular/core";
describe('ComponentTest', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [MyComponent]
});
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
});
it('should find elements by CSS selector', () => {
// Find single element
const titleElement = fixture.debugElement.query(By.css('h1'));
expect(titleElement.nativeElement.textContent).toBe('Page Title');
// Find multiple elements
const buttons = fixture.debugElement.queryAll(By.css('button'));
expect(buttons.length).toBe(3);
// Find with complex selectors
const activeItems = fixture.debugElement.queryAll(By.css('.item.active'));
expect(activeItems.length).toBe(2);
});
it('should find elements by directive', () => {
// Find elements with specific directive
const routerLinks = fixture.debugElement.queryAll(By.directive(RouterLink));
expect(routerLinks.length).toBe(5);
// Check directive instance
const firstLink = routerLinks[0].injector.get(RouterLink);
expect(firstLink.routerLink).toBe('/home');
});
it('should find all debug nodes', () => {
const allNodes = fixture.debugElement.queryAll(By.all());
expect(allNodes.length).toBeGreaterThan(0);
// Filter nodes by custom criteria
const textNodes = allNodes.filter(node =>
node.nativeNode && node.nativeNode.nodeType === Node.TEXT_NODE
);
});
});Browser developer console integration for Angular application debugging and performance profiling.
/**
* Enabled Angular debug tools that are accessible via your browser's developer console.
* Adds 'ng' global object with debugging utilities.
* @param ref - Component reference to enable debugging for
* @returns The same component reference for chaining
*/
function enableDebugTools<T>(ref: ComponentRef<T>): ComponentRef<T>;
/**
* Disables Angular debug tools by removing the global 'ng' object.
*/
function disableDebugTools(): void;Usage Examples:
import { bootstrapApplication } from "@angular/platform-browser";
import { enableDebugTools } from "@angular/platform-browser";
import { ApplicationRef } from "@angular/core";
// Enable debug tools in development
bootstrapApplication(AppComponent).then(appRef => {
if (!environment.production) {
const componentRef = appRef.components[0];
enableDebugTools(componentRef);
}
});
// In browser console after enabling debug tools:
// ng.profiler.timeChangeDetection() // Profile change detection
// ng.probe($0) // Get component instance from selected element
// ng.coreTokens.ApplicationRef // Access core Angular servicesDebug Console Commands:
// Available in browser console after enableDebugTools()
// Performance profiling
ng.profiler.timeChangeDetection() // Measure change detection performance
ng.profiler.timeChangeDetection(10) // Run 10 cycles and measure
// Component inspection
ng.probe($0) // Get Angular component for selected element
ng.probe($0).componentInstance // Access component instance
ng.probe($0).injector // Access component injector
// Core services access
ng.coreTokens.ApplicationRef // Application reference
ng.coreTokens.NgZone // NgZone instanceProvides testability support for applications, enabling integration with testing frameworks like Protractor.
/**
* Returns a set of providers required to setup Testability for an application
* bootstrapped using the bootstrapApplication function. Enables testing with Protractor.
* @returns Array of providers for testability support
*/
function provideProtractorTestingSupport(): Provider[];Usage Examples:
import { bootstrapApplication } from "@angular/platform-browser";
import { provideProtractorTestingSupport } from "@angular/platform-browser";
// Add testability support for e2e testing
await bootstrapApplication(AppComponent, {
providers: [
provideProtractorTestingSupport(),
// other providers
]
});
// This enables Protractor to:
// - Wait for Angular to be stable before interacting with elements
// - Detect when async operations complete
// - Synchronize with Angular's zone for reliable testing// Custom testing utilities using By predicates
export class TestingUtils {
static findByTestId(fixture: ComponentFixture<any>, testId: string): DebugElement {
return fixture.debugElement.query(By.css(`[data-testid="${testId}"]`));
}
static findAllByTestId(fixture: ComponentFixture<any>, testId: string): DebugElement[] {
return fixture.debugElement.queryAll(By.css(`[data-testid="${testId}"]`));
}
static findByText(fixture: ComponentFixture<any>, text: string): DebugElement {
return fixture.debugElement.query(
By.css('*')
).query((element: DebugElement) =>
element.nativeElement.textContent?.trim() === text
);
}
static getComponentInstance<T>(
fixture: ComponentFixture<any>,
componentType: Type<T>
): T {
const debugElement = fixture.debugElement.query(By.directive(componentType));
return debugElement.componentInstance;
}
}
// Usage in tests
describe('Advanced Testing', () => {
let fixture: ComponentFixture<MyComponent>;
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
});
it('should use custom test utilities', () => {
const saveButton = TestingUtils.findByTestId(fixture, 'save-button');
expect(saveButton).toBeTruthy();
const childComponent = TestingUtils.getComponentInstance(fixture, ChildComponent);
expect(childComponent.property).toBe('expected value');
});
});/**
* Predicate function type for filtering DebugNode instances
*/
type Predicate<T> = (value: T) => boolean;Integration with Angular Testing:
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { By } from "@angular/platform-browser";
import { DebugElement, Component } from "@angular/core";
// Example test component
@Component({
template: `
<div class="container">
<h1 data-testid="title">{{title}}</h1>
<button class="primary" (click)="onClick()">Click me</button>
<app-child [input]="data"></app-child>
</div>
`
})
class TestComponent {
title = 'Test Component';
data = { value: 'test' };
onClick() {}
}
describe('TestComponent', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TestComponent, ChildComponent]
});
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should demonstrate various By predicates', () => {
// CSS selector queries
const container = fixture.debugElement.query(By.css('.container'));
const title = fixture.debugElement.query(By.css('[data-testid="title"]'));
const buttons = fixture.debugElement.queryAll(By.css('button'));
// Directive queries
const childComponents = fixture.debugElement.queryAll(By.directive(ChildComponent));
const childInstance = childComponents[0].componentInstance;
// Assertions
expect(container).toBeTruthy();
expect(title.nativeElement.textContent).toBe('Test Component');
expect(buttons.length).toBe(1);
expect(childInstance.input).toEqual({ value: 'test' });
});
});