or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bootstrap-platform.mddocument-management.mdevent-management.mdhydration.mdindex.mdsecurity-sanitization.mdtesting-debug.md
tile.json

testing-debug.mddocs/

Testing and Debug Utilities

Tools for testing Angular applications and debugging browser-specific functionality, including element selection predicates, performance profiling, and testing infrastructure support.

Capabilities

Debug Element Selection

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
    );
  });
});

Debug Tools

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 services

Debug 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 instance

Testing Infrastructure

Provides 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

Advanced Testing Patterns

// 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');
  });
});

Types

/**
 * 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' });
  });
});