Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/aria/combobox/combobox.zone.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import {Component, computed, signal, provideZoneChangeDetection} from '@angular/core';
import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
import {Combobox} from './combobox';
import {ComboboxPopup} from './combobox-popup';
Expand Down Expand Up @@ -49,11 +49,11 @@ describe('Combobox Zone.js integration', () => {
return options.find(option => option.textContent?.trim() === text) || null;
}

it('should relay ArrowDown to the listbox and update active descendant', fakeAsync(() => {
it('should relay ArrowDown to the listbox and update active descendant', async () => {
// Open the popup (sets active descendant to Alabama via default state)
keydown('ArrowDown');
tick();
fixture.detectChanges();
await fixture.whenStable();

// Check if expanded is true
expect(inputElement.getAttribute('aria-expanded')).toBe('true');
Expand All @@ -63,12 +63,12 @@ describe('Combobox Zone.js integration', () => {

// Press ArrowDown again to move to Alaska
keydown('ArrowDown');
tick();
fixture.detectChanges();
await fixture.whenStable();

const alaska = getOption('Alaska')!;
expect(inputElement.getAttribute('aria-activedescendant')).toBe(alaska.id);
}));
});
});

@Component({
Expand Down
11 changes: 5 additions & 6 deletions src/cdk/bidi/directionality.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {waitForAsync, fakeAsync, TestBed, flush} from '@angular/core/testing';
import {waitForAsync, TestBed} from '@angular/core/testing';
import {Component, ViewChild, signal, inject, ChangeDetectionStrategy} from '@angular/core';
import {By} from '@angular/platform-browser';
import {BidiModule, Directionality, Dir, Direction, DIR_DOCUMENT} from './index';
Expand Down Expand Up @@ -78,7 +78,7 @@ describe('Directionality', () => {
expect(injectedDirectionality.value).toBe('rtl');
});

it('should emit a change event when the value changes', fakeAsync(() => {
it('should emit a change event when the value changes', () => {
const fixture = TestBed.createComponent(ElementWithDir);
const injectedDirectionality = fixture.debugElement.query(
By.directive(InjectsDirectionality),
Expand All @@ -102,9 +102,9 @@ describe('Directionality', () => {
expect(direction).toBe('ltr');
expect(injectedDirectionality.value).toBe('ltr');
expect(fixture.componentInstance.changeCount).toBe(1);
}));
});

it('should complete the change stream on destroy', fakeAsync(() => {
it('should complete the change stream on destroy', () => {
const fixture = TestBed.createComponent(ElementWithDir);
const dir = fixture.debugElement.query(By.directive(InjectsDirectionality))!.componentInstance
.dir;
Expand All @@ -114,8 +114,7 @@ describe('Directionality', () => {
fixture.destroy();
expect(spy).toHaveBeenCalled();
subscription.unsubscribe();
flush();
}));
});

it('should default to ltr if an invalid value is passed in', () => {
const fixture = TestBed.createComponent(ElementWithDir);
Expand Down
5 changes: 2 additions & 3 deletions src/cdk/coercion/private/observable.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {Observable, ReplaySubject} from 'rxjs';
import {coerceObservable} from './observable';
import {fakeAsync} from '@angular/core/testing';

describe('coerceObservable', () => {
it('should return the Observable, if an Observable is passed in', () => {
Expand All @@ -13,12 +12,12 @@ describe('coerceObservable', () => {
expect(coerceObservable(observable)).toBe(observable);
});

it('should wrap non-Observables in Observables', fakeAsync(() => {
it('should wrap non-Observables in Observables', () => {
const observable = coerceObservable(3);
let emittedValue = 0;
observable.subscribe(value => {
emittedValue = value;
});
expect(emittedValue).toBe(3);
}));
});
});
58 changes: 28 additions & 30 deletions src/cdk/listbox/listbox.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {A, B, DOWN_ARROW, END, HOME, LEFT_ARROW, RIGHT_ARROW, SPACE, UP_ARROW} from '../keycodes';
import {Component, Type, signal, ChangeDetectionStrategy} from '@angular/core';
import {TestBed, fakeAsync, tick} from '@angular/core/testing';
import {TestBed} from '@angular/core/testing';
import {FormControl, ReactiveFormsModule} from '@angular/forms';
import {By} from '@angular/platform-browser';
import {dispatchFakeEvent, dispatchKeyboardEvent, dispatchMouseEvent} from '../testing/private';
Expand All @@ -23,6 +23,10 @@ function setupComponent<T, O = string>(component: Type<T>) {
};
}

function wait(milliseconds: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}

describe('CdkOption and CdkListbox', () => {
describe('id', () => {
it('should generate unique ids', () => {
Expand Down Expand Up @@ -449,20 +453,18 @@ describe('CdkOption and CdkListbox', () => {
expect(fixture.componentInstance.changedOption).toBe(null);
});

it('should not handle type ahead on a disabled listbox', async (...args: unknown[]) => {
it('should not handle type ahead on a disabled listbox', async () => {
const {fixture, testComponent, listboxEl, options} = setupComponent(ListboxWithOptions);
await fakeAsync(() => {
testComponent.isListboxDisabled.set(true);
fixture.detectChanges();
testComponent.isListboxDisabled.set(true);
fixture.detectChanges();

dispatchKeyboardEvent(listboxEl, 'keydown', B);
fixture.detectChanges();
tick(200);
dispatchKeyboardEvent(listboxEl, 'keydown', B);
fixture.detectChanges();
await wait(200);

for (let option of options) {
expect(option.isActive()).toBeFalse();
}
})(args);
for (let option of options) {
expect(option.isActive()).toBeFalse();
}
});

it('should skip disabled options when navigating with arrow keys', () => {
Expand Down Expand Up @@ -561,32 +563,28 @@ describe('CdkOption and CdkListbox', () => {
expect(optionEls[0].classList).toContain('cdk-option-active');
});

it('should change active item using type ahead', async (...args: unknown[]) => {
it('should change active item using type ahead', async () => {
const {fixture, listbox, listboxEl, options} = setupComponent(ListboxWithOptions);
await fakeAsync(() => {
listbox.focus();
fixture.detectChanges();
listbox.focus();
fixture.detectChanges();

dispatchKeyboardEvent(listboxEl, 'keydown', B);
fixture.detectChanges();
tick(200);
dispatchKeyboardEvent(listboxEl, 'keydown', B);
fixture.detectChanges();
await wait(200);

expect(options[2].isActive()).toBeTrue();
})(args);
expect(options[2].isActive()).toBeTrue();
});

it('should allow custom type ahead label', async (...args: unknown[]) => {
it('should allow custom type ahead label', async () => {
const {fixture, listbox, listboxEl, options} = setupComponent(ListboxWithCustomTypeahead);
await fakeAsync(() => {
listbox.focus();
fixture.detectChanges();
listbox.focus();
fixture.detectChanges();

dispatchKeyboardEvent(listboxEl, 'keydown', B);
fixture.detectChanges();
tick(200);
dispatchKeyboardEvent(listboxEl, 'keydown', B);
fixture.detectChanges();
await wait(200);

expect(options[2].isActive()).toBeTrue();
})(args);
expect(options[2].isActive()).toBeTrue();
});

it('should focus and toggle the next item when pressing SHIFT + DOWN_ARROW', () => {
Expand Down
28 changes: 15 additions & 13 deletions src/cdk/text-field/autosize.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Component, ViewChild, ChangeDetectionStrategy} from '@angular/core';
import {ComponentFixture, TestBed, fakeAsync, flush, tick} from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {FormsModule} from '@angular/forms';
import {By} from '@angular/platform-browser';
import {dispatchFakeEvent} from '../testing/private';
Expand Down Expand Up @@ -264,7 +264,7 @@ describe('CdkTextareaAutosize', () => {
.toBe(textarea.scrollHeight);
});

it('should resize when an associated form control value changes', fakeAsync(() => {
it('should resize when an associated form control value changes', async () => {
const fixtureWithForms = TestBed.createComponent(AutosizeTextareaWithNgModel);
textarea = fixtureWithForms.nativeElement.querySelector('textarea');
fixtureWithForms.detectChanges();
Expand All @@ -280,15 +280,15 @@ describe('CdkTextareaAutosize', () => {
This it is and nothing more.” `;
fixtureWithForms.changeDetectorRef.markForCheck();
fixtureWithForms.detectChanges();
flush();
await wait(50);
fixtureWithForms.detectChanges();

expect(textarea.clientHeight)
.withContext('Expected increased height when ngModel is updated.')
.toBeGreaterThan(previousHeight);
}));
});

it('should resize when the textarea value is changed programmatically', fakeAsync(() => {
it('should resize when the textarea value is changed programmatically', () => {
const previousHeight = textarea.clientHeight;

textarea.value = `
Expand All @@ -298,24 +298,22 @@ describe('CdkTextareaAutosize', () => {

fixture.changeDetectorRef.markForCheck();
fixture.detectChanges();
flush();
fixture.detectChanges();

expect(textarea.clientHeight)
.withContext('Expected the textarea height to have increased.')
.toBeGreaterThan(previousHeight);
}));
});

it('should trigger a resize when the window is resized', fakeAsync(() => {
it('should trigger a resize when the window is resized', async () => {
spyOn(autosize, 'resizeToFitContent');

dispatchFakeEvent(window, 'resize');
tick(16);
await wait(100);

expect(autosize.resizeToFitContent).toHaveBeenCalled();
}));
});

it('should not trigger a resize when it is disabled', fakeAsync(() => {
it('should not trigger a resize when it is disabled', () => {
const fixtureWithoutAutosize = TestBed.createComponent(AutosizeTextareaWithoutAutosize);
textarea = fixtureWithoutAutosize.nativeElement.querySelector('textarea');
autosize = fixtureWithoutAutosize.debugElement
Expand Down Expand Up @@ -363,7 +361,7 @@ describe('CdkTextareaAutosize', () => {
expect(textarea.clientHeight)
.withContext('Expected textarea to have a scrollbar.')
.toBeLessThan(textarea.scrollHeight);
}));
});

it('should handle an undefined placeholder', () => {
fixture.componentInstance.placeholder = undefined!;
Expand All @@ -374,6 +372,10 @@ describe('CdkTextareaAutosize', () => {
});
});

function wait(milliseconds: number) {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}

// Styles to reset padding and border to make measurement comparisons easier.
const textareaStyleReset = `
textarea {
Expand Down
36 changes: 20 additions & 16 deletions src/cdk/tree/tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
signal,
ChangeDetectionStrategy,
} from '@angular/core';
import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {AsyncPipe} from '@angular/common';

import {BehaviorSubject, Observable, combineLatest, of} from 'rxjs';
Expand Down Expand Up @@ -1407,13 +1407,13 @@ describe('CdkTree', () => {
component = fixture.componentInstance;
});
describe(`when pressing 'b' with default configuration`, () => {
beforeEach(fakeAsync(() => {
beforeEach(async () => {
component.tree.nativeElement.dispatchEvent(
createKeyboardEvent('keydown', undefined, 'b'),
);
fixture.detectChanges();
tick(1000);
}));
await wait(1000);
});

it('focuses banana', () => {
expect(document.activeElement)
Expand All @@ -1435,35 +1435,35 @@ describe('CdkTree', () => {
});

describe(`when pressing 'b' with typeahead label binding`, () => {
beforeEach(fakeAsync(() => {
beforeEach(async () => {
component.tree.nativeElement.dispatchEvent(
createKeyboardEvent('keydown', undefined, 'b'),
);
fixture.detectChanges();
tick(1000);
}));
await wait(1000);
});

it('focuses banana', fakeAsync(() => {
it('focuses banana', async () => {
component.tree.nativeElement.dispatchEvent(
createKeyboardEvent('keydown', undefined, 'b'),
);
fixture.detectChanges();
tick(1000);
await wait(1000);

expect(document.activeElement)
.withContext('expecting banana to be focused')
.toBe(component.treeNodes.get(1)?.nativeElement!);
}));
});
});

describe(`when pressing 'c'`, () => {
beforeEach(fakeAsync(() => {
beforeEach(async () => {
component.tree.nativeElement.dispatchEvent(
createKeyboardEvent('keydown', undefined, 'c'),
);
fixture.detectChanges();
tick(1000);
}));
await wait(1000);
});
it('does not move focus', () => {
expect(document.activeElement)
.withContext('expecting document body to be focused')
Expand All @@ -1472,13 +1472,13 @@ describe('CdkTree', () => {
});

describe(`when pressing 't'`, () => {
beforeEach(fakeAsync(() => {
beforeEach(async () => {
component.tree.nativeElement.dispatchEvent(
createKeyboardEvent('keydown', undefined, 't'),
);
fixture.detectChanges();
tick(1000);
}));
await wait(1000);
});
it('focuses focuses cherry', () => {
expect(document.activeElement)
.withContext('expecting cherry to be focused')
Expand Down Expand Up @@ -1632,6 +1632,10 @@ function getExpandedNodes<T>(nodes: T[] | undefined, tree: CdkTree<T>): T[] {
return nodes?.filter(node => tree.isExpanded(node)) ?? [];
}

function wait(milliseconds: number) {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}

function expectFlatTreeToMatch(
treeElement: Element,
expectedPaddingIndent = 28,
Expand Down
Loading