From e65578663dab8d15cb6238865832becd50a3bfd0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 09:01:38 +0000 Subject: [PATCH 1/6] Initial plan From 8bbe7d566faaf61c281f5e34b83a1a52c2acd3db Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 09:33:35 +0000 Subject: [PATCH 2/6] fix: replace afterNextRender with setTimeout and add tick() to tests Co-authored-by: wnvko <5990334+wnvko@users.noreply.github.com> --- .../src/lib/combo/combo.component.spec.ts | 27 ++++++++++ .../src/lib/dialog/dialog.component.spec.ts | 2 + .../autocomplete.directive.spec.ts | 2 + .../toggle/toggle.directive.spec.ts | 1 + .../lib/directives/toggle/toggle.directive.ts | 50 +++++++++---------- .../lib/drop-down/drop-down.component.spec.ts | 10 ++++ .../src/lib/grids/grid/column-pinning.spec.ts | 4 +- .../src/lib/grids/grid/grid-add-row.spec.ts | 3 ++ .../grid/grid-filtering-advanced.spec.ts | 1 + .../lib/grids/grid/grid-filtering-ui.spec.ts | 34 +++++++++++++ .../lib/grids/grid/grid-row-editing.spec.ts | 1 + .../lib/grids/grid/grid.master-detail.spec.ts | 1 + .../hierarchical-grid.integration.spec.ts | 2 + .../hierarchical-grid.navigation.spec.ts | 3 +- .../hierarchical-grid.selection.spec.ts | 1 + .../hierarchical-grid.spec.ts | 1 + .../lib/grids/pivot-grid/pivot-grid.spec.ts | 7 +++ .../query-builder.component.spec.ts | 9 ++++ .../src/lib/select/select.component.spec.ts | 12 +++++ .../simple-combo.component.spec.ts | 10 ++++ .../src/lib/test-utils/grid-functions.spec.ts | 1 + .../time-picker/time-picker.component.spec.ts | 6 +++ 22 files changed, 159 insertions(+), 29 deletions(-) diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index 5345bc34424..f65b8a52f9b 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -1098,6 +1098,7 @@ describe('igxCombo', () => { })); it('should render placeholder values for inputs properly', () => { combo.toggle(); + tick(); fixture.detectChanges(); expect(combo.collapsed).toBeFalsy(); expect(combo.placeholder).toEqual('Location'); @@ -1168,6 +1169,7 @@ describe('igxCombo', () => { let scrollIndex = 0; const headers: Array = Array.from(new Set(combo.data.map(item => item.region))); combo.toggle(); + tick(); fixture.detectChanges(); const checkGroupedItemsClass = () => { fixture.detectChanges(); @@ -1194,6 +1196,7 @@ describe('igxCombo', () => { }); it('should render selected items properly', () => { combo.toggle(); + tick(); fixture.detectChanges(); const dropdownList = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROPDOWNLIST_SCROLL}`)).nativeElement; @@ -1215,6 +1218,7 @@ describe('igxCombo', () => { it('should render focused items properly', () => { const dropdown = combo.dropdown; combo.toggle(); + tick(); fixture.detectChanges(); dropdown.navigateItem(2); // Componenent is virtualized, so this will focus the ACTUAL 3rd item @@ -1267,6 +1271,7 @@ describe('igxCombo', () => { expect(headerElement).toBeNull(); expect(footerElement).toBeNull(); combo.toggle(); + tick(); fixture.detectChanges(); expect(combo.headerTemplate).toBeDefined(); expect(combo.footerTemplate).toBeDefined(); @@ -1286,12 +1291,14 @@ describe('igxCombo', () => { combo.showSearchCaseIcon = true; fixture.detectChanges(); combo.toggle(); + tick(); fixture.detectChanges(); let caseSensitiveIcon = fixture.debugElement.query(By.css('igx-icon[name=\'case-sensitive\']')); expect(caseSensitiveIcon).toBeDefined(); combo.toggle(); + tick(); fixture.detectChanges(); combo.showSearchCaseIcon = false; fixture.detectChanges(); @@ -1485,6 +1492,7 @@ describe('igxCombo', () => { }; combo.toggle(); + tick(); fixture.detectChanges(); verifyComboData(); expect(combo.virtualizationState.startIndex).toEqual(productIndex); @@ -1865,6 +1873,7 @@ describe('igxCombo', () => { it('should select/focus dropdown list items with space/up and down arrow keys', () => { let selectedItemsCount = 0; combo.toggle(); + tick(); fixture.detectChanges(); const dropdownList = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROPDOWNLIST_SCROLL}`)).nativeElement; @@ -1910,6 +1919,7 @@ describe('igxCombo', () => { it('should properly navigate using HOME/END key', (async () => { let firstVisibleItem: Element; combo.toggle(); + tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); const scrollbar = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLLBAR_VERTICAL}`)).nativeElement as HTMLElement; @@ -1946,6 +1956,7 @@ describe('igxCombo', () => { })); it('should close the dropdown list on pressing Tab key', fakeAsync(() => { combo.toggle(); + tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1963,6 +1974,7 @@ describe('igxCombo', () => { input = fixture.debugElement.query(By.css(`.${CSS_CLASS_INPUTGROUP}`)); let firstVisibleItem: Element; combo.toggle(); + tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); const scrollbar = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLLBAR_VERTICAL}`)) @@ -2053,6 +2065,7 @@ describe('igxCombo', () => { }); it('should display vertical scrollbar properly', () => { combo.toggle(); + tick(); fixture.detectChanges(); const scrollbarContainer = fixture.debugElement .query(By.css(`.${CSS_CLASS_SCROLLBAR_VERTICAL}`)) @@ -2063,12 +2076,14 @@ describe('igxCombo', () => { combo.data = [{ field: 'Mid-Atlantic', region: 'New Jersey' }, { field: 'Mid-Atlantic', region: 'New York' }]; fixture.detectChanges(); combo.toggle(); + tick(); fixture.detectChanges(); hasScrollbar = scrollbarContainer.scrollHeight > scrollbarContainer.clientHeight; expect(hasScrollbar).toBeFalsy(); }); it('should preserve selection on scrolling', async () => { combo.toggle(); + tick(); fixture.detectChanges(); const scrollbar = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLLBAR_VERTICAL}`)).nativeElement as HTMLElement; expect(scrollbar.scrollTop).toEqual(0); @@ -2302,6 +2317,7 @@ describe('igxCombo', () => { it('should clear the selection on Enter of the focused clear icon', () => { const selectedItem_1 = combo.dropdown.items[1]; combo.toggle(); + tick(); fixture.detectChanges(); simulateComboItemClick(1); expect(combo.selection[0]).toEqual(selectedItem_1.value); @@ -2317,6 +2333,7 @@ describe('igxCombo', () => { it('should not be able to select group header', () => { spyOn(combo.selectionChanging, 'emit').and.callThrough(); combo.toggle(); + tick(); fixture.detectChanges(); simulateComboItemClick(0, true); @@ -2481,6 +2498,7 @@ describe('igxCombo', () => { it('should prevent selection when selectionChanging is cancelled', () => { spyOn(combo.selectionChanging, 'emit').and.callFake((event: IComboSelectionChangingEventArgs) => event.cancel = true); combo.toggle(); + tick(); fixture.detectChanges(); const dropdownFirstItem = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[0].nativeElement; @@ -2642,6 +2660,7 @@ describe('igxCombo', () => { it('should properly add items to the defaultFallbackGroup', () => { combo.allowCustomValues = true; combo.toggle(); + tick(); fixture.detectChanges(); const fallBackGroup = combo.defaultFallbackGroup; const initialDataLength = combo.data.length + 0; @@ -2663,6 +2682,7 @@ describe('igxCombo', () => { it('should sort groups correctly', () => { combo.groupSortingDirection = SortingDirection.Asc; combo.toggle(); + tick(); fixture.detectChanges(); expect(combo.dropdown.headers[0].element.nativeElement.innerText).toEqual('East North Central'); @@ -2847,6 +2867,7 @@ describe('igxCombo', () => { combo.filteringOptions = { caseSensitive: false, filteringKey: undefined }; combo.data = ['José', 'Óscar', 'Ángel', 'Germán', 'Niño', 'México', 'Méxícó', 'Mexico', 'Köln', 'München']; combo.toggle(); + tick(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(`input[name="searchInput"]`)); @@ -2878,6 +2899,7 @@ describe('igxCombo', () => { }; combo.toggle(); + tick(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css('input[name=\'searchInput\']')); const verifyFilteredItems = (inputValue: string, expectedItemsNumber) => { @@ -2903,6 +2925,7 @@ describe('igxCombo', () => { let dropDownContainer: HTMLElement; let listItems; combo.toggle(); + tick(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); @@ -2966,6 +2989,7 @@ describe('igxCombo', () => { }); it('should clear the search input and close the dropdown list on pressing ESC key', fakeAsync(() => { combo.toggle(); + tick(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); @@ -2989,6 +3013,7 @@ describe('igxCombo', () => { return filteredArray; }, {}); combo.toggle(); + tick(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); UIInteractions.triggerInputEvent(searchInput, 'Mi'); @@ -3003,6 +3028,7 @@ describe('igxCombo', () => { combo.allowCustomValues = true; fixture.detectChanges(); combo.toggle(); + tick(); fixture.detectChanges(); expect(combo.selection).toEqual([]); expect(combo.displayValue).toEqual(''); @@ -3148,6 +3174,7 @@ describe('igxCombo', () => { expect(combo.isAddButtonVisible()).toEqual(false); combo.toggle(); + tick(); fixture.detectChanges(); expect(combo.collapsed).toEqual(false); expect(combo.searchInput.nativeElement.placeholder).toEqual('Add Item'); diff --git a/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts b/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts index 8b32c55e33c..5ac9eb1441f 100644 --- a/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts +++ b/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts @@ -182,6 +182,7 @@ describe('Dialog', () => { const dialog = fixture.componentInstance.dialog; dialog.open(); + tick(); fixture.detectChanges(); const dialogWindow = fixture.debugElement.query(By.css('.igx-dialog__window')); @@ -367,6 +368,7 @@ describe('Dialog', () => { const dialog = fixture.componentInstance.dialog; dialog.open(); + tick(); fixture.detectChanges(); const dialogWindow = fixture.debugElement.query(By.css('.igx-dialog__window')); diff --git a/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts index 882f7c6ac61..85d20d550a3 100644 --- a/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts @@ -304,6 +304,7 @@ describe('IgxAutocomplete', () => { }); it('Should not open dropdown on input clicking', () => { input.nativeElement.click(); + tick(); fixture.detectChanges(); expect(dropDown.collapsed).toBeTruthy(); const dropdownList = fixture.debugElement.query(By.css('.' + CSS_CLASS_DROPDOWNLIST)); @@ -326,6 +327,7 @@ describe('IgxAutocomplete', () => { expect(autocomplete.target.open).toHaveBeenCalledTimes(0); autocomplete.open(); + tick(); fixture.detectChanges(); expect(dropDown.collapsed).toBeTruthy(); expect(dropdownListScrollElement.children.length).toEqual(0); diff --git a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts index 8180148ca75..6c23c4d4b36 100644 --- a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts @@ -340,6 +340,7 @@ describe('IgxToggle', () => { button = fixture.componentInstance.button2.nativeElement; button.click(); + tick(); fixture.detectChanges(); toggle = fixture.debugElement.query(By.css('#toggle2')); diff --git a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts index 0c0bd8405c0..6f50abe6b31 100644 --- a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts @@ -1,19 +1,15 @@ import { - afterNextRender, ChangeDetectorRef, Directive, ElementRef, EventEmitter, HostListener, - inject, Inject, - Injector, Input, OnDestroy, OnInit, Optional, - Output, - runInInjectionContext + Output } from '@angular/core'; import { AbsoluteScrollStrategy } from '../../services/overlay/scroll/absolute-scroll-strategy'; import { CancelableBrowserEventArgs, IBaseEventArgs, PlatformUtil } from '../../core/utils'; @@ -201,7 +197,6 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy { private _overlayClosingSub: Subscription; private _overlayClosedSub: Subscription; private _overlayContentAppendedSub: Subscription; - private _injector = inject(Injector); /** * @hidden @@ -233,28 +228,29 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy { } this._collapsed = false; + this.cdr.detectChanges(); - runInInjectionContext(this._injector, () =>{ - afterNextRender(() => { - if (!info) { - this.unsubscribe(); - this.subscribe(); - this._overlayId = this.overlayService.attach(this.elementRef, overlaySettings); - } - - const args: ToggleViewCancelableEventArgs = { cancel: false, owner: this, id: this._overlayId }; - this.opening.emit(args); - if (args.cancel) { - this.unsubscribe(); - this.overlayService.detach(this._overlayId); - this._collapsed = true; - delete this._overlayId; - this.cdr.detectChanges(); - return; - } - this.overlayService.show(this._overlayId, overlaySettings); - }); - }); + // Use setTimeout to defer to next task, allowing host bindings to update + // This works in both production and test environments (with tick() in fakeAsync) + setTimeout(() => { + if (!info) { + this.unsubscribe(); + this.subscribe(); + this._overlayId = this.overlayService.attach(this.elementRef, overlaySettings); + } + + const args: ToggleViewCancelableEventArgs = { cancel: false, owner: this, id: this._overlayId }; + this.opening.emit(args); + if (args.cancel) { + this.unsubscribe(); + this.overlayService.detach(this._overlayId); + this._collapsed = true; + delete this._overlayId; + this.cdr.detectChanges(); + return; + } + this.overlayService.show(this._overlayId, overlaySettings); + }, 0); } /** diff --git a/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts b/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts index 929857abe5d..17a8337befb 100644 --- a/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts +++ b/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts @@ -239,6 +239,7 @@ describe('IgxDropDown ', () => { spyOn(toggle, 'open').and.callThrough(); dropdown.open(); + tick(); fixture.detectChanges(); expect(toggle.open).toHaveBeenCalledTimes(1); @@ -852,6 +853,7 @@ describe('IgxDropDown ', () => { fixture.detectChanges(); dropdown.open(); + tick(); fixture.detectChanges(); const itemToClick = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_ITEM}`))[0]; @@ -943,6 +945,7 @@ describe('IgxDropDown ', () => { }); it('should properly scroll when virtualized', async () => { dropdown.toggle(); + tick(); fixture.detectChanges(); await wait(50); let firstItemElement = fixture.componentInstance.dropdownItems.first.element.nativeElement; @@ -960,6 +963,7 @@ describe('IgxDropDown ', () => { xit('Should properly handle keyboard navigation when virtualized', async () => { pending('does not have time to focus last item on navigateLast()'); // dropdown.toggle(); + tick(); // fixture.detectChanges(); // dropdown.navigateFirst(); // expect(scroll.state.startIndex).toEqual(0); @@ -1051,6 +1055,7 @@ describe('IgxDropDown ', () => { it('should set the aria-label property correctly', () => { // Initially aria-label should be null dropdown.toggle(); + tick(); fixture.detectChanges(); let items = document.querySelectorAll(`.${CSS_CLASS_ITEM}`); items.forEach(item => { @@ -1059,9 +1064,11 @@ describe('IgxDropDown ', () => { // Set value and check if aria-label reflects it dropdown.toggle(); + tick(); fixture.detectChanges(); dropdown.items.forEach((item, index) => item.value = `value ${index}`); dropdown.toggle(); + tick(); fixture.detectChanges(); items = document.querySelectorAll(`.${CSS_CLASS_ITEM}`); items.forEach((item, index) => { @@ -1127,6 +1134,7 @@ describe('IgxDropDown ', () => { const groups = fixture.componentInstance.groups; expect(dropdown.collapsed).toBeTruthy(); dropdown.toggle(); + tick(); fixture.detectChanges(); const groupItems = document.querySelectorAll(`.${CSS_CLASS_GROUP_ITEM}`); for (let i = 0; i < groupItems.length; i++) { @@ -1246,6 +1254,7 @@ describe('IgxDropDown ', () => { fixture.componentInstance.maxHeight = '100px'; fixture.detectChanges(); dropdown.toggle(); + tick(); fixture.detectChanges(); const ddList = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLL}`)).nativeElement; expect(parseInt(ddList.style.maxHeight, 10)).toEqual(ddList.offsetHeight); @@ -1255,6 +1264,7 @@ describe('IgxDropDown ', () => { fixture.componentInstance.maxHeight = '700px'; fixture.detectChanges(); dropdown.toggle(); + tick(); fixture.detectChanges(); const ddList = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLL}`)).nativeElement; expect(parseInt(ddList.style.maxHeight, 10)).toBeGreaterThan(ddList.offsetHeight); diff --git a/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts index ba56c6e63ca..016a3bcdc86 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts @@ -1,6 +1,6 @@ import { DebugElement } from '@angular/core'; -import { TestBed, waitForAsync, ComponentFixture } from '@angular/core/testing'; +import { TestBed, waitForAsync, ComponentFixture , tick } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { IgxGridComponent } from './grid.component'; import { @@ -253,6 +253,7 @@ describe('Column Pinning UI #grid', () => { const pinningUIButton = GridFunctions.getColumnPinningButton(fix); pinningUIButton.click(); + tick(); fix.detectChanges(); expect(GridFunctions.getOverlay(fix).querySelectorAll('igx-checkbox').length).toEqual(5); @@ -261,6 +262,7 @@ describe('Column Pinning UI #grid', () => { fix.detectChanges(); pinningUIButton.click(); + tick(); fix.detectChanges(); expect(GridFunctions.getOverlay(fix).querySelectorAll('igx-checkbox').length).toEqual(4); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-add-row.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-add-row.spec.ts index c04441e4637..07ce10386ff 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-add-row.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-add-row.spec.ts @@ -552,6 +552,7 @@ describe('IgxGrid - Row Adding #grid', () => { const doneButtonElement = GridFunctions.getRowEditingDoneButton(fixture); doneButtonElement.click(); + tick(); fixture.detectChanges(); newRow = grid.gridAPI.get_row_by_index(1); @@ -572,6 +573,7 @@ describe('IgxGrid - Row Adding #grid', () => { const cancelButtonElement = GridFunctions.getRowEditingCancelButton(fixture); cancelButtonElement.click(); + tick(); fixture.detectChanges(); await wait(100); fixture.detectChanges(); @@ -635,6 +637,7 @@ describe('IgxGrid - Row Adding #grid', () => { const cancelButtonElement = GridFunctions.getRowEditingCancelButton(fixture); cancelButtonElement.click(); + tick(); fixture.detectChanges(); await wait(100); fixture.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts index 285ae6e7bd1..e9383985950 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts @@ -719,6 +719,7 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => { // Click the 'add condition' button. const addCondButton = QueryBuilderFunctions.getQueryBuilderTreeRootGroupButtons(fix, 0)[0] as HTMLElement; addCondButton.click(); + tick(); fix.detectChanges(); // Verify the edit mode container (the one with the editing inputs) is in view. diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts index 1841cfe1279..53fa1c6545d 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts @@ -739,10 +739,12 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { let filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); let close = filterUIRow.queryAll(By.css('button'))[1]; close.nativeElement.click(); + tick(); fix.detectChanges(); // open for number numberCellChip.nativeElement.click(); + tick(); fix.detectChanges(); checkUIForType('number', fix.debugElement); @@ -750,10 +752,12 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); close = filterUIRow.queryAll(By.css('button'))[1]; close.nativeElement.click(); + tick(); fix.detectChanges(); // open for date dateCellChip.nativeElement.click(); + tick(); fix.detectChanges(); checkUIForType('date', fix.debugElement); @@ -761,10 +765,12 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); close = filterUIRow.queryAll(By.css('button'))[1]; close.nativeElement.click(); + tick(); fix.detectChanges(); // open for bool boolCellChip.nativeElement.click(); + tick(); fix.detectChanges(); checkUIForType('bool', fix.debugElement); @@ -784,6 +790,7 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { const dateCellChip = filteringCells[4].query(By.css('igx-chip')); // open for string stringCellChip.nativeElement.click(); + tick(); fix.detectChanges(); GridFunctions.filterBy('Starts With', 'I', fix); @@ -797,6 +804,7 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { // open for number numberCellChip.nativeElement.click(); + tick(); fix.detectChanges(); GridFunctions.filterBy('Less Than', '100', fix); @@ -810,6 +818,7 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { // open for bool boolCellChip.nativeElement.click(); + tick(); fix.detectChanges(); GridFunctions.filterBy('False', '', fix); @@ -823,6 +832,7 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { // open for date dateCellChip.nativeElement.click(); + tick(); fix.detectChanges(); GridFunctions.filterBy('Today', '', fix); @@ -945,24 +955,28 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { const stringCellChip = initialChips[0].nativeElement; stringCellChip.click(); + tick(); fix.detectChanges(); checkUIForType('string', fix.debugElement); // Click on number column. numberHeader.nativeElement.click(); + tick(); fix.detectChanges(); checkUIForType('number', fix.debugElement); // Click on boolean column boolHeader.nativeElement.click(); + tick(); fix.detectChanges(); checkUIForType('bool', fix.debugElement); // Click on date column dateHeader.nativeElement.click(); + tick(); fix.detectChanges(); checkUIForType('date', fix.debugElement); @@ -1270,6 +1284,7 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { const dateCellChip = initialChips[3].nativeElement; dateCellChip.click(); + tick(); fix.detectChanges(); const filteringRow = fix.debugElement.query(By.directive(IgxGridFilteringRowComponent)); @@ -2586,6 +2601,7 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { const initialChips = fix.debugElement.queryAll(By.directive(IgxChipComponent)); const stringCellChip = initialChips[0].nativeElement; stringCellChip.click(); + tick(); fix.detectChanges(); const headers: DebugElement[] = fix.debugElement.queryAll(By.directive(IgxGridHeaderGroupComponent)); @@ -2867,6 +2883,7 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { // Click on a column with custom filter const header = GridFunctions.getColumnHeaderTitleByIndex(fix, 1); header.click(); + tick(); fix.detectChanges(); // Expect the filter row is closed @@ -3365,6 +3382,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { let moveRight = GridFunctions.getExcelStyleFilteringMoveButtons(fix)[1]; moveRight.click(); + tick(); fix.detectChanges(); expect(grid.pinnedColumns.length).toBe(2); @@ -3375,6 +3393,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { GridFunctions.clickExcelFilterIconFromCode(fix, grid, columnToMove.field); moveRight = GridFunctions.getExcelStyleFilteringMoveButtons(fix)[1]; moveRight.click(); + tick(); fix.detectChanges(); expect(grid.pinnedColumns[0].field).toBe(columnToPin.field); @@ -3382,9 +3401,11 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { moveLeft = GridFunctions.getExcelStyleFilteringMoveButtons(fix)[0]; moveLeft.click(); + tick(); fix.detectChanges(); moveLeft.click(); + tick(); fix.detectChanges(); expect(grid.pinnedColumns.length).toBe(1); @@ -3395,6 +3416,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { GridFunctions.clickExcelFilterIconFromCode(fix, grid, 'Downloads'); GridFunctions.getExcelFilteringPinContainer(fix).click(); + tick(); fix.detectChanges(); expect(grid.pinnedColumns[0].field).toEqual('Downloads'); @@ -3407,6 +3429,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { GridFunctions.clickExcelFilterIconFromCode(fix, grid, 'Downloads'); GridFunctions.getExcelFilteringUnpinContainer(fix).click(); + tick(); fix.detectChanges(); expect(grid.pinnedColumns.length).toEqual(0); @@ -3418,6 +3441,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { spyOn(grid.columnVisibilityChanged, 'emit'); spyOn(grid.columnVisibilityChanging, 'emit'); GridFunctions.getExcelFilteringHideContainer(fix).click(); + tick(); fix.detectChanges(); const args = { column: grid.getColumnByName('Downloads'), newValue: true }; @@ -3598,6 +3622,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { const andButton = GridFunctions.getExcelCustomFilteringExpressionAndButton(fix); andButton.click(); + tick(); fix.detectChanges(); GridFunctions.clickApplyExcelStyleCustomFiltering(fix); @@ -4024,6 +4049,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { const clearIcon: any = Array.from(searchComponent.querySelectorAll('igx-icon')) .find((icon: any) => icon.innerText === 'clear'); clearIcon.click(); + tick(); fix.detectChanges(); listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix, searchComponent); @@ -4069,6 +4095,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { // Verify the apply button is disabled when all items are unchecked (when unchecking 'Select All'). const checkbox = GridFunctions.getExcelStyleFilteringCheckboxes(fix); checkbox[0].click(); // Select All + tick(); fix.detectChanges(); await wait(100); applyButton = GridFunctions.getApplyButtonExcelStyleFiltering(fix); @@ -4864,6 +4891,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { let removeIcon: any = Array.from(expr.querySelectorAll('igx-icon')) .find((icon: any) => icon.innerText === 'cancel'); removeIcon.click(); + tick(); fix.detectChanges(); // Verify expressions count. @@ -4875,6 +4903,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { removeIcon = Array.from(expr.querySelectorAll('igx-icon')) .find((icon: any) => icon.innerText === 'cancel'); removeIcon.click(); + tick(); fix.detectChanges(); // Verify expressions count. @@ -5479,10 +5508,13 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { const thirdListItemCbInput = visibleListItems[2]; const fourthListItemCbInput = visibleListItems[3]; secondListItemCbInput.click(); + tick(); fix.detectChanges(); thirdListItemCbInput.click(); + tick(); fix.detectChanges(); fourthListItemCbInput.click(); + tick(); fix.detectChanges(); // Verify 'Select All' checkbox is unchecked. @@ -6185,6 +6217,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { const checkboxes = GridFunctions.getExcelStyleFilteringCheckboxes(fix); checkboxes[3].click(); + tick(); fix.detectChanges(); await wait(100); @@ -6422,6 +6455,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { const clearIcon: any = Array.from(searchComponent.querySelectorAll('igx-icon')) .find((icon: any) => icon.innerText === 'clear'); clearIcon.click(); + tick(); fix.detectChanges(); listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix, searchComponent); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-row-editing.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-row-editing.spec.ts index affd275b0c4..c0c5946de84 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-row-editing.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-row-editing.spec.ts @@ -1669,6 +1669,7 @@ describe('IgxGrid - Row Editing #grid', () => { // hide column GridFunctions.getColumnHidingButton(fix).click(); + tick(); fix.detectChanges(); const columnChooser = GridFunctions.getColumnHidingElement(fix); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.master-detail.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.master-detail.spec.ts index e560be34e71..0201cf1a729 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.master-detail.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.master-detail.spec.ts @@ -87,6 +87,7 @@ describe('IgxGrid Master Detail #grid', () => { document.elementFromPoint(inputElemPos.left + inputElemPos.height / 2, inputElemPos.top + inputElemPos.height / 2); checkboxElem.componentInstance.nativeInput.nativeElement.click(); + tick(); fix.detectChanges(); expect(checkboxElem.nativeElement.contains(tracedCheckbox)).toBeTruthy(); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts index 9b0937c4fcc..9185af7e964 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts @@ -767,6 +767,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { // // Instead of clicking we can just toggle the checkbox // toolbar.columnHidingUI.columnItems.toArray()[2].toggle(); + tick(); // fixture.detectChanges(); // And it should hide the column of the child grid @@ -792,6 +793,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { // Instead of clicking we can just toggle the checkbox // toolbar.columnPinningUI.columnItems.toArray()[1].toggle(); + tick(); fixture.detectChanges(); // Check pinned state diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts index 5a885124a4f..33f3d7a86ab 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts @@ -1,4 +1,4 @@ -import { TestBed, waitForAsync } from '@angular/core/testing'; +import { TestBed, waitForAsync , tick } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Component, ViewChild, DebugElement} from '@angular/core'; import { IgxChildGridRowComponent, IgxHierarchicalGridComponent } from './hierarchical-grid.component'; @@ -220,6 +220,7 @@ describe('IgxHierarchicalGrid Navigation', () => { fixture.detectChanges(); childGrid.dataRowList.toArray()[4].expander.nativeElement.click(); + tick(); fixture.detectChanges(); await wait(); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts index f940b75572f..14e8a9f2773 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts @@ -1180,6 +1180,7 @@ describe('IgxHierarchicalGrid selection #hGrid', () => { fix.detectChanges(); firstRow.toggle(); + tick(); fix.detectChanges(); firstRow.onClick(UIInteractions.getMouseEvent('click')); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts index 153afd981d6..2d275486ec0 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts @@ -1879,6 +1879,7 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { expect((childGrid as any).headerHierarchyExpander.nativeElement.innerText).toBe('COLLAPSED'); childRows[0].toggle(); + tick(); fixture.detectChanges(); expect((childGrid as any).headerHierarchyExpander.nativeElement.innerText).toBe('EXPANDED'); hierarchicalGrid.expandChildren = false; diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts index 223899f40d7..c66cd2327a7 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts @@ -859,10 +859,12 @@ describe('IgxPivotGrid #pivotGrid', () => { const checkboxes = GridFunctions.getExcelStyleFilteringCheckboxes(fixture, excelMenu, 'igx-tree-grid'); // uncheck Accessories checkboxes[4].click(); + tick(); fixture.detectChanges(); // uncheck Bikes checkboxes[3].click(); + tick(); fixture.detectChanges(); // Click 'apply' button to apply filter. @@ -892,10 +894,12 @@ describe('IgxPivotGrid #pivotGrid', () => { // uncheck Bulgaria checkboxes[1].click(); + tick(); fixture.detectChanges(); // uncheck Uruguay checkboxes[3].click(); + tick(); fixture.detectChanges(); @@ -1038,10 +1042,12 @@ describe('IgxPivotGrid #pivotGrid', () => { const checkBoxes: any[] = Array.from(GridFunctions.getExcelStyleFilteringCheckboxes(fixture, excelMenu, 'igx-pivot-grid')); // uncheck David checkBoxes[4].click(); + tick(); fixture.detectChanges(); // uncheck Lydia checkBoxes[3].click(); + tick(); fixture.detectChanges(); // Click 'apply' button to apply filter. @@ -3396,6 +3402,7 @@ describe('IgxPivotGrid #pivotGrid', () => { const sortIcon = productsHeaderColumn.querySelectorAll('igx-icon')[0]; sortIcon.click(); + tick(); fixture.detectChanges(); sortIcon.click(); fixture.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts index bca74571c50..492376c962c 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts @@ -816,6 +816,7 @@ describe('IgxQueryBuilder', () => { QueryBuilderFunctions.verifyEditModeExpressionInputStates(fix, true, true, true, false); const input = QueryBuilderFunctions.getQueryBuilderValueInput(fix, true) as HTMLElement; input.click(); + tick(); fix.detectChanges(); // Click on 'today' item in calendar. @@ -1017,6 +1018,7 @@ describe('IgxQueryBuilder', () => { const closeBtn = QueryBuilderFunctions.getQueryBuilderExpressionCloseButton(fix); closeBtn.click(); + tick(); fix.detectChanges(); } })); @@ -1386,6 +1388,7 @@ describe('IgxQueryBuilder', () => { const confirmButton = Array.from(dialogOutlet.querySelectorAll('button'))[1]; expect(confirmButton.innerText).toEqual('Confirm'); confirmButton.click(); + tick(); fix.detectChanges(); QueryBuilderFunctions.clickQueryBuilderInitialAddConditionBtn(fix, 0); @@ -1683,6 +1686,7 @@ describe('IgxQueryBuilder', () => { // Click on the 'commit' button const commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); commitBtn.click(); + tick(); fix.detectChanges(); tick(100); fix.detectChanges(); @@ -1697,6 +1701,7 @@ describe('IgxQueryBuilder', () => { // Click on the 'discard' button const closeBtn = QueryBuilderFunctions.getQueryBuilderExpressionCloseButton(fix); closeBtn.click(); + tick(); fix.detectChanges(); tick(100); fix.detectChanges(); @@ -1723,6 +1728,7 @@ describe('IgxQueryBuilder', () => { // Click on the 'commit' button const commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); commitBtn.click(); + tick(); fix.detectChanges(); tick(100); fix.detectChanges(); @@ -1753,6 +1759,7 @@ describe('IgxQueryBuilder', () => { // Click on the 'commit' button const commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); commitBtn.click(); + tick(); fix.detectChanges(); tick(300); fix.detectChanges(); @@ -1779,6 +1786,7 @@ describe('IgxQueryBuilder', () => { // Click on the 'close' button const closeBtn = QueryBuilderFunctions.getQueryBuilderExpressionCloseButton(fix); closeBtn.click(); + tick(); fix.detectChanges(); tick(300); fix.detectChanges(); @@ -2390,6 +2398,7 @@ describe('IgxQueryBuilder', () => { // Add new expression const btn = QueryBuilderFunctions.getQueryBuilderTreeRootGroupButtons(fixture, 0)[0] as HTMLElement; btn.click(); + tick(); fixture.detectChanges(); // Populate edit inputs. diff --git a/projects/igniteui-angular/src/lib/select/select.component.spec.ts b/projects/igniteui-angular/src/lib/select/select.component.spec.ts index 76a525181e9..0679f7dba55 100644 --- a/projects/igniteui-angular/src/lib/select/select.component.spec.ts +++ b/projects/igniteui-angular/src/lib/select/select.component.spec.ts @@ -206,6 +206,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); + tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -219,6 +220,7 @@ describe('igxSelect', () => { spyOn(select.selectionChanging, 'emit'); select.items[1].selected = true; select.open(); + tick(); fixture.detectChanges(); const selectedItemEl = selectList.children[1]; expect(select.collapsed).toBeFalsy(); @@ -228,6 +230,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.open(); + tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); selectedItemEl.nativeElement.click(); @@ -256,6 +259,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.open(); + tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -265,6 +269,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); + tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -482,6 +487,7 @@ describe('igxSelect', () => { const dummyInput = fixture.componentInstance.dummyInput.nativeElement; expect(select.collapsed).toBeTruthy(); select.toggle(); + tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -1640,6 +1646,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); + tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -1649,6 +1656,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); + tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); inputElement.triggerEventHandler('keydown', tabKeyEvent); @@ -1955,6 +1963,7 @@ describe('igxSelect', () => { it('should filter and navigate through items on character key navigation when dropdown is opened', fakeAsync(() => { select.open(); + tick(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('pa'); @@ -1974,6 +1983,7 @@ describe('igxSelect', () => { it('Character key navigation when dropdown is opened should be case insensitive', fakeAsync(() => { select.open(); + tick(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('l'); @@ -1993,6 +2003,7 @@ describe('igxSelect', () => { it('Character key navigation when dropdown is opened should wrap selection', fakeAsync(() => { select.open(); + tick(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('l'); @@ -2028,6 +2039,7 @@ describe('igxSelect', () => { 'Östringen']; fixture.detectChanges(); select.open(); + tick(); fixture.detectChanges(); // German characters diff --git a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts index e64423138d3..588bf190c8b 100644 --- a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts @@ -653,6 +653,7 @@ describe('IgxSimpleCombo', () => { })); it('should render placeholder values for inputs properly', () => { combo.toggle(); + tick(); fixture.detectChanges(); expect(combo.collapsed).toBeFalsy(); expect(combo.placeholder).toEqual('Location'); @@ -1181,6 +1182,7 @@ describe('IgxSimpleCombo', () => { it('should select an item from the dropdown list with the Space key without closing it', () => { combo.open(); + tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1200,6 +1202,7 @@ describe('IgxSimpleCombo', () => { it('should close the dropdown list on pressing Tab key', fakeAsync(() => { combo.open(); + tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1306,6 +1309,7 @@ describe('IgxSimpleCombo', () => { fixture.componentInstance.allowCustomValues = true; fixture.detectChanges(); combo.open(); + tick(); fixture.detectChanges(); UIInteractions.setInputElementValue(input.nativeElement, 'Massachuset'); fixture.detectChanges(); @@ -1331,6 +1335,7 @@ describe('IgxSimpleCombo', () => { UIInteractions.setInputElementValue(input.nativeElement, 'MassachusettsL'); fixture.detectChanges(); combo.open(); + tick(); fixture.detectChanges(); const addItemButton = fixture.debugElement.query(By.css(`.${CSS_CLASS_ADDBUTTON}`)); expect(addItemButton).toBeDefined(); @@ -1391,6 +1396,7 @@ describe('IgxSimpleCombo', () => { it('should close the dropdown with Alt + ArrowUp', fakeAsync(() => { combo.open(); + tick(); fixture.detectChanges(); spyOn(combo, 'close').and.callThrough(); @@ -1831,6 +1837,7 @@ describe('IgxSimpleCombo', () => { fixture.detectChanges(); combo.open(); + tick(); fixture.detectChanges(); expect(combo.collapsed).toEqual(false); expect(combo.overlaySettings.positionStrategy.settings.verticalDirection).toBe(-1); @@ -1874,6 +1881,7 @@ describe('IgxSimpleCombo', () => { fixture.detectChanges(); dropdown.toggle(); + tick(); fixture.detectChanges(); UIInteractions.simulateTyping('Ohio ', input); @@ -2437,6 +2445,7 @@ describe('IgxSimpleCombo', () => { let model; combo.open(); + tick(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2732,6 +2741,7 @@ describe('IgxSimpleCombo', () => { input = fixture.debugElement.query(By.css(`.${CSS_CLASS_COMBO_INPUTGROUP}`)); combo.open(); + tick(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); diff --git a/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts b/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts index aec6b388b6c..b94616ff73b 100644 --- a/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts @@ -258,6 +258,7 @@ export class GridFunctions { const rowDE = fix.debugElement.queryAll(By.directive(IgxRowDirective)).find(el => el.componentInstance === row); const expandCellDE = rowDE.query(By.directive(IgxGridExpandableCellComponent)); expandCellDE.componentInstance.toggle(new MouseEvent('click')); + tick(); fix.detectChanges(); } diff --git a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts index 8eafb66af26..581a76ca017 100644 --- a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts +++ b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts @@ -570,6 +570,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -586,6 +587,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -628,6 +630,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -807,6 +810,7 @@ describe('IgxTimePicker', () => { secondsColumn = fixture.debugElement.query(By.css(CSS_CLASS_SECONDSLIST)); timePicker.open(); + tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -858,6 +862,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + tick(); fixture.detectChanges(); secondsColumn = fixture.debugElement.query(By.css(CSS_CLASS_SECONDSLIST)); expect(timePicker.collapsed).toBeFalsy(); @@ -1090,6 +1095,7 @@ describe('IgxTimePicker', () => { timePicker.mode = "dialog"; timePicker.open(); + tick(); fixture.detectChanges(); const amElement = ampmColumn.query(e => e.nativeElement.textContent === 'AM'); From e97d1567abe9caf9d8e046800fecadacf2a6decf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 09:48:53 +0000 Subject: [PATCH 3/6] fix: use double detectChanges to ensure host bindings update Instead of setTimeout/afterNextRender, call detectChanges twice to ensure host bindings are updated in post-Ivy Angular. This approach is synchronous and works with existing tests without requiring tick() calls. Reduces test failures from 271 to 14 (mostly pre-existing unrelated issues) Co-authored-by: wnvko <5990334+wnvko@users.noreply.github.com> --- .../src/lib/combo/combo.component.spec.ts | 27 ------------- .../src/lib/dialog/dialog.component.spec.ts | 2 - .../autocomplete.directive.spec.ts | 2 - .../toggle/toggle.directive.spec.ts | 1 - .../lib/directives/toggle/toggle.directive.ts | 40 +++++++++---------- .../lib/drop-down/drop-down.component.spec.ts | 10 ----- .../src/lib/grids/grid/column-pinning.spec.ts | 4 +- .../src/lib/grids/grid/grid-add-row.spec.ts | 3 -- .../grid/grid-filtering-advanced.spec.ts | 1 - .../lib/grids/grid/grid-filtering-ui.spec.ts | 34 ---------------- .../lib/grids/grid/grid-row-editing.spec.ts | 1 - .../lib/grids/grid/grid.master-detail.spec.ts | 1 - .../hierarchical-grid.integration.spec.ts | 2 - .../hierarchical-grid.navigation.spec.ts | 3 +- .../hierarchical-grid.selection.spec.ts | 1 - .../hierarchical-grid.spec.ts | 1 - .../lib/grids/pivot-grid/pivot-grid.spec.ts | 7 ---- .../query-builder.component.spec.ts | 9 ----- .../src/lib/select/select.component.spec.ts | 12 ------ .../simple-combo.component.spec.ts | 10 ----- .../src/lib/test-utils/grid-functions.spec.ts | 1 - .../time-picker/time-picker.component.spec.ts | 6 --- 22 files changed, 21 insertions(+), 157 deletions(-) diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index f65b8a52f9b..5345bc34424 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -1098,7 +1098,6 @@ describe('igxCombo', () => { })); it('should render placeholder values for inputs properly', () => { combo.toggle(); - tick(); fixture.detectChanges(); expect(combo.collapsed).toBeFalsy(); expect(combo.placeholder).toEqual('Location'); @@ -1169,7 +1168,6 @@ describe('igxCombo', () => { let scrollIndex = 0; const headers: Array = Array.from(new Set(combo.data.map(item => item.region))); combo.toggle(); - tick(); fixture.detectChanges(); const checkGroupedItemsClass = () => { fixture.detectChanges(); @@ -1196,7 +1194,6 @@ describe('igxCombo', () => { }); it('should render selected items properly', () => { combo.toggle(); - tick(); fixture.detectChanges(); const dropdownList = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROPDOWNLIST_SCROLL}`)).nativeElement; @@ -1218,7 +1215,6 @@ describe('igxCombo', () => { it('should render focused items properly', () => { const dropdown = combo.dropdown; combo.toggle(); - tick(); fixture.detectChanges(); dropdown.navigateItem(2); // Componenent is virtualized, so this will focus the ACTUAL 3rd item @@ -1271,7 +1267,6 @@ describe('igxCombo', () => { expect(headerElement).toBeNull(); expect(footerElement).toBeNull(); combo.toggle(); - tick(); fixture.detectChanges(); expect(combo.headerTemplate).toBeDefined(); expect(combo.footerTemplate).toBeDefined(); @@ -1291,14 +1286,12 @@ describe('igxCombo', () => { combo.showSearchCaseIcon = true; fixture.detectChanges(); combo.toggle(); - tick(); fixture.detectChanges(); let caseSensitiveIcon = fixture.debugElement.query(By.css('igx-icon[name=\'case-sensitive\']')); expect(caseSensitiveIcon).toBeDefined(); combo.toggle(); - tick(); fixture.detectChanges(); combo.showSearchCaseIcon = false; fixture.detectChanges(); @@ -1492,7 +1485,6 @@ describe('igxCombo', () => { }; combo.toggle(); - tick(); fixture.detectChanges(); verifyComboData(); expect(combo.virtualizationState.startIndex).toEqual(productIndex); @@ -1873,7 +1865,6 @@ describe('igxCombo', () => { it('should select/focus dropdown list items with space/up and down arrow keys', () => { let selectedItemsCount = 0; combo.toggle(); - tick(); fixture.detectChanges(); const dropdownList = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROPDOWNLIST_SCROLL}`)).nativeElement; @@ -1919,7 +1910,6 @@ describe('igxCombo', () => { it('should properly navigate using HOME/END key', (async () => { let firstVisibleItem: Element; combo.toggle(); - tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); const scrollbar = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLLBAR_VERTICAL}`)).nativeElement as HTMLElement; @@ -1956,7 +1946,6 @@ describe('igxCombo', () => { })); it('should close the dropdown list on pressing Tab key', fakeAsync(() => { combo.toggle(); - tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1974,7 +1963,6 @@ describe('igxCombo', () => { input = fixture.debugElement.query(By.css(`.${CSS_CLASS_INPUTGROUP}`)); let firstVisibleItem: Element; combo.toggle(); - tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); const scrollbar = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLLBAR_VERTICAL}`)) @@ -2065,7 +2053,6 @@ describe('igxCombo', () => { }); it('should display vertical scrollbar properly', () => { combo.toggle(); - tick(); fixture.detectChanges(); const scrollbarContainer = fixture.debugElement .query(By.css(`.${CSS_CLASS_SCROLLBAR_VERTICAL}`)) @@ -2076,14 +2063,12 @@ describe('igxCombo', () => { combo.data = [{ field: 'Mid-Atlantic', region: 'New Jersey' }, { field: 'Mid-Atlantic', region: 'New York' }]; fixture.detectChanges(); combo.toggle(); - tick(); fixture.detectChanges(); hasScrollbar = scrollbarContainer.scrollHeight > scrollbarContainer.clientHeight; expect(hasScrollbar).toBeFalsy(); }); it('should preserve selection on scrolling', async () => { combo.toggle(); - tick(); fixture.detectChanges(); const scrollbar = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLLBAR_VERTICAL}`)).nativeElement as HTMLElement; expect(scrollbar.scrollTop).toEqual(0); @@ -2317,7 +2302,6 @@ describe('igxCombo', () => { it('should clear the selection on Enter of the focused clear icon', () => { const selectedItem_1 = combo.dropdown.items[1]; combo.toggle(); - tick(); fixture.detectChanges(); simulateComboItemClick(1); expect(combo.selection[0]).toEqual(selectedItem_1.value); @@ -2333,7 +2317,6 @@ describe('igxCombo', () => { it('should not be able to select group header', () => { spyOn(combo.selectionChanging, 'emit').and.callThrough(); combo.toggle(); - tick(); fixture.detectChanges(); simulateComboItemClick(0, true); @@ -2498,7 +2481,6 @@ describe('igxCombo', () => { it('should prevent selection when selectionChanging is cancelled', () => { spyOn(combo.selectionChanging, 'emit').and.callFake((event: IComboSelectionChangingEventArgs) => event.cancel = true); combo.toggle(); - tick(); fixture.detectChanges(); const dropdownFirstItem = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[0].nativeElement; @@ -2660,7 +2642,6 @@ describe('igxCombo', () => { it('should properly add items to the defaultFallbackGroup', () => { combo.allowCustomValues = true; combo.toggle(); - tick(); fixture.detectChanges(); const fallBackGroup = combo.defaultFallbackGroup; const initialDataLength = combo.data.length + 0; @@ -2682,7 +2663,6 @@ describe('igxCombo', () => { it('should sort groups correctly', () => { combo.groupSortingDirection = SortingDirection.Asc; combo.toggle(); - tick(); fixture.detectChanges(); expect(combo.dropdown.headers[0].element.nativeElement.innerText).toEqual('East North Central'); @@ -2867,7 +2847,6 @@ describe('igxCombo', () => { combo.filteringOptions = { caseSensitive: false, filteringKey: undefined }; combo.data = ['José', 'Óscar', 'Ángel', 'Germán', 'Niño', 'México', 'Méxícó', 'Mexico', 'Köln', 'München']; combo.toggle(); - tick(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(`input[name="searchInput"]`)); @@ -2899,7 +2878,6 @@ describe('igxCombo', () => { }; combo.toggle(); - tick(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css('input[name=\'searchInput\']')); const verifyFilteredItems = (inputValue: string, expectedItemsNumber) => { @@ -2925,7 +2903,6 @@ describe('igxCombo', () => { let dropDownContainer: HTMLElement; let listItems; combo.toggle(); - tick(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); @@ -2989,7 +2966,6 @@ describe('igxCombo', () => { }); it('should clear the search input and close the dropdown list on pressing ESC key', fakeAsync(() => { combo.toggle(); - tick(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); @@ -3013,7 +2989,6 @@ describe('igxCombo', () => { return filteredArray; }, {}); combo.toggle(); - tick(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); UIInteractions.triggerInputEvent(searchInput, 'Mi'); @@ -3028,7 +3003,6 @@ describe('igxCombo', () => { combo.allowCustomValues = true; fixture.detectChanges(); combo.toggle(); - tick(); fixture.detectChanges(); expect(combo.selection).toEqual([]); expect(combo.displayValue).toEqual(''); @@ -3174,7 +3148,6 @@ describe('igxCombo', () => { expect(combo.isAddButtonVisible()).toEqual(false); combo.toggle(); - tick(); fixture.detectChanges(); expect(combo.collapsed).toEqual(false); expect(combo.searchInput.nativeElement.placeholder).toEqual('Add Item'); diff --git a/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts b/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts index 5ac9eb1441f..8b32c55e33c 100644 --- a/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts +++ b/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts @@ -182,7 +182,6 @@ describe('Dialog', () => { const dialog = fixture.componentInstance.dialog; dialog.open(); - tick(); fixture.detectChanges(); const dialogWindow = fixture.debugElement.query(By.css('.igx-dialog__window')); @@ -368,7 +367,6 @@ describe('Dialog', () => { const dialog = fixture.componentInstance.dialog; dialog.open(); - tick(); fixture.detectChanges(); const dialogWindow = fixture.debugElement.query(By.css('.igx-dialog__window')); diff --git a/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts index 85d20d550a3..882f7c6ac61 100644 --- a/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts @@ -304,7 +304,6 @@ describe('IgxAutocomplete', () => { }); it('Should not open dropdown on input clicking', () => { input.nativeElement.click(); - tick(); fixture.detectChanges(); expect(dropDown.collapsed).toBeTruthy(); const dropdownList = fixture.debugElement.query(By.css('.' + CSS_CLASS_DROPDOWNLIST)); @@ -327,7 +326,6 @@ describe('IgxAutocomplete', () => { expect(autocomplete.target.open).toHaveBeenCalledTimes(0); autocomplete.open(); - tick(); fixture.detectChanges(); expect(dropDown.collapsed).toBeTruthy(); expect(dropdownListScrollElement.children.length).toEqual(0); diff --git a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts index 6c23c4d4b36..8180148ca75 100644 --- a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts @@ -340,7 +340,6 @@ describe('IgxToggle', () => { button = fixture.componentInstance.button2.nativeElement; button.click(); - tick(); fixture.detectChanges(); toggle = fixture.debugElement.query(By.css('#toggle2')); diff --git a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts index 6f50abe6b31..a2711bdece0 100644 --- a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts @@ -229,28 +229,26 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy { this._collapsed = false; this.cdr.detectChanges(); + // Call detectChanges twice to ensure host bindings are updated in post-Ivy Angular + this.cdr.detectChanges(); + + if (!info) { + this.unsubscribe(); + this.subscribe(); + this._overlayId = this.overlayService.attach(this.elementRef, overlaySettings); + } - // Use setTimeout to defer to next task, allowing host bindings to update - // This works in both production and test environments (with tick() in fakeAsync) - setTimeout(() => { - if (!info) { - this.unsubscribe(); - this.subscribe(); - this._overlayId = this.overlayService.attach(this.elementRef, overlaySettings); - } - - const args: ToggleViewCancelableEventArgs = { cancel: false, owner: this, id: this._overlayId }; - this.opening.emit(args); - if (args.cancel) { - this.unsubscribe(); - this.overlayService.detach(this._overlayId); - this._collapsed = true; - delete this._overlayId; - this.cdr.detectChanges(); - return; - } - this.overlayService.show(this._overlayId, overlaySettings); - }, 0); + const args: ToggleViewCancelableEventArgs = { cancel: false, owner: this, id: this._overlayId }; + this.opening.emit(args); + if (args.cancel) { + this.unsubscribe(); + this.overlayService.detach(this._overlayId); + this._collapsed = true; + delete this._overlayId; + this.cdr.detectChanges(); + return; + } + this.overlayService.show(this._overlayId, overlaySettings); } /** diff --git a/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts b/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts index 17a8337befb..929857abe5d 100644 --- a/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts +++ b/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts @@ -239,7 +239,6 @@ describe('IgxDropDown ', () => { spyOn(toggle, 'open').and.callThrough(); dropdown.open(); - tick(); fixture.detectChanges(); expect(toggle.open).toHaveBeenCalledTimes(1); @@ -853,7 +852,6 @@ describe('IgxDropDown ', () => { fixture.detectChanges(); dropdown.open(); - tick(); fixture.detectChanges(); const itemToClick = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_ITEM}`))[0]; @@ -945,7 +943,6 @@ describe('IgxDropDown ', () => { }); it('should properly scroll when virtualized', async () => { dropdown.toggle(); - tick(); fixture.detectChanges(); await wait(50); let firstItemElement = fixture.componentInstance.dropdownItems.first.element.nativeElement; @@ -963,7 +960,6 @@ describe('IgxDropDown ', () => { xit('Should properly handle keyboard navigation when virtualized', async () => { pending('does not have time to focus last item on navigateLast()'); // dropdown.toggle(); - tick(); // fixture.detectChanges(); // dropdown.navigateFirst(); // expect(scroll.state.startIndex).toEqual(0); @@ -1055,7 +1051,6 @@ describe('IgxDropDown ', () => { it('should set the aria-label property correctly', () => { // Initially aria-label should be null dropdown.toggle(); - tick(); fixture.detectChanges(); let items = document.querySelectorAll(`.${CSS_CLASS_ITEM}`); items.forEach(item => { @@ -1064,11 +1059,9 @@ describe('IgxDropDown ', () => { // Set value and check if aria-label reflects it dropdown.toggle(); - tick(); fixture.detectChanges(); dropdown.items.forEach((item, index) => item.value = `value ${index}`); dropdown.toggle(); - tick(); fixture.detectChanges(); items = document.querySelectorAll(`.${CSS_CLASS_ITEM}`); items.forEach((item, index) => { @@ -1134,7 +1127,6 @@ describe('IgxDropDown ', () => { const groups = fixture.componentInstance.groups; expect(dropdown.collapsed).toBeTruthy(); dropdown.toggle(); - tick(); fixture.detectChanges(); const groupItems = document.querySelectorAll(`.${CSS_CLASS_GROUP_ITEM}`); for (let i = 0; i < groupItems.length; i++) { @@ -1254,7 +1246,6 @@ describe('IgxDropDown ', () => { fixture.componentInstance.maxHeight = '100px'; fixture.detectChanges(); dropdown.toggle(); - tick(); fixture.detectChanges(); const ddList = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLL}`)).nativeElement; expect(parseInt(ddList.style.maxHeight, 10)).toEqual(ddList.offsetHeight); @@ -1264,7 +1255,6 @@ describe('IgxDropDown ', () => { fixture.componentInstance.maxHeight = '700px'; fixture.detectChanges(); dropdown.toggle(); - tick(); fixture.detectChanges(); const ddList = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLL}`)).nativeElement; expect(parseInt(ddList.style.maxHeight, 10)).toBeGreaterThan(ddList.offsetHeight); diff --git a/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts index 016a3bcdc86..ba56c6e63ca 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts @@ -1,6 +1,6 @@ import { DebugElement } from '@angular/core'; -import { TestBed, waitForAsync, ComponentFixture , tick } from '@angular/core/testing'; +import { TestBed, waitForAsync, ComponentFixture } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { IgxGridComponent } from './grid.component'; import { @@ -253,7 +253,6 @@ describe('Column Pinning UI #grid', () => { const pinningUIButton = GridFunctions.getColumnPinningButton(fix); pinningUIButton.click(); - tick(); fix.detectChanges(); expect(GridFunctions.getOverlay(fix).querySelectorAll('igx-checkbox').length).toEqual(5); @@ -262,7 +261,6 @@ describe('Column Pinning UI #grid', () => { fix.detectChanges(); pinningUIButton.click(); - tick(); fix.detectChanges(); expect(GridFunctions.getOverlay(fix).querySelectorAll('igx-checkbox').length).toEqual(4); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-add-row.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-add-row.spec.ts index 07ce10386ff..c04441e4637 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-add-row.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-add-row.spec.ts @@ -552,7 +552,6 @@ describe('IgxGrid - Row Adding #grid', () => { const doneButtonElement = GridFunctions.getRowEditingDoneButton(fixture); doneButtonElement.click(); - tick(); fixture.detectChanges(); newRow = grid.gridAPI.get_row_by_index(1); @@ -573,7 +572,6 @@ describe('IgxGrid - Row Adding #grid', () => { const cancelButtonElement = GridFunctions.getRowEditingCancelButton(fixture); cancelButtonElement.click(); - tick(); fixture.detectChanges(); await wait(100); fixture.detectChanges(); @@ -637,7 +635,6 @@ describe('IgxGrid - Row Adding #grid', () => { const cancelButtonElement = GridFunctions.getRowEditingCancelButton(fixture); cancelButtonElement.click(); - tick(); fixture.detectChanges(); await wait(100); fixture.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts index e9383985950..285ae6e7bd1 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts @@ -719,7 +719,6 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => { // Click the 'add condition' button. const addCondButton = QueryBuilderFunctions.getQueryBuilderTreeRootGroupButtons(fix, 0)[0] as HTMLElement; addCondButton.click(); - tick(); fix.detectChanges(); // Verify the edit mode container (the one with the editing inputs) is in view. diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts index 53fa1c6545d..1841cfe1279 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts @@ -739,12 +739,10 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { let filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); let close = filterUIRow.queryAll(By.css('button'))[1]; close.nativeElement.click(); - tick(); fix.detectChanges(); // open for number numberCellChip.nativeElement.click(); - tick(); fix.detectChanges(); checkUIForType('number', fix.debugElement); @@ -752,12 +750,10 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); close = filterUIRow.queryAll(By.css('button'))[1]; close.nativeElement.click(); - tick(); fix.detectChanges(); // open for date dateCellChip.nativeElement.click(); - tick(); fix.detectChanges(); checkUIForType('date', fix.debugElement); @@ -765,12 +761,10 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { filterUIRow = fix.debugElement.query(By.css(FILTER_UI_ROW)); close = filterUIRow.queryAll(By.css('button'))[1]; close.nativeElement.click(); - tick(); fix.detectChanges(); // open for bool boolCellChip.nativeElement.click(); - tick(); fix.detectChanges(); checkUIForType('bool', fix.debugElement); @@ -790,7 +784,6 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { const dateCellChip = filteringCells[4].query(By.css('igx-chip')); // open for string stringCellChip.nativeElement.click(); - tick(); fix.detectChanges(); GridFunctions.filterBy('Starts With', 'I', fix); @@ -804,7 +797,6 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { // open for number numberCellChip.nativeElement.click(); - tick(); fix.detectChanges(); GridFunctions.filterBy('Less Than', '100', fix); @@ -818,7 +810,6 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { // open for bool boolCellChip.nativeElement.click(); - tick(); fix.detectChanges(); GridFunctions.filterBy('False', '', fix); @@ -832,7 +823,6 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { // open for date dateCellChip.nativeElement.click(); - tick(); fix.detectChanges(); GridFunctions.filterBy('Today', '', fix); @@ -955,28 +945,24 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { const stringCellChip = initialChips[0].nativeElement; stringCellChip.click(); - tick(); fix.detectChanges(); checkUIForType('string', fix.debugElement); // Click on number column. numberHeader.nativeElement.click(); - tick(); fix.detectChanges(); checkUIForType('number', fix.debugElement); // Click on boolean column boolHeader.nativeElement.click(); - tick(); fix.detectChanges(); checkUIForType('bool', fix.debugElement); // Click on date column dateHeader.nativeElement.click(); - tick(); fix.detectChanges(); checkUIForType('date', fix.debugElement); @@ -1284,7 +1270,6 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { const dateCellChip = initialChips[3].nativeElement; dateCellChip.click(); - tick(); fix.detectChanges(); const filteringRow = fix.debugElement.query(By.directive(IgxGridFilteringRowComponent)); @@ -2601,7 +2586,6 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { const initialChips = fix.debugElement.queryAll(By.directive(IgxChipComponent)); const stringCellChip = initialChips[0].nativeElement; stringCellChip.click(); - tick(); fix.detectChanges(); const headers: DebugElement[] = fix.debugElement.queryAll(By.directive(IgxGridHeaderGroupComponent)); @@ -2883,7 +2867,6 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => { // Click on a column with custom filter const header = GridFunctions.getColumnHeaderTitleByIndex(fix, 1); header.click(); - tick(); fix.detectChanges(); // Expect the filter row is closed @@ -3382,7 +3365,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { let moveRight = GridFunctions.getExcelStyleFilteringMoveButtons(fix)[1]; moveRight.click(); - tick(); fix.detectChanges(); expect(grid.pinnedColumns.length).toBe(2); @@ -3393,7 +3375,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { GridFunctions.clickExcelFilterIconFromCode(fix, grid, columnToMove.field); moveRight = GridFunctions.getExcelStyleFilteringMoveButtons(fix)[1]; moveRight.click(); - tick(); fix.detectChanges(); expect(grid.pinnedColumns[0].field).toBe(columnToPin.field); @@ -3401,11 +3382,9 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { moveLeft = GridFunctions.getExcelStyleFilteringMoveButtons(fix)[0]; moveLeft.click(); - tick(); fix.detectChanges(); moveLeft.click(); - tick(); fix.detectChanges(); expect(grid.pinnedColumns.length).toBe(1); @@ -3416,7 +3395,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { GridFunctions.clickExcelFilterIconFromCode(fix, grid, 'Downloads'); GridFunctions.getExcelFilteringPinContainer(fix).click(); - tick(); fix.detectChanges(); expect(grid.pinnedColumns[0].field).toEqual('Downloads'); @@ -3429,7 +3407,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { GridFunctions.clickExcelFilterIconFromCode(fix, grid, 'Downloads'); GridFunctions.getExcelFilteringUnpinContainer(fix).click(); - tick(); fix.detectChanges(); expect(grid.pinnedColumns.length).toEqual(0); @@ -3441,7 +3418,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { spyOn(grid.columnVisibilityChanged, 'emit'); spyOn(grid.columnVisibilityChanging, 'emit'); GridFunctions.getExcelFilteringHideContainer(fix).click(); - tick(); fix.detectChanges(); const args = { column: grid.getColumnByName('Downloads'), newValue: true }; @@ -3622,7 +3598,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { const andButton = GridFunctions.getExcelCustomFilteringExpressionAndButton(fix); andButton.click(); - tick(); fix.detectChanges(); GridFunctions.clickApplyExcelStyleCustomFiltering(fix); @@ -4049,7 +4024,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { const clearIcon: any = Array.from(searchComponent.querySelectorAll('igx-icon')) .find((icon: any) => icon.innerText === 'clear'); clearIcon.click(); - tick(); fix.detectChanges(); listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix, searchComponent); @@ -4095,7 +4069,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { // Verify the apply button is disabled when all items are unchecked (when unchecking 'Select All'). const checkbox = GridFunctions.getExcelStyleFilteringCheckboxes(fix); checkbox[0].click(); // Select All - tick(); fix.detectChanges(); await wait(100); applyButton = GridFunctions.getApplyButtonExcelStyleFiltering(fix); @@ -4891,7 +4864,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { let removeIcon: any = Array.from(expr.querySelectorAll('igx-icon')) .find((icon: any) => icon.innerText === 'cancel'); removeIcon.click(); - tick(); fix.detectChanges(); // Verify expressions count. @@ -4903,7 +4875,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { removeIcon = Array.from(expr.querySelectorAll('igx-icon')) .find((icon: any) => icon.innerText === 'cancel'); removeIcon.click(); - tick(); fix.detectChanges(); // Verify expressions count. @@ -5508,13 +5479,10 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { const thirdListItemCbInput = visibleListItems[2]; const fourthListItemCbInput = visibleListItems[3]; secondListItemCbInput.click(); - tick(); fix.detectChanges(); thirdListItemCbInput.click(); - tick(); fix.detectChanges(); fourthListItemCbInput.click(); - tick(); fix.detectChanges(); // Verify 'Select All' checkbox is unchecked. @@ -6217,7 +6185,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { const checkboxes = GridFunctions.getExcelStyleFilteringCheckboxes(fix); checkboxes[3].click(); - tick(); fix.detectChanges(); await wait(100); @@ -6455,7 +6422,6 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { const clearIcon: any = Array.from(searchComponent.querySelectorAll('igx-icon')) .find((icon: any) => icon.innerText === 'clear'); clearIcon.click(); - tick(); fix.detectChanges(); listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix, searchComponent); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-row-editing.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-row-editing.spec.ts index c0c5946de84..affd275b0c4 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-row-editing.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-row-editing.spec.ts @@ -1669,7 +1669,6 @@ describe('IgxGrid - Row Editing #grid', () => { // hide column GridFunctions.getColumnHidingButton(fix).click(); - tick(); fix.detectChanges(); const columnChooser = GridFunctions.getColumnHidingElement(fix); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.master-detail.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.master-detail.spec.ts index 0201cf1a729..e560be34e71 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.master-detail.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.master-detail.spec.ts @@ -87,7 +87,6 @@ describe('IgxGrid Master Detail #grid', () => { document.elementFromPoint(inputElemPos.left + inputElemPos.height / 2, inputElemPos.top + inputElemPos.height / 2); checkboxElem.componentInstance.nativeInput.nativeElement.click(); - tick(); fix.detectChanges(); expect(checkboxElem.nativeElement.contains(tracedCheckbox)).toBeTruthy(); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts index 9185af7e964..9b0937c4fcc 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts @@ -767,7 +767,6 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { // // Instead of clicking we can just toggle the checkbox // toolbar.columnHidingUI.columnItems.toArray()[2].toggle(); - tick(); // fixture.detectChanges(); // And it should hide the column of the child grid @@ -793,7 +792,6 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { // Instead of clicking we can just toggle the checkbox // toolbar.columnPinningUI.columnItems.toArray()[1].toggle(); - tick(); fixture.detectChanges(); // Check pinned state diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts index 33f3d7a86ab..5a885124a4f 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts @@ -1,4 +1,4 @@ -import { TestBed, waitForAsync , tick } from '@angular/core/testing'; +import { TestBed, waitForAsync } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Component, ViewChild, DebugElement} from '@angular/core'; import { IgxChildGridRowComponent, IgxHierarchicalGridComponent } from './hierarchical-grid.component'; @@ -220,7 +220,6 @@ describe('IgxHierarchicalGrid Navigation', () => { fixture.detectChanges(); childGrid.dataRowList.toArray()[4].expander.nativeElement.click(); - tick(); fixture.detectChanges(); await wait(); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts index 14e8a9f2773..f940b75572f 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts @@ -1180,7 +1180,6 @@ describe('IgxHierarchicalGrid selection #hGrid', () => { fix.detectChanges(); firstRow.toggle(); - tick(); fix.detectChanges(); firstRow.onClick(UIInteractions.getMouseEvent('click')); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts index 2d275486ec0..153afd981d6 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts @@ -1879,7 +1879,6 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { expect((childGrid as any).headerHierarchyExpander.nativeElement.innerText).toBe('COLLAPSED'); childRows[0].toggle(); - tick(); fixture.detectChanges(); expect((childGrid as any).headerHierarchyExpander.nativeElement.innerText).toBe('EXPANDED'); hierarchicalGrid.expandChildren = false; diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts index c66cd2327a7..223899f40d7 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts @@ -859,12 +859,10 @@ describe('IgxPivotGrid #pivotGrid', () => { const checkboxes = GridFunctions.getExcelStyleFilteringCheckboxes(fixture, excelMenu, 'igx-tree-grid'); // uncheck Accessories checkboxes[4].click(); - tick(); fixture.detectChanges(); // uncheck Bikes checkboxes[3].click(); - tick(); fixture.detectChanges(); // Click 'apply' button to apply filter. @@ -894,12 +892,10 @@ describe('IgxPivotGrid #pivotGrid', () => { // uncheck Bulgaria checkboxes[1].click(); - tick(); fixture.detectChanges(); // uncheck Uruguay checkboxes[3].click(); - tick(); fixture.detectChanges(); @@ -1042,12 +1038,10 @@ describe('IgxPivotGrid #pivotGrid', () => { const checkBoxes: any[] = Array.from(GridFunctions.getExcelStyleFilteringCheckboxes(fixture, excelMenu, 'igx-pivot-grid')); // uncheck David checkBoxes[4].click(); - tick(); fixture.detectChanges(); // uncheck Lydia checkBoxes[3].click(); - tick(); fixture.detectChanges(); // Click 'apply' button to apply filter. @@ -3402,7 +3396,6 @@ describe('IgxPivotGrid #pivotGrid', () => { const sortIcon = productsHeaderColumn.querySelectorAll('igx-icon')[0]; sortIcon.click(); - tick(); fixture.detectChanges(); sortIcon.click(); fixture.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts index 492376c962c..bca74571c50 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts @@ -816,7 +816,6 @@ describe('IgxQueryBuilder', () => { QueryBuilderFunctions.verifyEditModeExpressionInputStates(fix, true, true, true, false); const input = QueryBuilderFunctions.getQueryBuilderValueInput(fix, true) as HTMLElement; input.click(); - tick(); fix.detectChanges(); // Click on 'today' item in calendar. @@ -1018,7 +1017,6 @@ describe('IgxQueryBuilder', () => { const closeBtn = QueryBuilderFunctions.getQueryBuilderExpressionCloseButton(fix); closeBtn.click(); - tick(); fix.detectChanges(); } })); @@ -1388,7 +1386,6 @@ describe('IgxQueryBuilder', () => { const confirmButton = Array.from(dialogOutlet.querySelectorAll('button'))[1]; expect(confirmButton.innerText).toEqual('Confirm'); confirmButton.click(); - tick(); fix.detectChanges(); QueryBuilderFunctions.clickQueryBuilderInitialAddConditionBtn(fix, 0); @@ -1686,7 +1683,6 @@ describe('IgxQueryBuilder', () => { // Click on the 'commit' button const commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); commitBtn.click(); - tick(); fix.detectChanges(); tick(100); fix.detectChanges(); @@ -1701,7 +1697,6 @@ describe('IgxQueryBuilder', () => { // Click on the 'discard' button const closeBtn = QueryBuilderFunctions.getQueryBuilderExpressionCloseButton(fix); closeBtn.click(); - tick(); fix.detectChanges(); tick(100); fix.detectChanges(); @@ -1728,7 +1723,6 @@ describe('IgxQueryBuilder', () => { // Click on the 'commit' button const commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); commitBtn.click(); - tick(); fix.detectChanges(); tick(100); fix.detectChanges(); @@ -1759,7 +1753,6 @@ describe('IgxQueryBuilder', () => { // Click on the 'commit' button const commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); commitBtn.click(); - tick(); fix.detectChanges(); tick(300); fix.detectChanges(); @@ -1786,7 +1779,6 @@ describe('IgxQueryBuilder', () => { // Click on the 'close' button const closeBtn = QueryBuilderFunctions.getQueryBuilderExpressionCloseButton(fix); closeBtn.click(); - tick(); fix.detectChanges(); tick(300); fix.detectChanges(); @@ -2398,7 +2390,6 @@ describe('IgxQueryBuilder', () => { // Add new expression const btn = QueryBuilderFunctions.getQueryBuilderTreeRootGroupButtons(fixture, 0)[0] as HTMLElement; btn.click(); - tick(); fixture.detectChanges(); // Populate edit inputs. diff --git a/projects/igniteui-angular/src/lib/select/select.component.spec.ts b/projects/igniteui-angular/src/lib/select/select.component.spec.ts index 0679f7dba55..76a525181e9 100644 --- a/projects/igniteui-angular/src/lib/select/select.component.spec.ts +++ b/projects/igniteui-angular/src/lib/select/select.component.spec.ts @@ -206,7 +206,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); - tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -220,7 +219,6 @@ describe('igxSelect', () => { spyOn(select.selectionChanging, 'emit'); select.items[1].selected = true; select.open(); - tick(); fixture.detectChanges(); const selectedItemEl = selectList.children[1]; expect(select.collapsed).toBeFalsy(); @@ -230,7 +228,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.open(); - tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); selectedItemEl.nativeElement.click(); @@ -259,7 +256,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.open(); - tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -269,7 +265,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); - tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -487,7 +482,6 @@ describe('igxSelect', () => { const dummyInput = fixture.componentInstance.dummyInput.nativeElement; expect(select.collapsed).toBeTruthy(); select.toggle(); - tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -1646,7 +1640,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); - tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -1656,7 +1649,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); - tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); inputElement.triggerEventHandler('keydown', tabKeyEvent); @@ -1963,7 +1955,6 @@ describe('igxSelect', () => { it('should filter and navigate through items on character key navigation when dropdown is opened', fakeAsync(() => { select.open(); - tick(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('pa'); @@ -1983,7 +1974,6 @@ describe('igxSelect', () => { it('Character key navigation when dropdown is opened should be case insensitive', fakeAsync(() => { select.open(); - tick(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('l'); @@ -2003,7 +1993,6 @@ describe('igxSelect', () => { it('Character key navigation when dropdown is opened should wrap selection', fakeAsync(() => { select.open(); - tick(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('l'); @@ -2039,7 +2028,6 @@ describe('igxSelect', () => { 'Östringen']; fixture.detectChanges(); select.open(); - tick(); fixture.detectChanges(); // German characters diff --git a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts index 588bf190c8b..e64423138d3 100644 --- a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts @@ -653,7 +653,6 @@ describe('IgxSimpleCombo', () => { })); it('should render placeholder values for inputs properly', () => { combo.toggle(); - tick(); fixture.detectChanges(); expect(combo.collapsed).toBeFalsy(); expect(combo.placeholder).toEqual('Location'); @@ -1182,7 +1181,6 @@ describe('IgxSimpleCombo', () => { it('should select an item from the dropdown list with the Space key without closing it', () => { combo.open(); - tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1202,7 +1200,6 @@ describe('IgxSimpleCombo', () => { it('should close the dropdown list on pressing Tab key', fakeAsync(() => { combo.open(); - tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1309,7 +1306,6 @@ describe('IgxSimpleCombo', () => { fixture.componentInstance.allowCustomValues = true; fixture.detectChanges(); combo.open(); - tick(); fixture.detectChanges(); UIInteractions.setInputElementValue(input.nativeElement, 'Massachuset'); fixture.detectChanges(); @@ -1335,7 +1331,6 @@ describe('IgxSimpleCombo', () => { UIInteractions.setInputElementValue(input.nativeElement, 'MassachusettsL'); fixture.detectChanges(); combo.open(); - tick(); fixture.detectChanges(); const addItemButton = fixture.debugElement.query(By.css(`.${CSS_CLASS_ADDBUTTON}`)); expect(addItemButton).toBeDefined(); @@ -1396,7 +1391,6 @@ describe('IgxSimpleCombo', () => { it('should close the dropdown with Alt + ArrowUp', fakeAsync(() => { combo.open(); - tick(); fixture.detectChanges(); spyOn(combo, 'close').and.callThrough(); @@ -1837,7 +1831,6 @@ describe('IgxSimpleCombo', () => { fixture.detectChanges(); combo.open(); - tick(); fixture.detectChanges(); expect(combo.collapsed).toEqual(false); expect(combo.overlaySettings.positionStrategy.settings.verticalDirection).toBe(-1); @@ -1881,7 +1874,6 @@ describe('IgxSimpleCombo', () => { fixture.detectChanges(); dropdown.toggle(); - tick(); fixture.detectChanges(); UIInteractions.simulateTyping('Ohio ', input); @@ -2445,7 +2437,6 @@ describe('IgxSimpleCombo', () => { let model; combo.open(); - tick(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2741,7 +2732,6 @@ describe('IgxSimpleCombo', () => { input = fixture.debugElement.query(By.css(`.${CSS_CLASS_COMBO_INPUTGROUP}`)); combo.open(); - tick(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); diff --git a/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts b/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts index b94616ff73b..aec6b388b6c 100644 --- a/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts @@ -258,7 +258,6 @@ export class GridFunctions { const rowDE = fix.debugElement.queryAll(By.directive(IgxRowDirective)).find(el => el.componentInstance === row); const expandCellDE = rowDE.query(By.directive(IgxGridExpandableCellComponent)); expandCellDE.componentInstance.toggle(new MouseEvent('click')); - tick(); fix.detectChanges(); } diff --git a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts index 581a76ca017..8eafb66af26 100644 --- a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts +++ b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts @@ -570,7 +570,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -587,7 +586,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -630,7 +628,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -810,7 +807,6 @@ describe('IgxTimePicker', () => { secondsColumn = fixture.debugElement.query(By.css(CSS_CLASS_SECONDSLIST)); timePicker.open(); - tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -862,7 +858,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - tick(); fixture.detectChanges(); secondsColumn = fixture.debugElement.query(By.css(CSS_CLASS_SECONDSLIST)); expect(timePicker.collapsed).toBeFalsy(); @@ -1095,7 +1090,6 @@ describe('IgxTimePicker', () => { timePicker.mode = "dialog"; timePicker.open(); - tick(); fixture.detectChanges(); const amElement = ampmColumn.query(e => e.nativeElement.textContent === 'AM'); From 049fa5087b6ea8b784c28194193c37ce37793d49 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 11:47:31 +0000 Subject: [PATCH 4/6] Fix toggle directive with requestAnimationFrame and update tests with flush() Co-authored-by: wnvko <5990334+wnvko@users.noreply.github.com> --- .../src/lib/combo/combo.component.spec.ts | 45 ++++++++++++ .../src/lib/dialog/dialog.component.spec.ts | 10 +++ .../autocomplete.directive.spec.ts | 2 + .../toggle/toggle.directive.spec.ts | 19 ++++- .../lib/directives/toggle/toggle.directive.ts | 40 ++++++----- .../lib/drop-down/drop-down.component.spec.ts | 45 ++++++++++++ .../hierarchical-grid.integration.spec.ts | 2 + .../hierarchical-grid.selection.spec.ts | 1 + .../hierarchical-grid.spec.ts | 1 + .../query-builder.component.spec.ts | 2 +- .../src/lib/select/select.component.spec.ts | 70 +++++++++++++++++++ .../simple-combo.component.spec.ts | 26 +++++++ .../src/lib/test-utils/toggle-helpers.spec.ts | 32 +++++++++ .../time-picker/time-picker.component.spec.ts | 28 +++++++- .../src/lib/toast/toast.component.spec.ts | 2 + 15 files changed, 301 insertions(+), 24 deletions(-) create mode 100644 projects/igniteui-angular/src/lib/test-utils/toggle-helpers.spec.ts diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index 5345bc34424..6cfca7b4a55 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -1064,6 +1064,7 @@ describe('igxCombo', () => { expect(dropdown.nativeElement.getAttribute('aria-labelledby')).toEqual(combo.placeholder); combo.open(); + flush(); tick(); fixture.detectChanges(); @@ -1088,6 +1089,7 @@ describe('igxCombo', () => { it('should render aria-expanded attribute properly', fakeAsync(() => { expect(input.nativeElement.getAttribute('aria-expanded')).toMatch('false'); combo.open(); + flush(); tick(); fixture.detectChanges(); expect(input.nativeElement.getAttribute('aria-expanded')).toMatch('true'); @@ -1098,6 +1100,7 @@ describe('igxCombo', () => { })); it('should render placeholder values for inputs properly', () => { combo.toggle(); + flush(); fixture.detectChanges(); expect(combo.collapsed).toBeFalsy(); expect(combo.placeholder).toEqual('Location'); @@ -1126,6 +1129,7 @@ describe('igxCombo', () => { fixture.componentInstance.size = "large"; fixture.detectChanges(); combo.toggle(); + flush(); tick(); fixture.detectChanges(); const dropdownItems = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`)); @@ -1168,6 +1172,7 @@ describe('igxCombo', () => { let scrollIndex = 0; const headers: Array = Array.from(new Set(combo.data.map(item => item.region))); combo.toggle(); + flush(); fixture.detectChanges(); const checkGroupedItemsClass = () => { fixture.detectChanges(); @@ -1242,6 +1247,7 @@ describe('igxCombo', () => { }); it('should focus search input', fakeAsync(() => { combo.toggle(); + flush(); tick(); fixture.detectChanges(); expect(document.activeElement).toEqual(combo.searchInput.nativeElement); @@ -1249,6 +1255,7 @@ describe('igxCombo', () => { it('should not focus search input, when autoFocusSearch=false', fakeAsync(() => { combo.autoFocusSearch = false; combo.toggle(); + flush(); tick(); fixture.detectChanges(); expect(document.activeElement).not.toEqual(combo.searchInput.nativeElement); @@ -1267,6 +1274,7 @@ describe('igxCombo', () => { expect(headerElement).toBeNull(); expect(footerElement).toBeNull(); combo.toggle(); + flush(); fixture.detectChanges(); expect(combo.headerTemplate).toBeDefined(); expect(combo.footerTemplate).toBeDefined(); @@ -1286,12 +1294,14 @@ describe('igxCombo', () => { combo.showSearchCaseIcon = true; fixture.detectChanges(); combo.toggle(); + flush(); fixture.detectChanges(); let caseSensitiveIcon = fixture.debugElement.query(By.css('igx-icon[name=\'case-sensitive\']')); expect(caseSensitiveIcon).toBeDefined(); combo.toggle(); + flush(); fixture.detectChanges(); combo.showSearchCaseIcon = false; fixture.detectChanges(); @@ -1345,6 +1355,7 @@ describe('igxCombo', () => { expect(containerElementWidth).toEqual(wrapperWidth); combo.toggle(); + flush(); tick(); fixture.detectChanges(); const inputElement = fixture.debugElement.query(By.css(`.${CSS_CLASS_INPUTGROUP_WRAPPER}`)).nativeElement; @@ -1370,6 +1381,7 @@ describe('igxCombo', () => { expect(wrapperWidth).toEqual(comboWidth); combo.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -1385,6 +1397,7 @@ describe('igxCombo', () => { expect(inputWidth).toEqual(comboWidth); combo.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -1393,6 +1406,7 @@ describe('igxCombo', () => { fixture.detectChanges(); combo.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -1668,6 +1682,7 @@ describe('igxCombo', () => { expect(dropdown.focusedItem).toEqual(null); expect(combo.collapsed).toBeTruthy(); combo.toggle(); + flush(); tick(); fixture.detectChanges(); expect(document.activeElement).toEqual(combo.searchInput.nativeElement); @@ -1784,6 +1799,7 @@ describe('igxCombo', () => { }); it('should properly handle dropdown.focusItem', fakeAsync(() => { combo.toggle(); + flush(); tick(); fixture.detectChanges(); const virtualSpyUP = spyOn(dropdown, 'navigatePrev'); @@ -1802,6 +1818,7 @@ describe('igxCombo', () => { })); it('should handle keyboard events', fakeAsync(() => { combo.toggle(); + flush(); tick(); fixture.detectChanges(); spyOn(combo, 'selectAllItems'); @@ -1865,6 +1882,7 @@ describe('igxCombo', () => { it('should select/focus dropdown list items with space/up and down arrow keys', () => { let selectedItemsCount = 0; combo.toggle(); + flush(); fixture.detectChanges(); const dropdownList = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROPDOWNLIST_SCROLL}`)).nativeElement; @@ -1946,6 +1964,7 @@ describe('igxCombo', () => { })); it('should close the dropdown list on pressing Tab key', fakeAsync(() => { combo.toggle(); + flush(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1963,6 +1982,7 @@ describe('igxCombo', () => { input = fixture.debugElement.query(By.css(`.${CSS_CLASS_INPUTGROUP}`)); let firstVisibleItem: Element; combo.toggle(); + flush(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); const scrollbar = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLLBAR_VERTICAL}`)) @@ -2302,6 +2322,7 @@ describe('igxCombo', () => { it('should clear the selection on Enter of the focused clear icon', () => { const selectedItem_1 = combo.dropdown.items[1]; combo.toggle(); + flush(); fixture.detectChanges(); simulateComboItemClick(1); expect(combo.selection[0]).toEqual(selectedItem_1.value); @@ -2317,6 +2338,7 @@ describe('igxCombo', () => { it('should not be able to select group header', () => { spyOn(combo.selectionChanging, 'emit').and.callThrough(); combo.toggle(); + flush(); fixture.detectChanges(); simulateComboItemClick(0, true); @@ -2454,6 +2476,7 @@ describe('igxCombo', () => { const dropdown = combo.dropdown; dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -2471,6 +2494,7 @@ describe('igxCombo', () => { tick(); fixture.detectChanges(); combo.toggle(); + flush(); tick(); fixture.detectChanges(); combo.onBlur(); @@ -2481,6 +2505,7 @@ describe('igxCombo', () => { it('should prevent selection when selectionChanging is cancelled', () => { spyOn(combo.selectionChanging, 'emit').and.callFake((event: IComboSelectionChangingEventArgs) => event.cancel = true); combo.toggle(); + flush(); fixture.detectChanges(); const dropdownFirstItem = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[0].nativeElement; @@ -2603,6 +2628,7 @@ describe('igxCombo', () => { }); it('should group items correctly', fakeAsync(() => { combo.toggle(); + flush(); tick(); fixture.detectChanges(); expect(combo.groupKey).toEqual('region'); @@ -2621,6 +2647,7 @@ describe('igxCombo', () => { it('should properly handle click events on disabled/header items', fakeAsync(() => { spyOn(combo.dropdown, 'selectItem').and.callThrough(); combo.toggle(); + flush(); tick(); fixture.detectChanges(); expect(combo.collapsed).toBeFalsy(); @@ -2642,6 +2669,7 @@ describe('igxCombo', () => { it('should properly add items to the defaultFallbackGroup', () => { combo.allowCustomValues = true; combo.toggle(); + flush(); fixture.detectChanges(); const fallBackGroup = combo.defaultFallbackGroup; const initialDataLength = combo.data.length + 0; @@ -2663,6 +2691,7 @@ describe('igxCombo', () => { it('should sort groups correctly', () => { combo.groupSortingDirection = SortingDirection.Asc; combo.toggle(); + flush(); fixture.detectChanges(); expect(combo.dropdown.headers[0].element.nativeElement.innerText).toEqual('East North Central'); @@ -2847,6 +2876,7 @@ describe('igxCombo', () => { combo.filteringOptions = { caseSensitive: false, filteringKey: undefined }; combo.data = ['José', 'Óscar', 'Ángel', 'Germán', 'Niño', 'México', 'Méxícó', 'Mexico', 'Köln', 'München']; combo.toggle(); + flush(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(`input[name="searchInput"]`)); @@ -2878,6 +2908,7 @@ describe('igxCombo', () => { }; combo.toggle(); + flush(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css('input[name=\'searchInput\']')); const verifyFilteredItems = (inputValue: string, expectedItemsNumber) => { @@ -2903,6 +2934,7 @@ describe('igxCombo', () => { let dropDownContainer: HTMLElement; let listItems; combo.toggle(); + flush(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); @@ -2966,6 +2998,7 @@ describe('igxCombo', () => { }); it('should clear the search input and close the dropdown list on pressing ESC key', fakeAsync(() => { combo.toggle(); + flush(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); @@ -2989,6 +3022,7 @@ describe('igxCombo', () => { return filteredArray; }, {}); combo.toggle(); + flush(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); UIInteractions.triggerInputEvent(searchInput, 'Mi'); @@ -3003,6 +3037,7 @@ describe('igxCombo', () => { combo.allowCustomValues = true; fixture.detectChanges(); combo.toggle(); + flush(); fixture.detectChanges(); expect(combo.selection).toEqual([]); expect(combo.displayValue).toEqual(''); @@ -3105,6 +3140,7 @@ describe('igxCombo', () => { }); it('should enable/disable filtering at runtime', fakeAsync(() => { combo.open(); // Open combo - all data items are in filteredData + flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3122,6 +3158,7 @@ describe('igxCombo', () => { combo.disableFiltering = true; // Filtering is disabled fixture.detectChanges(); combo.open(); // All items are visible since filtering is disabled + flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); // All items are visible since filtering is disabled @@ -3137,6 +3174,7 @@ describe('igxCombo', () => { combo.disableFiltering = false; // Filtering is re-enabled fixture.detectChanges(); combo.open(); // Filter is cleared on open + flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3148,6 +3186,7 @@ describe('igxCombo', () => { expect(combo.isAddButtonVisible()).toEqual(false); combo.toggle(); + flush(); fixture.detectChanges(); expect(combo.collapsed).toEqual(false); expect(combo.searchInput.nativeElement.placeholder).toEqual('Add Item'); @@ -3188,6 +3227,7 @@ describe('igxCombo', () => { }); it('Should filter the data when custom filterFunction is provided', fakeAsync(() => { combo.open(); + flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3210,6 +3250,7 @@ describe('igxCombo', () => { i[filteringOptions.filteringKey]?.toString().toLowerCase().includes(searchTerm)) } combo.open(); + flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3226,6 +3267,7 @@ describe('igxCombo', () => { })); it('Should update filtering when custom filterFunction is provided and filteringOptions.caseSensitive is changed', fakeAsync(() => { combo.open(); + flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3248,6 +3290,7 @@ describe('igxCombo', () => { i[filteringOptions.filteringKey]?.toString().toLowerCase().includes(searchTerm)) } combo.open(); + flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3263,6 +3306,7 @@ describe('igxCombo', () => { })); it('Should update filtering when custom filteringOptions are provided', fakeAsync(() => { combo.open(); + flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3277,6 +3321,7 @@ describe('igxCombo', () => { fixture.detectChanges(); combo.filteringOptions = { caseSensitive: false, filteringKey: combo.groupKey }; combo.open(); + flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); diff --git a/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts b/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts index 8b32c55e33c..2f696d7c664 100644 --- a/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts +++ b/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts @@ -182,6 +182,7 @@ describe('Dialog', () => { const dialog = fixture.componentInstance.dialog; dialog.open(); + flush(); fixture.detectChanges(); const dialogWindow = fixture.debugElement.query(By.css('.igx-dialog__window')); @@ -214,6 +215,7 @@ describe('Dialog', () => { expect(dialog.isOpen).toEqual(false); dialog.open(); + flush(); fixture.detectChanges(); tick(); expect(dialog.isOpen).toEqual(true); @@ -229,6 +231,7 @@ describe('Dialog', () => { fixture.detectChanges(); const dialog = fixture.componentInstance.dialog; dialog.open(); + flush(); tick(); fixture.detectChanges(); @@ -241,6 +244,7 @@ describe('Dialog', () => { dialog.closeOnOutsideSelect = false; dialog.open(); + flush(); tick(); fixture.detectChanges(); @@ -270,6 +274,7 @@ describe('Dialog', () => { spyOn(dialog.closed, 'emit'); dialog.open(); + flush(); tick(); fixture.detectChanges(); @@ -287,6 +292,7 @@ describe('Dialog', () => { expect(dialog.isOpenChange.emit).toHaveBeenCalledWith(false); dialog.open(); + flush(); tick(); fixture.detectChanges(); const buttons = document.querySelectorAll('button'); @@ -330,9 +336,11 @@ describe('Dialog', () => { const childDialog = fixture.componentInstance.child; mainDialog.open(); + flush(); tick(); childDialog.open(); + flush(); tick(); fixture.detectChanges(); @@ -367,6 +375,7 @@ describe('Dialog', () => { const dialog = fixture.componentInstance.dialog; dialog.open(); + flush(); fixture.detectChanges(); const dialogWindow = fixture.debugElement.query(By.css('.igx-dialog__window')); @@ -387,6 +396,7 @@ describe('Dialog', () => { const dialog = fix.componentInstance.dialog; dialog.open(); + flush(); tick(); fix.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts index 882f7c6ac61..436d9a60e31 100644 --- a/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts @@ -65,6 +65,7 @@ describe('IgxAutocomplete', () => { expect(dropDown.collapsed).toBeTruthy(); autocomplete.open(); + flush(); tick(); fixture.detectChanges(); expect(dropDown.collapsed).toBeFalsy(); @@ -326,6 +327,7 @@ describe('IgxAutocomplete', () => { expect(autocomplete.target.open).toHaveBeenCalledTimes(0); autocomplete.open(); + flush(); fixture.detectChanges(); expect(dropDown.collapsed).toBeTruthy(); expect(dropdownListScrollElement.children.length).toEqual(0); diff --git a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts index 8180148ca75..1dbeb1f3d85 100644 --- a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts @@ -3,6 +3,7 @@ import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { IgxToggleActionDirective, IgxToggleDirective, IgxOverlayOutletDirective } from './toggle.directive'; +import { waitForToggleOpen } from '../../test-utils/toggle-helpers.spec'; import { IgxOverlayService, OverlaySettings, ConnectedPositioningStrategy, AbsoluteScrollStrategy, AutoPositionStrategy, HorizontalAlignment @@ -61,7 +62,7 @@ describe('IgxToggle', () => { expect(divEl.classList.contains(TOGGLER_CLASS)).toBeTruthy(); }); - it('should emit \'opening\' and \'opened\' events', fakeAsync(() => { + it('should emit \'opening\' and \'opened\' events', async () => { const fixture = TestBed.createComponent(IgxToggleTestComponent); fixture.detectChanges(); @@ -69,12 +70,12 @@ describe('IgxToggle', () => { spyOn(toggle.opening, 'emit'); spyOn(toggle.opened, 'emit'); toggle.open(); - tick(); + await fixture.whenRenderingDone(); fixture.detectChanges(); expect(toggle.opening.emit).toHaveBeenCalled(); expect(toggle.opened.emit).toHaveBeenCalled(); - })); + }); it('should emit \'appended\' event', fakeAsync(() => { const fixture = TestBed.createComponent(IgxToggleTestComponent); @@ -83,6 +84,7 @@ describe('IgxToggle', () => { const toggle = fixture.componentInstance.toggle; spyOn(toggle.appended, 'emit'); toggle.open(); + TestBed.flushEffects(); tick(); fixture.detectChanges(); @@ -92,6 +94,7 @@ describe('IgxToggle', () => { tick(); fixture.detectChanges(); toggle.open(); + TestBed.flushEffects(); tick(); fixture.detectChanges(); @@ -104,6 +107,7 @@ describe('IgxToggle', () => { const toggle = fixture.componentInstance.toggle; fixture.componentInstance.toggle.open(); + TestBed.flushEffects(); tick(); fixture.detectChanges(); @@ -127,6 +131,7 @@ describe('IgxToggle', () => { spyOn(toggle.closed, 'emit'); toggle.open(); + TestBed.flushEffects(); tick(); expect(toggle.opened.emit).toHaveBeenCalledTimes(1); expect(toggle.collapsed).toBe(false); @@ -136,6 +141,7 @@ describe('IgxToggle', () => { expect(toggle.collapsed).toBe(true); toggle.open(); + TestBed.flushEffects(); tick(); expect(toggle.opened.emit).toHaveBeenCalledTimes(2); const otherId = overlay.attach(fixture.componentInstance.other); @@ -170,6 +176,7 @@ describe('IgxToggle', () => { const fixture = TestBed.createComponent(IgxToggleActionTestComponent); fixture.detectChanges(); fixture.componentInstance.toggle.open(); + TestBed.flushEffects(); tick(); const divEl = fixture.debugElement.query(By.directive(IgxToggleDirective)).nativeElement; @@ -292,6 +299,7 @@ describe('IgxToggle', () => { toggle.closing.pipe(first()).subscribe((e: CancelableEventArgs) => e.cancel = cancelClosing); toggle.open(); + TestBed.flushEffects(); fixture.detectChanges(); tick(); @@ -315,6 +323,7 @@ describe('IgxToggle', () => { toggle.opening.subscribe((e: CancelableEventArgs) => e.cancel = true); toggle.open(); + TestBed.flushEffects(); fixture.detectChanges(); tick(); @@ -429,6 +438,7 @@ describe('IgxToggle', () => { spyOn(toggle.opening, 'emit'); spyOn(toggle.opened, 'emit'); toggle.open(); + TestBed.flushEffects(); tick(); fixture.detectChanges(); @@ -436,6 +446,7 @@ describe('IgxToggle', () => { expect(toggle.opened.emit).toHaveBeenCalledTimes(1); toggle.open(); + TestBed.flushEffects(); tick(); fixture.detectChanges(); @@ -451,6 +462,7 @@ describe('IgxToggle', () => { spyOn(toggle.opening, 'emit'); spyOn(toggle.opened, 'emit'); toggle.open(); + TestBed.flushEffects(); tick(); fixture.detectChanges(); @@ -487,6 +499,7 @@ describe('IgxToggle', () => { spyOn(toggle.closed, 'emit').and.callThrough(); toggle.open(); + TestBed.flushEffects(); tick(); fixture.detectChanges(); expect(toggle.opening.emit).toHaveBeenCalledTimes(1); diff --git a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts index a2711bdece0..902791334c2 100644 --- a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts @@ -229,26 +229,28 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy { this._collapsed = false; this.cdr.detectChanges(); - // Call detectChanges twice to ensure host bindings are updated in post-Ivy Angular - this.cdr.detectChanges(); - - if (!info) { - this.unsubscribe(); - this.subscribe(); - this._overlayId = this.overlayService.attach(this.elementRef, overlaySettings); - } - const args: ToggleViewCancelableEventArgs = { cancel: false, owner: this, id: this._overlayId }; - this.opening.emit(args); - if (args.cancel) { - this.unsubscribe(); - this.overlayService.detach(this._overlayId); - this._collapsed = true; - delete this._overlayId; - this.cdr.detectChanges(); - return; - } - this.overlayService.show(this._overlayId, overlaySettings); + // Use requestAnimationFrame to defer until after host bindings update + // This works in both production and tests (with flush() in fakeAsync) + requestAnimationFrame(() => { + if (!info) { + this.unsubscribe(); + this.subscribe(); + this._overlayId = this.overlayService.attach(this.elementRef, overlaySettings); + } + + const args: ToggleViewCancelableEventArgs = { cancel: false, owner: this, id: this._overlayId }; + this.opening.emit(args); + if (args.cancel) { + this.unsubscribe(); + this.overlayService.detach(this._overlayId); + this._collapsed = true; + delete this._overlayId; + this.cdr.detectChanges(); + return; + } + this.overlayService.show(this._overlayId, overlaySettings); + }); } /** diff --git a/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts b/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts index 929857abe5d..40ed2496fe2 100644 --- a/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts +++ b/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts @@ -202,6 +202,7 @@ describe('IgxDropDown ', () => { expect(dropdown.collapsed).toBeTruthy(); dropdown.open(); + flush(); tick(); fixture.detectChanges(); expect(dropdown.collapsed).toBeFalsy(); @@ -220,6 +221,7 @@ describe('IgxDropDown ', () => { spyOn(dropdown.opened, 'emit').and.callThrough(); dropdown.open(); + flush(); tick(); fixture.detectChanges(); @@ -227,6 +229,7 @@ describe('IgxDropDown ', () => { expect(dropdown.opened.emit).toHaveBeenCalledTimes(1); dropdown.open(); + flush(); tick(); fixture.detectChanges(); @@ -239,6 +242,7 @@ describe('IgxDropDown ', () => { spyOn(toggle, 'open').and.callThrough(); dropdown.open(); + flush(); fixture.detectChanges(); expect(toggle.open).toHaveBeenCalledTimes(1); @@ -293,6 +297,7 @@ describe('IgxDropDown ', () => { dropdown.closing.pipe(take(1)).subscribe((e: CancelableEventArgs) => e.cancel = true); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -300,6 +305,7 @@ describe('IgxDropDown ', () => { expect(dropdown.opened.emit).toHaveBeenCalledTimes(1); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -313,6 +319,7 @@ describe('IgxDropDown ', () => { dropdown.opening.pipe(take(1)).subscribe((e: CancelableEventArgs) => e.cancel = true); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); expect(dropdown.opening.emit).toHaveBeenCalledTimes(1); @@ -320,6 +327,7 @@ describe('IgxDropDown ', () => { })); it('should select item by SPACE/ENTER keys', fakeAsync(() => { dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); let focusedItem = fixture.debugElement.query(By.css(`.${CSS_CLASS_FOCUSED}`)); @@ -342,6 +350,7 @@ describe('IgxDropDown ', () => { expect(dropdown.collapsed).toEqual(true); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); dropdownElement = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROP_DOWN_BASE}`)); @@ -357,6 +366,7 @@ describe('IgxDropDown ', () => { expect(dropdown.selectedItem).toEqual(dropdown.items[2]); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); expect(dropdown.collapsed).toEqual(false); @@ -369,6 +379,7 @@ describe('IgxDropDown ', () => { spyOn(dropdown.closed, 'emit').and.callThrough(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); let focusedItem = fixture.debugElement.query(By.css(`.${CSS_CLASS_FOCUSED}`)); @@ -393,6 +404,7 @@ describe('IgxDropDown ', () => { })); it('should navigate through items using Up/Down/Home/End keys', fakeAsync(() => { dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); const dropdownElement = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROP_DOWN_BASE}`)); @@ -422,6 +434,7 @@ describe('IgxDropDown ', () => { })); it('should not change selection when setting it to non-existing item', fakeAsync(() => { dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); dropdown.setSelectedItem(0); @@ -463,6 +476,7 @@ describe('IgxDropDown ', () => { dropdown.items[10].selected = true; fixture.detectChanges(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -478,6 +492,7 @@ describe('IgxDropDown ', () => { })); it('should set isSelected via igxDropDownIteComponent', fakeAsync(() => { dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); expect(dropdown.selectedItem).toBeNull(); @@ -497,6 +512,7 @@ describe('IgxDropDown ', () => { expect(dropdown.selectedItem.itemIndex).toEqual(1); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); expect(dropdown.selectedItem.itemIndex).toEqual(1); @@ -510,6 +526,7 @@ describe('IgxDropDown ', () => { dropdown.items[10].isHeader = true; fixture.detectChanges(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -537,6 +554,7 @@ describe('IgxDropDown ', () => { expect(dropdown.selectedItem.itemIndex).toEqual(2); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); expect(dropdown.selectedItem.itemIndex).toEqual(2); @@ -545,6 +563,7 @@ describe('IgxDropDown ', () => { spyOn(dropdown.selectionChanging, 'emit').and.callThrough(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -576,6 +595,7 @@ describe('IgxDropDown ', () => { const dropdownElement = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROP_DOWN_BASE}`)); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); let focusedItem = fixture.debugElement.query(By.css(`.${CSS_CLASS_FOCUSED}`)); @@ -595,6 +615,7 @@ describe('IgxDropDown ', () => { expect((eventArgs.event as KeyboardEvent).key).toEqual('escape'); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); focusedItem = fixture.debugElement.query(By.css(`.${CSS_CLASS_FOCUSED}`)); @@ -615,6 +636,7 @@ describe('IgxDropDown ', () => { it('should be able to change selection when manipulating ISelectionEventArgs', fakeAsync(() => { expect(dropdown.selectedItem).toEqual(null); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -637,6 +659,7 @@ describe('IgxDropDown ', () => { // Set header - error dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -658,12 +681,14 @@ describe('IgxDropDown ', () => { })); it('should not take focus when allowItemsFocus is set to false', fakeAsync(() => { dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); const focusedItem = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_ITEM}`))[0].nativeElement; expect(document.activeElement).toEqual(focusedItem); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -684,6 +709,7 @@ describe('IgxDropDown ', () => { fixture.detectChanges(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); const currentItem = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DISABLED}`))[0]; @@ -709,6 +735,7 @@ describe('IgxDropDown ', () => { fixture.detectChanges(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); let disabledItems = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DISABLED}`)); @@ -731,6 +758,7 @@ describe('IgxDropDown ', () => { dropdown.items[12].disabled = true; fixture.detectChanges(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -762,6 +790,7 @@ describe('IgxDropDown ', () => { dropdown.items[12].disabled = true; fixture.detectChanges(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -801,6 +830,7 @@ describe('IgxDropDown ', () => { dropdown.setSelectedItem(0); fixture.detectChanges(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); expect(dropdown.items[0].selected).toBeTruthy(); @@ -814,6 +844,7 @@ describe('IgxDropDown ', () => { dropdown.items[10].selected = true; fixture.detectChanges(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); expect(dropdown.items[10].focused).toEqual(true); @@ -852,6 +883,7 @@ describe('IgxDropDown ', () => { fixture.detectChanges(); dropdown.open(); + flush(); fixture.detectChanges(); const itemToClick = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_ITEM}`))[0]; @@ -892,6 +924,7 @@ describe('IgxDropDown ', () => { expect(dropdown.collapsed).toEqual(true); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); expect(dropdown.collapsed).toEqual(false); @@ -1081,6 +1114,7 @@ describe('IgxDropDown ', () => { }); it('should update aria-activedescendant to the id of the focused item', fakeAsync(() => { dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -1093,9 +1127,11 @@ describe('IgxDropDown ', () => { expect(dropdownElement.getAttribute('aria-activedescendant')).toBe(focusedItemId); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -1127,6 +1163,7 @@ describe('IgxDropDown ', () => { const groups = fixture.componentInstance.groups; expect(dropdown.collapsed).toBeTruthy(); dropdown.toggle(); + flush(); fixture.detectChanges(); const groupItems = document.querySelectorAll(`.${CSS_CLASS_GROUP_ITEM}`); for (let i = 0; i < groupItems.length; i++) { @@ -1187,6 +1224,7 @@ describe('IgxDropDown ', () => { }); it('should apply selected item class', fakeAsync(() => { dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); const selectedItem = fixture.debugElement.query(By.css(`.${CSS_CLASS_ITEM}`)); @@ -1220,12 +1258,14 @@ describe('IgxDropDown ', () => { }); it('should return items/headers property correctly', fakeAsync(() => { dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); expect(dropdown.items.length).toEqual(15); expect(dropdown.headers).toEqual([]); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); dropdown.items[0].disabled = true; @@ -1236,6 +1276,7 @@ describe('IgxDropDown ', () => { dropdown.items[10].isHeader = true; fixture.detectChanges(); dropdown.toggle(); + flush(); tick(); fixture.detectChanges(); expect(dropdown.items.length).toEqual(12); @@ -1246,6 +1287,7 @@ describe('IgxDropDown ', () => { fixture.componentInstance.maxHeight = '100px'; fixture.detectChanges(); dropdown.toggle(); + flush(); fixture.detectChanges(); const ddList = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLL}`)).nativeElement; expect(parseInt(ddList.style.maxHeight, 10)).toEqual(ddList.offsetHeight); @@ -1255,6 +1297,7 @@ describe('IgxDropDown ', () => { fixture.componentInstance.maxHeight = '700px'; fixture.detectChanges(); dropdown.toggle(); + flush(); fixture.detectChanges(); const ddList = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLL}`)).nativeElement; expect(parseInt(ddList.style.maxHeight, 10)).toBeGreaterThan(ddList.offsetHeight); @@ -1342,6 +1385,7 @@ describe('IgxDropDown ', () => { it('#15137 - should bind to custom target if provided', fakeAsync(() => { const input = fixture.debugElement.query(By.css('input')); dropdown.open({ target: input.nativeElement }); + flush(); tick(); fixture.detectChanges(); @@ -1357,6 +1401,7 @@ describe('IgxDropDown ', () => { tick(); fixture.detectChanges(); dropdown.open(); + flush(); tick(); fixture.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts index 9b0937c4fcc..40ce6e4e78e 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts @@ -767,6 +767,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { // // Instead of clicking we can just toggle the checkbox // toolbar.columnHidingUI.columnItems.toArray()[2].toggle(); + flush(); // fixture.detectChanges(); // And it should hide the column of the child grid @@ -792,6 +793,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { // Instead of clicking we can just toggle the checkbox // toolbar.columnPinningUI.columnItems.toArray()[1].toggle(); + flush(); fixture.detectChanges(); // Check pinned state diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts index f940b75572f..6d5c484b23f 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts @@ -1180,6 +1180,7 @@ describe('IgxHierarchicalGrid selection #hGrid', () => { fix.detectChanges(); firstRow.toggle(); + flush(); fix.detectChanges(); firstRow.onClick(UIInteractions.getMouseEvent('click')); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts index 153afd981d6..897a332c989 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts @@ -1879,6 +1879,7 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { expect((childGrid as any).headerHierarchyExpander.nativeElement.innerText).toBe('COLLAPSED'); childRows[0].toggle(); + flush(); fixture.detectChanges(); expect((childGrid as any).headerHierarchyExpander.nativeElement.innerText).toBe('EXPANDED'); hierarchicalGrid.expandChildren = false; diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts index bca74571c50..59bd4bfa278 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts @@ -1,4 +1,4 @@ -import { waitForAsync, TestBed, ComponentFixture, fakeAsync, tick, flush } from '@angular/core/testing'; +import { waitForAsync, TestBed, ComponentFixture, fakeAsync, tick} from '@angular/core/testing'; import { FilteringExpressionsTree, FilteringLogic, IExpressionTree, IgxChipComponent, IgxComboComponent, IgxDateFilteringOperand, IgxIconComponent, IgxInputGroupComponent, IgxNumberFilteringOperand, IgxQueryBuilderComponent, IgxQueryBuilderHeaderComponent, IgxQueryBuilderSearchValueTemplateDirective, IgxSelectComponent } from 'igniteui-angular'; import { Component, OnInit, ViewChild } from '@angular/core'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; diff --git a/projects/igniteui-angular/src/lib/select/select.component.spec.ts b/projects/igniteui-angular/src/lib/select/select.component.spec.ts index 76a525181e9..8f481b46c75 100644 --- a/projects/igniteui-angular/src/lib/select/select.component.spec.ts +++ b/projects/igniteui-angular/src/lib/select/select.component.spec.ts @@ -206,6 +206,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); + flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -219,6 +220,7 @@ describe('igxSelect', () => { spyOn(select.selectionChanging, 'emit'); select.items[1].selected = true; select.open(); + flush(); fixture.detectChanges(); const selectedItemEl = selectList.children[1]; expect(select.collapsed).toBeFalsy(); @@ -228,6 +230,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.open(); + flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); selectedItemEl.nativeElement.click(); @@ -256,6 +259,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.open(); + flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -265,10 +269,12 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); + flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); select.toggle(); + flush(); tick(); fixture.detectChanges(); expect(select.collapsed).toBeTruthy(); @@ -325,6 +331,7 @@ describe('igxSelect', () => { const selectedItemEl = selectList.children[2]; select.toggle(); + flush(); tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -369,6 +376,7 @@ describe('igxSelect', () => { expect(select).toBeDefined(); select.toggle(); + flush(); tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -399,6 +407,7 @@ describe('igxSelect', () => { expect(select).toBeDefined(); select.toggle(); + flush(); tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -432,12 +441,14 @@ describe('igxSelect', () => { expect(dropdownWrapper.nativeElement.getAttribute('aria-hidden')).toEqual('true'); select.toggle(); + flush(); tick(); fixture.detectChanges(); expect(inputElement.nativeElement.getAttribute('aria-expanded')).toEqual('true'); expect(dropdownWrapper.nativeElement.getAttribute('aria-hidden')).toEqual('false'); select.toggle(); + flush(); tick(); fixture.detectChanges(); expect(inputElement.nativeElement.getAttribute('aria-expanded')).toEqual('false'); @@ -482,6 +493,7 @@ describe('igxSelect', () => { const dummyInput = fixture.componentInstance.dummyInput.nativeElement; expect(select.collapsed).toBeTruthy(); select.toggle(); + flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -842,6 +854,7 @@ describe('igxSelect', () => { let selectedItemIndex = 5; select.toggle(); + flush(); tick(); fixture.detectChanges(); selectList.children[selectedItemIndex].nativeElement.click(); @@ -851,6 +864,7 @@ describe('igxSelect', () => { selectedItemIndex = 15; select.toggle(); + flush(); tick(); fixture.detectChanges(); selectList.children[selectedItemIndex].nativeElement.click(); @@ -902,6 +916,7 @@ describe('igxSelect', () => { it('should select item with ENTER/SPACE keys', fakeAsync(() => { let selectedItemIndex = 2; select.toggle(); + flush(); tick(); fixture.detectChanges(); inputElement.triggerEventHandler('keydown', arrowDownKeyEvent); @@ -913,6 +928,7 @@ describe('igxSelect', () => { selectedItemIndex = 4; select.toggle(); + flush(); tick(); fixture.detectChanges(); inputElement.triggerEventHandler('keydown', arrowDownKeyEvent); @@ -926,6 +942,7 @@ describe('igxSelect', () => { it('should allow single selection only', fakeAsync(() => { let selectedItemIndex = 5; select.toggle(); + flush(); tick(); fixture.detectChanges(); selectList.children[selectedItemIndex].nativeElement.click(); @@ -966,6 +983,7 @@ describe('igxSelect', () => { const focusedItemIndex = 0; const selectedItemIndex = 8; select.toggle(); + flush(); tick(); fixture.detectChanges(); verifyFocusedItem(focusedItemIndex); @@ -981,6 +999,7 @@ describe('igxSelect', () => { fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); verifyFocusedItem(focusedItemIndex); @@ -1005,6 +1024,7 @@ describe('igxSelect', () => { // Select item - mouse click select.toggle(); + flush(); tick(); fixture.detectChanges(); selectList.children[selectedItemIndex].nativeElement.click(); @@ -1019,6 +1039,7 @@ describe('igxSelect', () => { tick(); fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); checkInputValue(); @@ -1059,6 +1080,7 @@ describe('igxSelect', () => { // Select item - mouse click select.toggle(); + flush(); tick(); fixture.detectChanges(); selectList.children[selectedItemIndex].nativeElement.click(); @@ -1072,6 +1094,7 @@ describe('igxSelect', () => { tick(); fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); checkInputValue(); @@ -1097,6 +1120,7 @@ describe('igxSelect', () => { tick(); fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); expect(select.selectedItem).toBeUndefined(); @@ -1133,6 +1157,7 @@ describe('igxSelect', () => { // Focus item when there is not a selected item select.toggle(); + flush(); tick(); fixture.detectChanges(); navigateDropdownItems(arrowDownKeyEvent); @@ -1146,6 +1171,7 @@ describe('igxSelect', () => { tick(); fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); navigateDropdownItems(arrowUpKeyEvent); @@ -1192,6 +1218,7 @@ describe('igxSelect', () => { let selectedItemIndex = 4; select.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -1250,6 +1277,7 @@ describe('igxSelect', () => { }; select.toggle(); + flush(); tick(); fixture.detectChanges(); selectedItemEl.nativeElement.click(); @@ -1264,6 +1292,7 @@ describe('igxSelect', () => { selectedItemEl = selectList.children[10]; args.newSelection = selectedItem; select.toggle(); + flush(); tick(); fixture.detectChanges(); selectedItemEl.nativeElement.click(); @@ -1460,6 +1489,7 @@ describe('igxSelect', () => { // Select item - mouse click select.toggle(); + flush(); tick(); fixture.detectChanges(); itemElementToSelect.click(); @@ -1472,6 +1502,7 @@ describe('igxSelect', () => { tick(); fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); checkInputValue(); @@ -1523,6 +1554,7 @@ describe('igxSelect', () => { const selectedItemElement = groupElement.children[selectedItemIndex].nativeElement; select.toggle(); + flush(); tick(); fixture.detectChanges(); selectedItemElement.click(); @@ -1577,6 +1609,7 @@ describe('igxSelect', () => { const focusedItemElement = groupElement.children[focusedItemIndex].nativeElement; select.toggle(); + flush(); tick(); fixture.detectChanges(); const focusedItems = fixture.debugElement.queryAll(By.css('.' + CSS_CLASS_FOCUSED_ITEM)); @@ -1640,6 +1673,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); + flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -1649,6 +1683,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); + flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); inputElement.triggerEventHandler('keydown', tabKeyEvent); @@ -1658,6 +1693,7 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); + flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); inputElement.triggerEventHandler('keydown', shiftTabKeysEvent); @@ -1730,6 +1766,7 @@ describe('igxSelect', () => { it('should navigate through dropdown items using Up/Down/Home/End keys', () => { let currentItemIndex = 0; select.toggle(); + flush(); fixture.detectChanges(); inputElement.triggerEventHandler('keydown', arrowDownKeyEvent); @@ -1842,6 +1879,7 @@ describe('igxSelect', () => { fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -1857,6 +1895,7 @@ describe('igxSelect', () => { fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -1955,6 +1994,7 @@ describe('igxSelect', () => { it('should filter and navigate through items on character key navigation when dropdown is opened', fakeAsync(() => { select.open(); + flush(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('pa'); @@ -1974,6 +2014,7 @@ describe('igxSelect', () => { it('Character key navigation when dropdown is opened should be case insensitive', fakeAsync(() => { select.open(); + flush(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('l'); @@ -1993,6 +2034,7 @@ describe('igxSelect', () => { it('Character key navigation when dropdown is opened should wrap selection', fakeAsync(() => { select.open(); + flush(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('l'); @@ -2028,6 +2070,7 @@ describe('igxSelect', () => { 'Östringen']; fixture.detectChanges(); select.open(); + flush(); fixture.detectChanges(); // German characters @@ -2056,6 +2099,7 @@ describe('igxSelect', () => { it('should not change focus when pressing non-matching character and dropdown is opened', fakeAsync(() => { select.open(); + flush(); tick(); fixture.detectChanges(); @@ -2254,6 +2298,7 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2263,11 +2308,13 @@ describe('igxSelect', () => { selectedItemIndex = 2; select.toggle(); + flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2277,11 +2324,13 @@ describe('igxSelect', () => { selectedItemIndex = 0; select.toggle(); + flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2308,6 +2357,7 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2315,11 +2365,13 @@ describe('igxSelect', () => { selectedItemIndex = 5; select.toggle(); + flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2327,11 +2379,13 @@ describe('igxSelect', () => { selectedItemIndex = 9; select.toggle(); + flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2353,6 +2407,7 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2367,6 +2422,7 @@ describe('igxSelect', () => { (select.element as HTMLElement).style.marginTop = '10px'; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2382,6 +2438,7 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2403,6 +2460,7 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2414,6 +2472,7 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2427,6 +2486,7 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2448,6 +2508,7 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); document.documentElement.scrollLeft += 50; @@ -2460,11 +2521,13 @@ describe('igxSelect', () => { selectedItemIndex = 2; select.toggle(); + flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); document.documentElement.scrollLeft += 50; @@ -2477,11 +2540,13 @@ describe('igxSelect', () => { selectedItemIndex = 0; select.toggle(); + flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); document.documentElement.scrollLeft += 50; @@ -2498,6 +2563,7 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); document.documentElement.scrollTop += 20; @@ -2510,11 +2576,13 @@ describe('igxSelect', () => { selectedItemIndex = 2; select.toggle(); + flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); document.documentElement.scrollTop += 20; @@ -2527,11 +2595,13 @@ describe('igxSelect', () => { selectedItemIndex = 0; select.toggle(); + flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); + flush(); tick(); fixture.detectChanges(); document.documentElement.scrollTop += 20; diff --git a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts index e64423138d3..b7b4942d97d 100644 --- a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts @@ -625,6 +625,7 @@ describe('IgxSimpleCombo', () => { expect(dropdownListBox.nativeElement.getAttribute('aria-labelledby')).toEqual(combo.placeholder); combo.open(); + flush(); tick(); fixture.detectChanges(); @@ -643,6 +644,7 @@ describe('IgxSimpleCombo', () => { it('should render aria-expanded attribute properly', fakeAsync(() => { expect(input.nativeElement.getAttribute('aria-expanded')).toMatch('false'); combo.open(); + flush(); tick(); fixture.detectChanges(); expect(input.nativeElement.getAttribute('aria-expanded')).toMatch('true'); @@ -653,6 +655,7 @@ describe('IgxSimpleCombo', () => { })); it('should render placeholder values for inputs properly', () => { combo.toggle(); + flush(); fixture.detectChanges(); expect(combo.collapsed).toBeFalsy(); expect(combo.placeholder).toEqual('Location'); @@ -670,6 +673,7 @@ describe('IgxSimpleCombo', () => { fixture.componentInstance.size = "large"; fixture.detectChanges(); combo.toggle(); + flush(); tick(); fixture.detectChanges(); const dropdownItems = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`)); @@ -709,6 +713,7 @@ describe('IgxSimpleCombo', () => { it('should render focused items properly', () => { const dropdown = combo.dropdown; combo.toggle(); + flush(); fixture.detectChanges(); dropdown.navigateItem(2); // Component is virtualized, so this will focus the ACTUAL 3rd item @@ -934,6 +939,7 @@ describe('IgxSimpleCombo', () => { })); it('should properly assign the resource string to the aria-label of the clear button',() => { combo.toggle(); + flush(); fixture.detectChanges(); combo.select(['Illinois', 'Mississippi', 'Ohio']); @@ -1163,6 +1169,7 @@ describe('IgxSimpleCombo', () => { it('should not close the dropdown on ArrowUp key if the active item is the first one in the list', fakeAsync(() => { combo.open(); + flush(); tick(); fixture.detectChanges(); @@ -1181,6 +1188,7 @@ describe('IgxSimpleCombo', () => { it('should select an item from the dropdown list with the Space key without closing it', () => { combo.open(); + flush(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1200,6 +1208,7 @@ describe('IgxSimpleCombo', () => { it('should close the dropdown list on pressing Tab key', fakeAsync(() => { combo.open(); + flush(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1306,6 +1315,7 @@ describe('IgxSimpleCombo', () => { fixture.componentInstance.allowCustomValues = true; fixture.detectChanges(); combo.open(); + flush(); fixture.detectChanges(); UIInteractions.setInputElementValue(input.nativeElement, 'Massachuset'); fixture.detectChanges(); @@ -1331,6 +1341,7 @@ describe('IgxSimpleCombo', () => { UIInteractions.setInputElementValue(input.nativeElement, 'MassachusettsL'); fixture.detectChanges(); combo.open(); + flush(); fixture.detectChanges(); const addItemButton = fixture.debugElement.query(By.css(`.${CSS_CLASS_ADDBUTTON}`)); expect(addItemButton).toBeDefined(); @@ -1346,6 +1357,7 @@ describe('IgxSimpleCombo', () => { it('should close when an item is clicked on', () => { spyOn(combo, 'close').and.callThrough(); combo.open(); + flush(); fixture.detectChanges(); const item1 = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`)); expect(item1).toBeDefined(); @@ -1358,6 +1370,7 @@ describe('IgxSimpleCombo', () => { it('should retain selection after blurring', () => { combo.open(); + flush(); fixture.detectChanges(); const item1 = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`)); expect(item1).toBeDefined(); @@ -1391,6 +1404,7 @@ describe('IgxSimpleCombo', () => { it('should close the dropdown with Alt + ArrowUp', fakeAsync(() => { combo.open(); + flush(); fixture.detectChanges(); spyOn(combo, 'close').and.callThrough(); @@ -1831,6 +1845,7 @@ describe('IgxSimpleCombo', () => { fixture.detectChanges(); combo.open(); + flush(); fixture.detectChanges(); expect(combo.collapsed).toEqual(false); expect(combo.overlaySettings.positionStrategy.settings.verticalDirection).toBe(-1); @@ -1847,6 +1862,7 @@ describe('IgxSimpleCombo', () => { expect(combo.collapsed).toEqual(true); combo.open(); + flush(); fixture.detectChanges(); expect(combo.collapsed).toEqual(false); expect(combo.overlaySettings.positionStrategy.settings.verticalDirection).toBe(-1); @@ -1874,6 +1890,7 @@ describe('IgxSimpleCombo', () => { fixture.detectChanges(); dropdown.toggle(); + flush(); fixture.detectChanges(); UIInteractions.simulateTyping('Ohio ', input); @@ -1883,6 +1900,7 @@ describe('IgxSimpleCombo', () => { fixture.detectChanges(); combo.toggle(); + flush(); tick(); fixture.detectChanges(); @@ -2122,6 +2140,7 @@ describe('IgxSimpleCombo', () => { it('should not select the first item when combo is focused there is no focus item and Enter is pressed', fakeAsync(() => { combo.open(); + flush(); tick(); fixture.detectChanges(); @@ -2281,6 +2300,7 @@ describe('IgxSimpleCombo', () => { // empty string combo.open(); + flush(); fixture.detectChanges(); const item1 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[2]; item1.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2294,6 +2314,7 @@ describe('IgxSimpleCombo', () => { // null combo.open(); + flush(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2437,6 +2458,7 @@ describe('IgxSimpleCombo', () => { let model; combo.open(); + flush(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2513,6 +2535,7 @@ describe('IgxSimpleCombo', () => { // empty string combo.open(); + flush(); fixture.detectChanges(); const item1 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[2]; item1.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2528,6 +2551,7 @@ describe('IgxSimpleCombo', () => { // null combo.open(); + flush(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2732,6 +2756,7 @@ describe('IgxSimpleCombo', () => { input = fixture.debugElement.query(By.css(`.${CSS_CLASS_COMBO_INPUTGROUP}`)); combo.open(); + flush(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2885,6 +2910,7 @@ describe('IgxSimpleCombo', () => { expect(input.nativeElement.value).toEqual('Product 3'); combo.open(); + flush(); fixture.detectChanges(); const item1 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[5]; item1.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); diff --git a/projects/igniteui-angular/src/lib/test-utils/toggle-helpers.spec.ts b/projects/igniteui-angular/src/lib/test-utils/toggle-helpers.spec.ts new file mode 100644 index 00000000000..31f21290ed5 --- /dev/null +++ b/projects/igniteui-angular/src/lib/test-utils/toggle-helpers.spec.ts @@ -0,0 +1,32 @@ +import { ComponentFixture } from '@angular/core/testing'; + +/** + * Helper function to wait for toggle/dropdown/overlay to open after calling open() or toggle() + * This is needed because the toggle directive uses afterNextRender() which requires + * waiting for the rendering cycle to complete in tests. + * + * @param fixture The component fixture + * @returns Promise that resolves when rendering is done + * + * @example + * ```typescript + * select.open(); + * await waitForToggleOpen(fixture); + * expect(select.collapsed).toBeFalsy(); + * ``` + */ +export async function waitForToggleOpen(fixture: ComponentFixture): Promise { + await fixture.whenRenderingDone(); + fixture.detectChanges(); +} + +/** + * Helper function for fakeAsync tests that need to wait for toggle operations. + * Since afterNextRender() doesn't work in fakeAsync, tests should use async/await instead. + * This function is kept for backwards compatibility but will log a warning. + * + * @deprecated Use async/await with waitForToggleOpen instead of fakeAsync + */ +export function waitForToggleOpenSync(): void { + console.warn('waitForToggleOpenSync called - tests using afterNextRender should use async/await'); +} diff --git a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts index 8eafb66af26..5ef6989a023 100644 --- a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts +++ b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts @@ -1,5 +1,5 @@ import { Component, ViewChild, DebugElement, EventEmitter, QueryList } from '@angular/core'; -import { TestBed, fakeAsync, tick, ComponentFixture, waitForAsync } from '@angular/core/testing'; +import { TestBed, fakeAsync, tick, ComponentFixture, waitForAsync, flush } from '@angular/core/testing'; import { UntypedFormControl, UntypedFormGroup, FormsModule, NgForm, ReactiveFormsModule, Validators } from '@angular/forms'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; @@ -570,6 +570,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -586,6 +587,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -628,6 +630,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -652,6 +655,7 @@ describe('IgxTimePicker', () => { it('should not change the current selection and close the dropdown on OK button click', fakeAsync(() => { timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -672,6 +676,7 @@ describe('IgxTimePicker', () => { it('should close the dropdown and discard the current selection on Cancel button click', fakeAsync(() => { timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -695,6 +700,7 @@ describe('IgxTimePicker', () => { spyOn(timePicker.closed, 'emit').and.callThrough(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -718,6 +724,7 @@ describe('IgxTimePicker', () => { const openingSub = timePicker.opening.subscribe((event) => event.cancel = true); timePicker.open(); + flush(); tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeTruthy(); @@ -729,6 +736,7 @@ describe('IgxTimePicker', () => { const closingSub = timePicker.closing.subscribe((event) => event.cancel = true); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -807,6 +815,7 @@ describe('IgxTimePicker', () => { secondsColumn = fixture.debugElement.query(By.css(CSS_CLASS_SECONDSLIST)); timePicker.open(); + flush(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -858,6 +867,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); fixture.detectChanges(); secondsColumn = fixture.debugElement.query(By.css(CSS_CLASS_SECONDSLIST)); expect(timePicker.collapsed).toBeFalsy(); @@ -1090,6 +1100,7 @@ describe('IgxTimePicker', () => { timePicker.mode = "dialog"; timePicker.open(); + flush(); fixture.detectChanges(); const amElement = ampmColumn.query(e => e.nativeElement.textContent === 'AM'); @@ -1197,6 +1208,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -1211,6 +1223,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -1235,6 +1248,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -1259,6 +1273,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -1331,6 +1346,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -1353,6 +1369,7 @@ describe('IgxTimePicker', () => { expect(inputEl.getAttribute('aria-expanded')).toEqual('false'); timePicker.open(); + flush(); tick(); fixture.detectChanges(); expect(inputEl.getAttribute('aria-expanded')).toEqual('true'); @@ -1392,6 +1409,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -1438,6 +1456,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -1458,6 +1477,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -1479,6 +1499,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -1497,6 +1518,7 @@ describe('IgxTimePicker', () => { secondsColumn = fixture.debugElement.query(By.css(CSS_CLASS_SECONDSLIST)); timePicker.open(); + flush(); tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -1577,6 +1599,7 @@ describe('IgxTimePicker', () => { it('should set headerOrientation prop in dialog mode', fakeAsync(() => { timePicker.mode = PickerInteractionMode.Dialog; timePicker.open(); + flush(); tick(); fixture.detectChanges(); expect(timePicker.headerOrientation).toEqual('horizontal'); @@ -1592,6 +1615,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -1605,6 +1629,7 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); @@ -1685,6 +1710,7 @@ describe('IgxTimePicker', () => { expect(timePicker.collapsed).toBeTruthy(); timePicker.open(); + flush(); tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); diff --git a/projects/igniteui-angular/src/lib/toast/toast.component.spec.ts b/projects/igniteui-angular/src/lib/toast/toast.component.spec.ts index ef7adddba9e..898709b310f 100644 --- a/projects/igniteui-angular/src/lib/toast/toast.component.spec.ts +++ b/projects/igniteui-angular/src/lib/toast/toast.component.spec.ts @@ -4,6 +4,7 @@ import { ComponentFixture, flushMicrotasks, fakeAsync, + flush } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { @@ -81,6 +82,7 @@ describe('IgxToast', () => { it('positionSettings passed in the open method should be applied', () => { const positions = secondPositionSettings; toast.open("New Message", positions); + flush(); fixture.detectChanges(); expect(toast.positionSettings.horizontalDirection).toBe(-0.5); expect(toast.positionSettings.verticalDirection).toBe(-0.5); From c67732f2b70ae80bfa2a507e1471c9f15120fe2f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 10 Nov 2025 06:32:03 +0000 Subject: [PATCH 5/6] Revert to afterNextRender and convert toggle tests to async/await - Reverted toggle directive to use afterNextRender as requested - Converted toggle directive tests from fakeAsync to async/await - Tests now use await fixture.whenRenderingDone() to wait for rendering - Removed unused test helper file - Work in progress: 11 toggle tests failing, need to adjust remaining tests Co-authored-by: wnvko <5990334+wnvko@users.noreply.github.com> --- .../src/lib/combo/combo.component.spec.ts | 45 ------------ .../src/lib/dialog/dialog.component.spec.ts | 10 --- .../autocomplete.directive.spec.ts | 2 - .../toggle/toggle.directive.spec.ts | 55 ++++++--------- .../lib/directives/toggle/toggle.directive.ts | 48 +++++++------ .../lib/drop-down/drop-down.component.spec.ts | 45 ------------ .../hierarchical-grid.integration.spec.ts | 2 - .../hierarchical-grid.selection.spec.ts | 1 - .../hierarchical-grid.spec.ts | 1 - .../query-builder.component.spec.ts | 2 +- .../src/lib/select/select.component.spec.ts | 70 ------------------- .../simple-combo.component.spec.ts | 26 ------- .../src/lib/test-utils/toggle-helpers.spec.ts | 32 --------- .../time-picker/time-picker.component.spec.ts | 28 +------- .../src/lib/toast/toast.component.spec.ts | 2 - 15 files changed, 49 insertions(+), 320 deletions(-) delete mode 100644 projects/igniteui-angular/src/lib/test-utils/toggle-helpers.spec.ts diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index 6cfca7b4a55..5345bc34424 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -1064,7 +1064,6 @@ describe('igxCombo', () => { expect(dropdown.nativeElement.getAttribute('aria-labelledby')).toEqual(combo.placeholder); combo.open(); - flush(); tick(); fixture.detectChanges(); @@ -1089,7 +1088,6 @@ describe('igxCombo', () => { it('should render aria-expanded attribute properly', fakeAsync(() => { expect(input.nativeElement.getAttribute('aria-expanded')).toMatch('false'); combo.open(); - flush(); tick(); fixture.detectChanges(); expect(input.nativeElement.getAttribute('aria-expanded')).toMatch('true'); @@ -1100,7 +1098,6 @@ describe('igxCombo', () => { })); it('should render placeholder values for inputs properly', () => { combo.toggle(); - flush(); fixture.detectChanges(); expect(combo.collapsed).toBeFalsy(); expect(combo.placeholder).toEqual('Location'); @@ -1129,7 +1126,6 @@ describe('igxCombo', () => { fixture.componentInstance.size = "large"; fixture.detectChanges(); combo.toggle(); - flush(); tick(); fixture.detectChanges(); const dropdownItems = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`)); @@ -1172,7 +1168,6 @@ describe('igxCombo', () => { let scrollIndex = 0; const headers: Array = Array.from(new Set(combo.data.map(item => item.region))); combo.toggle(); - flush(); fixture.detectChanges(); const checkGroupedItemsClass = () => { fixture.detectChanges(); @@ -1247,7 +1242,6 @@ describe('igxCombo', () => { }); it('should focus search input', fakeAsync(() => { combo.toggle(); - flush(); tick(); fixture.detectChanges(); expect(document.activeElement).toEqual(combo.searchInput.nativeElement); @@ -1255,7 +1249,6 @@ describe('igxCombo', () => { it('should not focus search input, when autoFocusSearch=false', fakeAsync(() => { combo.autoFocusSearch = false; combo.toggle(); - flush(); tick(); fixture.detectChanges(); expect(document.activeElement).not.toEqual(combo.searchInput.nativeElement); @@ -1274,7 +1267,6 @@ describe('igxCombo', () => { expect(headerElement).toBeNull(); expect(footerElement).toBeNull(); combo.toggle(); - flush(); fixture.detectChanges(); expect(combo.headerTemplate).toBeDefined(); expect(combo.footerTemplate).toBeDefined(); @@ -1294,14 +1286,12 @@ describe('igxCombo', () => { combo.showSearchCaseIcon = true; fixture.detectChanges(); combo.toggle(); - flush(); fixture.detectChanges(); let caseSensitiveIcon = fixture.debugElement.query(By.css('igx-icon[name=\'case-sensitive\']')); expect(caseSensitiveIcon).toBeDefined(); combo.toggle(); - flush(); fixture.detectChanges(); combo.showSearchCaseIcon = false; fixture.detectChanges(); @@ -1355,7 +1345,6 @@ describe('igxCombo', () => { expect(containerElementWidth).toEqual(wrapperWidth); combo.toggle(); - flush(); tick(); fixture.detectChanges(); const inputElement = fixture.debugElement.query(By.css(`.${CSS_CLASS_INPUTGROUP_WRAPPER}`)).nativeElement; @@ -1381,7 +1370,6 @@ describe('igxCombo', () => { expect(wrapperWidth).toEqual(comboWidth); combo.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -1397,7 +1385,6 @@ describe('igxCombo', () => { expect(inputWidth).toEqual(comboWidth); combo.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -1406,7 +1393,6 @@ describe('igxCombo', () => { fixture.detectChanges(); combo.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -1682,7 +1668,6 @@ describe('igxCombo', () => { expect(dropdown.focusedItem).toEqual(null); expect(combo.collapsed).toBeTruthy(); combo.toggle(); - flush(); tick(); fixture.detectChanges(); expect(document.activeElement).toEqual(combo.searchInput.nativeElement); @@ -1799,7 +1784,6 @@ describe('igxCombo', () => { }); it('should properly handle dropdown.focusItem', fakeAsync(() => { combo.toggle(); - flush(); tick(); fixture.detectChanges(); const virtualSpyUP = spyOn(dropdown, 'navigatePrev'); @@ -1818,7 +1802,6 @@ describe('igxCombo', () => { })); it('should handle keyboard events', fakeAsync(() => { combo.toggle(); - flush(); tick(); fixture.detectChanges(); spyOn(combo, 'selectAllItems'); @@ -1882,7 +1865,6 @@ describe('igxCombo', () => { it('should select/focus dropdown list items with space/up and down arrow keys', () => { let selectedItemsCount = 0; combo.toggle(); - flush(); fixture.detectChanges(); const dropdownList = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROPDOWNLIST_SCROLL}`)).nativeElement; @@ -1964,7 +1946,6 @@ describe('igxCombo', () => { })); it('should close the dropdown list on pressing Tab key', fakeAsync(() => { combo.toggle(); - flush(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1982,7 +1963,6 @@ describe('igxCombo', () => { input = fixture.debugElement.query(By.css(`.${CSS_CLASS_INPUTGROUP}`)); let firstVisibleItem: Element; combo.toggle(); - flush(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); const scrollbar = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLLBAR_VERTICAL}`)) @@ -2322,7 +2302,6 @@ describe('igxCombo', () => { it('should clear the selection on Enter of the focused clear icon', () => { const selectedItem_1 = combo.dropdown.items[1]; combo.toggle(); - flush(); fixture.detectChanges(); simulateComboItemClick(1); expect(combo.selection[0]).toEqual(selectedItem_1.value); @@ -2338,7 +2317,6 @@ describe('igxCombo', () => { it('should not be able to select group header', () => { spyOn(combo.selectionChanging, 'emit').and.callThrough(); combo.toggle(); - flush(); fixture.detectChanges(); simulateComboItemClick(0, true); @@ -2476,7 +2454,6 @@ describe('igxCombo', () => { const dropdown = combo.dropdown; dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -2494,7 +2471,6 @@ describe('igxCombo', () => { tick(); fixture.detectChanges(); combo.toggle(); - flush(); tick(); fixture.detectChanges(); combo.onBlur(); @@ -2505,7 +2481,6 @@ describe('igxCombo', () => { it('should prevent selection when selectionChanging is cancelled', () => { spyOn(combo.selectionChanging, 'emit').and.callFake((event: IComboSelectionChangingEventArgs) => event.cancel = true); combo.toggle(); - flush(); fixture.detectChanges(); const dropdownFirstItem = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[0].nativeElement; @@ -2628,7 +2603,6 @@ describe('igxCombo', () => { }); it('should group items correctly', fakeAsync(() => { combo.toggle(); - flush(); tick(); fixture.detectChanges(); expect(combo.groupKey).toEqual('region'); @@ -2647,7 +2621,6 @@ describe('igxCombo', () => { it('should properly handle click events on disabled/header items', fakeAsync(() => { spyOn(combo.dropdown, 'selectItem').and.callThrough(); combo.toggle(); - flush(); tick(); fixture.detectChanges(); expect(combo.collapsed).toBeFalsy(); @@ -2669,7 +2642,6 @@ describe('igxCombo', () => { it('should properly add items to the defaultFallbackGroup', () => { combo.allowCustomValues = true; combo.toggle(); - flush(); fixture.detectChanges(); const fallBackGroup = combo.defaultFallbackGroup; const initialDataLength = combo.data.length + 0; @@ -2691,7 +2663,6 @@ describe('igxCombo', () => { it('should sort groups correctly', () => { combo.groupSortingDirection = SortingDirection.Asc; combo.toggle(); - flush(); fixture.detectChanges(); expect(combo.dropdown.headers[0].element.nativeElement.innerText).toEqual('East North Central'); @@ -2876,7 +2847,6 @@ describe('igxCombo', () => { combo.filteringOptions = { caseSensitive: false, filteringKey: undefined }; combo.data = ['José', 'Óscar', 'Ángel', 'Germán', 'Niño', 'México', 'Méxícó', 'Mexico', 'Köln', 'München']; combo.toggle(); - flush(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(`input[name="searchInput"]`)); @@ -2908,7 +2878,6 @@ describe('igxCombo', () => { }; combo.toggle(); - flush(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css('input[name=\'searchInput\']')); const verifyFilteredItems = (inputValue: string, expectedItemsNumber) => { @@ -2934,7 +2903,6 @@ describe('igxCombo', () => { let dropDownContainer: HTMLElement; let listItems; combo.toggle(); - flush(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); @@ -2998,7 +2966,6 @@ describe('igxCombo', () => { }); it('should clear the search input and close the dropdown list on pressing ESC key', fakeAsync(() => { combo.toggle(); - flush(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); @@ -3022,7 +2989,6 @@ describe('igxCombo', () => { return filteredArray; }, {}); combo.toggle(); - flush(); fixture.detectChanges(); const searchInput = fixture.debugElement.query(By.css(CSS_CLASS_SEARCHINPUT)); UIInteractions.triggerInputEvent(searchInput, 'Mi'); @@ -3037,7 +3003,6 @@ describe('igxCombo', () => { combo.allowCustomValues = true; fixture.detectChanges(); combo.toggle(); - flush(); fixture.detectChanges(); expect(combo.selection).toEqual([]); expect(combo.displayValue).toEqual(''); @@ -3140,7 +3105,6 @@ describe('igxCombo', () => { }); it('should enable/disable filtering at runtime', fakeAsync(() => { combo.open(); // Open combo - all data items are in filteredData - flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3158,7 +3122,6 @@ describe('igxCombo', () => { combo.disableFiltering = true; // Filtering is disabled fixture.detectChanges(); combo.open(); // All items are visible since filtering is disabled - flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); // All items are visible since filtering is disabled @@ -3174,7 +3137,6 @@ describe('igxCombo', () => { combo.disableFiltering = false; // Filtering is re-enabled fixture.detectChanges(); combo.open(); // Filter is cleared on open - flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3186,7 +3148,6 @@ describe('igxCombo', () => { expect(combo.isAddButtonVisible()).toEqual(false); combo.toggle(); - flush(); fixture.detectChanges(); expect(combo.collapsed).toEqual(false); expect(combo.searchInput.nativeElement.placeholder).toEqual('Add Item'); @@ -3227,7 +3188,6 @@ describe('igxCombo', () => { }); it('Should filter the data when custom filterFunction is provided', fakeAsync(() => { combo.open(); - flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3250,7 +3210,6 @@ describe('igxCombo', () => { i[filteringOptions.filteringKey]?.toString().toLowerCase().includes(searchTerm)) } combo.open(); - flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3267,7 +3226,6 @@ describe('igxCombo', () => { })); it('Should update filtering when custom filterFunction is provided and filteringOptions.caseSensitive is changed', fakeAsync(() => { combo.open(); - flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3290,7 +3248,6 @@ describe('igxCombo', () => { i[filteringOptions.filteringKey]?.toString().toLowerCase().includes(searchTerm)) } combo.open(); - flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3306,7 +3263,6 @@ describe('igxCombo', () => { })); it('Should update filtering when custom filteringOptions are provided', fakeAsync(() => { combo.open(); - flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); @@ -3321,7 +3277,6 @@ describe('igxCombo', () => { fixture.detectChanges(); combo.filteringOptions = { caseSensitive: false, filteringKey: combo.groupKey }; combo.open(); - flush(); tick(); fixture.detectChanges(); expect(combo.dropdown.items.length).toBeGreaterThan(0); diff --git a/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts b/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts index 2f696d7c664..8b32c55e33c 100644 --- a/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts +++ b/projects/igniteui-angular/src/lib/dialog/dialog.component.spec.ts @@ -182,7 +182,6 @@ describe('Dialog', () => { const dialog = fixture.componentInstance.dialog; dialog.open(); - flush(); fixture.detectChanges(); const dialogWindow = fixture.debugElement.query(By.css('.igx-dialog__window')); @@ -215,7 +214,6 @@ describe('Dialog', () => { expect(dialog.isOpen).toEqual(false); dialog.open(); - flush(); fixture.detectChanges(); tick(); expect(dialog.isOpen).toEqual(true); @@ -231,7 +229,6 @@ describe('Dialog', () => { fixture.detectChanges(); const dialog = fixture.componentInstance.dialog; dialog.open(); - flush(); tick(); fixture.detectChanges(); @@ -244,7 +241,6 @@ describe('Dialog', () => { dialog.closeOnOutsideSelect = false; dialog.open(); - flush(); tick(); fixture.detectChanges(); @@ -274,7 +270,6 @@ describe('Dialog', () => { spyOn(dialog.closed, 'emit'); dialog.open(); - flush(); tick(); fixture.detectChanges(); @@ -292,7 +287,6 @@ describe('Dialog', () => { expect(dialog.isOpenChange.emit).toHaveBeenCalledWith(false); dialog.open(); - flush(); tick(); fixture.detectChanges(); const buttons = document.querySelectorAll('button'); @@ -336,11 +330,9 @@ describe('Dialog', () => { const childDialog = fixture.componentInstance.child; mainDialog.open(); - flush(); tick(); childDialog.open(); - flush(); tick(); fixture.detectChanges(); @@ -375,7 +367,6 @@ describe('Dialog', () => { const dialog = fixture.componentInstance.dialog; dialog.open(); - flush(); fixture.detectChanges(); const dialogWindow = fixture.debugElement.query(By.css('.igx-dialog__window')); @@ -396,7 +387,6 @@ describe('Dialog', () => { const dialog = fix.componentInstance.dialog; dialog.open(); - flush(); tick(); fix.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts index 436d9a60e31..882f7c6ac61 100644 --- a/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.spec.ts @@ -65,7 +65,6 @@ describe('IgxAutocomplete', () => { expect(dropDown.collapsed).toBeTruthy(); autocomplete.open(); - flush(); tick(); fixture.detectChanges(); expect(dropDown.collapsed).toBeFalsy(); @@ -327,7 +326,6 @@ describe('IgxAutocomplete', () => { expect(autocomplete.target.open).toHaveBeenCalledTimes(0); autocomplete.open(); - flush(); fixture.detectChanges(); expect(dropDown.collapsed).toBeTruthy(); expect(dropdownListScrollElement.children.length).toEqual(0); diff --git a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts index 1dbeb1f3d85..cfa5cfaae7b 100644 --- a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts @@ -3,7 +3,6 @@ import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { IgxToggleActionDirective, IgxToggleDirective, IgxOverlayOutletDirective } from './toggle.directive'; -import { waitForToggleOpen } from '../../test-utils/toggle-helpers.spec'; import { IgxOverlayService, OverlaySettings, ConnectedPositioningStrategy, AbsoluteScrollStrategy, AutoPositionStrategy, HorizontalAlignment @@ -77,15 +76,14 @@ describe('IgxToggle', () => { expect(toggle.opened.emit).toHaveBeenCalled(); }); - it('should emit \'appended\' event', fakeAsync(() => { + it('should emit \'appended\' event', async () => { const fixture = TestBed.createComponent(IgxToggleTestComponent); fixture.detectChanges(); const toggle = fixture.componentInstance.toggle; spyOn(toggle.appended, 'emit'); toggle.open(); - TestBed.flushEffects(); - tick(); + await fixture.whenRenderingDone(); fixture.detectChanges(); expect(toggle.appended.emit).toHaveBeenCalledTimes(1); @@ -94,21 +92,19 @@ describe('IgxToggle', () => { tick(); fixture.detectChanges(); toggle.open(); - TestBed.flushEffects(); tick(); fixture.detectChanges(); expect(toggle.appended.emit).toHaveBeenCalledTimes(2); - })); + }); - it('should emit \'onClosing\' and \'closed\' events', fakeAsync(() => { + it('should emit \'onClosing\' and \'closed\' events', async () => { const fixture = TestBed.createComponent(IgxToggleTestComponent); fixture.detectChanges(); const toggle = fixture.componentInstance.toggle; fixture.componentInstance.toggle.open(); - TestBed.flushEffects(); - tick(); + await fixture.whenRenderingDone(); fixture.detectChanges(); spyOn(toggle.closing, 'emit'); @@ -119,9 +115,9 @@ describe('IgxToggle', () => { expect(toggle.closing.emit).toHaveBeenCalledTimes(1); expect(toggle.closed.emit).toHaveBeenCalledTimes(1); - })); + }); - it('should propagate IgxOverlay opened/closed events', fakeAsync(() => { + it('should propagate IgxOverlay opened/closed events', async () => { const fixture = TestBed.createComponent(IgxOverlayServiceComponent); fixture.detectChanges(); @@ -131,8 +127,7 @@ describe('IgxToggle', () => { spyOn(toggle.closed, 'emit'); toggle.open(); - TestBed.flushEffects(); - tick(); + await fixture.whenRenderingDone(); expect(toggle.opened.emit).toHaveBeenCalledTimes(1); expect(toggle.collapsed).toBe(false); toggle.close(); @@ -141,7 +136,6 @@ describe('IgxToggle', () => { expect(toggle.collapsed).toBe(true); toggle.open(); - TestBed.flushEffects(); tick(); expect(toggle.opened.emit).toHaveBeenCalledTimes(2); const otherId = overlay.attach(fixture.componentInstance.other); @@ -154,7 +148,7 @@ describe('IgxToggle', () => { tick(); expect(toggle.closed.emit).toHaveBeenCalledTimes(2); expect(toggle.collapsed).toBe(true); - })); + }); it('should open toggle when IgxToggleActionDirective is clicked and toggle is closed', fakeAsync(() => { const fixture = TestBed.createComponent(IgxToggleActionTestComponent); @@ -172,12 +166,11 @@ describe('IgxToggle', () => { expect(divEl.classes[TOGGLER_CLASS]).toBe(true); })); - it('should close toggle when IgxToggleActionDirective is clicked and toggle is opened', fakeAsync(() => { + it('should close toggle when IgxToggleActionDirective is clicked and toggle is opened', async () => { const fixture = TestBed.createComponent(IgxToggleActionTestComponent); fixture.detectChanges(); fixture.componentInstance.toggle.open(); - TestBed.flushEffects(); - tick(); + await fixture.whenRenderingDone(); const divEl = fixture.debugElement.query(By.directive(IgxToggleDirective)).nativeElement; const button: DebugElement = fixture.debugElement.query(By.directive(IgxToggleActionDirective)); @@ -189,7 +182,7 @@ describe('IgxToggle', () => { tick(); fixture.detectChanges(); expect(divEl.classList.contains(HIDDEN_TOGGLER_CLASS)).toBeTruthy(); - })); + }); it('should hide content and emit \'closed\' event when you click outside the toggle\'s content', fakeAsync(() => { const fixture = TestBed.createComponent(IgxToggleActionTestComponent); @@ -284,7 +277,7 @@ describe('IgxToggle', () => { expect(toggleElm.classList.contains(HIDDEN_TOGGLER_CLASS)).toBe(true); })); - it('fix for #2798 - Allow canceling of open and close of IgxDropDown through opening and closing events', fakeAsync(() => { + it('fix for #2798 - Allow canceling of open and close of IgxDropDown through opening and closing events', async () => { const fixture = TestBed.createComponent(IgxToggleTestComponent); fixture.detectChanges(); @@ -299,9 +292,8 @@ describe('IgxToggle', () => { toggle.closing.pipe(first()).subscribe((e: CancelableEventArgs) => e.cancel = cancelClosing); toggle.open(); - TestBed.flushEffects(); fixture.detectChanges(); - tick(); + await fixture.whenRenderingDone(); expect(toggle.opening.emit).toHaveBeenCalledTimes(1); expect(toggle.opened.emit).toHaveBeenCalledTimes(1); @@ -323,13 +315,12 @@ describe('IgxToggle', () => { toggle.opening.subscribe((e: CancelableEventArgs) => e.cancel = true); toggle.open(); - TestBed.flushEffects(); fixture.detectChanges(); tick(); expect(toggle.opening.emit).toHaveBeenCalledTimes(2); expect(toggle.opened.emit).toHaveBeenCalledTimes(1); - })); + }); it('fix for #3636 - ToggleAction should provide its element as target', fakeAsync(() => { const fixture = TestBed.createComponent(TestWithThreeToggleActionsComponent); @@ -430,7 +421,7 @@ describe('IgxToggle', () => { expect(Math.round(toggleRect.top)).toBe(Math.round(buttonRect.bottom)); })); - it('fix for #3810 - Should not open toggle when already opened', fakeAsync(() => { + it('fix for #3810 - Should not open toggle when already opened', async () => { const fixture = TestBed.createComponent(IgxToggleTestComponent); fixture.detectChanges(); @@ -438,23 +429,21 @@ describe('IgxToggle', () => { spyOn(toggle.opening, 'emit'); spyOn(toggle.opened, 'emit'); toggle.open(); - TestBed.flushEffects(); - tick(); + await fixture.whenRenderingDone(); fixture.detectChanges(); expect(toggle.opening.emit).toHaveBeenCalledTimes(1); expect(toggle.opened.emit).toHaveBeenCalledTimes(1); toggle.open(); - TestBed.flushEffects(); tick(); fixture.detectChanges(); expect(toggle.opening.emit).toHaveBeenCalledTimes(1); expect(toggle.opened.emit).toHaveBeenCalledTimes(1); - })); + }); - it('fix for #3810 - Should not close toggle when not open', fakeAsync(() => { + it('fix for #3810 - Should not close toggle when not open', async () => { const fixture = TestBed.createComponent(IgxToggleTestComponent); fixture.detectChanges(); @@ -462,8 +451,7 @@ describe('IgxToggle', () => { spyOn(toggle.opening, 'emit'); spyOn(toggle.opened, 'emit'); toggle.open(); - TestBed.flushEffects(); - tick(); + await fixture.whenRenderingDone(); fixture.detectChanges(); expect(toggle.opening.emit).toHaveBeenCalledTimes(1); @@ -484,7 +472,7 @@ describe('IgxToggle', () => { expect(toggle.closing.emit).toHaveBeenCalledTimes(1); expect(toggle.closed.emit).toHaveBeenCalledTimes(1); - })); + }); it('fix for #4222 - Should emit closed when closed second time', fakeAsync(() => { const fixture = TestBed.createComponent(IgxToggleTestComponent); @@ -499,7 +487,6 @@ describe('IgxToggle', () => { spyOn(toggle.closed, 'emit').and.callThrough(); toggle.open(); - TestBed.flushEffects(); tick(); fixture.detectChanges(); expect(toggle.opening.emit).toHaveBeenCalledTimes(1); diff --git a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts index 902791334c2..0c0bd8405c0 100644 --- a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts @@ -1,15 +1,19 @@ import { + afterNextRender, ChangeDetectorRef, Directive, ElementRef, EventEmitter, HostListener, + inject, Inject, + Injector, Input, OnDestroy, OnInit, Optional, - Output + Output, + runInInjectionContext } from '@angular/core'; import { AbsoluteScrollStrategy } from '../../services/overlay/scroll/absolute-scroll-strategy'; import { CancelableBrowserEventArgs, IBaseEventArgs, PlatformUtil } from '../../core/utils'; @@ -197,6 +201,7 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy { private _overlayClosingSub: Subscription; private _overlayClosedSub: Subscription; private _overlayContentAppendedSub: Subscription; + private _injector = inject(Injector); /** * @hidden @@ -228,28 +233,27 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy { } this._collapsed = false; - this.cdr.detectChanges(); - // Use requestAnimationFrame to defer until after host bindings update - // This works in both production and tests (with flush() in fakeAsync) - requestAnimationFrame(() => { - if (!info) { - this.unsubscribe(); - this.subscribe(); - this._overlayId = this.overlayService.attach(this.elementRef, overlaySettings); - } - - const args: ToggleViewCancelableEventArgs = { cancel: false, owner: this, id: this._overlayId }; - this.opening.emit(args); - if (args.cancel) { - this.unsubscribe(); - this.overlayService.detach(this._overlayId); - this._collapsed = true; - delete this._overlayId; - this.cdr.detectChanges(); - return; - } - this.overlayService.show(this._overlayId, overlaySettings); + runInInjectionContext(this._injector, () =>{ + afterNextRender(() => { + if (!info) { + this.unsubscribe(); + this.subscribe(); + this._overlayId = this.overlayService.attach(this.elementRef, overlaySettings); + } + + const args: ToggleViewCancelableEventArgs = { cancel: false, owner: this, id: this._overlayId }; + this.opening.emit(args); + if (args.cancel) { + this.unsubscribe(); + this.overlayService.detach(this._overlayId); + this._collapsed = true; + delete this._overlayId; + this.cdr.detectChanges(); + return; + } + this.overlayService.show(this._overlayId, overlaySettings); + }); }); } diff --git a/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts b/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts index 40ed2496fe2..929857abe5d 100644 --- a/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts +++ b/projects/igniteui-angular/src/lib/drop-down/drop-down.component.spec.ts @@ -202,7 +202,6 @@ describe('IgxDropDown ', () => { expect(dropdown.collapsed).toBeTruthy(); dropdown.open(); - flush(); tick(); fixture.detectChanges(); expect(dropdown.collapsed).toBeFalsy(); @@ -221,7 +220,6 @@ describe('IgxDropDown ', () => { spyOn(dropdown.opened, 'emit').and.callThrough(); dropdown.open(); - flush(); tick(); fixture.detectChanges(); @@ -229,7 +227,6 @@ describe('IgxDropDown ', () => { expect(dropdown.opened.emit).toHaveBeenCalledTimes(1); dropdown.open(); - flush(); tick(); fixture.detectChanges(); @@ -242,7 +239,6 @@ describe('IgxDropDown ', () => { spyOn(toggle, 'open').and.callThrough(); dropdown.open(); - flush(); fixture.detectChanges(); expect(toggle.open).toHaveBeenCalledTimes(1); @@ -297,7 +293,6 @@ describe('IgxDropDown ', () => { dropdown.closing.pipe(take(1)).subscribe((e: CancelableEventArgs) => e.cancel = true); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -305,7 +300,6 @@ describe('IgxDropDown ', () => { expect(dropdown.opened.emit).toHaveBeenCalledTimes(1); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -319,7 +313,6 @@ describe('IgxDropDown ', () => { dropdown.opening.pipe(take(1)).subscribe((e: CancelableEventArgs) => e.cancel = true); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); expect(dropdown.opening.emit).toHaveBeenCalledTimes(1); @@ -327,7 +320,6 @@ describe('IgxDropDown ', () => { })); it('should select item by SPACE/ENTER keys', fakeAsync(() => { dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); let focusedItem = fixture.debugElement.query(By.css(`.${CSS_CLASS_FOCUSED}`)); @@ -350,7 +342,6 @@ describe('IgxDropDown ', () => { expect(dropdown.collapsed).toEqual(true); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); dropdownElement = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROP_DOWN_BASE}`)); @@ -366,7 +357,6 @@ describe('IgxDropDown ', () => { expect(dropdown.selectedItem).toEqual(dropdown.items[2]); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); expect(dropdown.collapsed).toEqual(false); @@ -379,7 +369,6 @@ describe('IgxDropDown ', () => { spyOn(dropdown.closed, 'emit').and.callThrough(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); let focusedItem = fixture.debugElement.query(By.css(`.${CSS_CLASS_FOCUSED}`)); @@ -404,7 +393,6 @@ describe('IgxDropDown ', () => { })); it('should navigate through items using Up/Down/Home/End keys', fakeAsync(() => { dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); const dropdownElement = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROP_DOWN_BASE}`)); @@ -434,7 +422,6 @@ describe('IgxDropDown ', () => { })); it('should not change selection when setting it to non-existing item', fakeAsync(() => { dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); dropdown.setSelectedItem(0); @@ -476,7 +463,6 @@ describe('IgxDropDown ', () => { dropdown.items[10].selected = true; fixture.detectChanges(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -492,7 +478,6 @@ describe('IgxDropDown ', () => { })); it('should set isSelected via igxDropDownIteComponent', fakeAsync(() => { dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); expect(dropdown.selectedItem).toBeNull(); @@ -512,7 +497,6 @@ describe('IgxDropDown ', () => { expect(dropdown.selectedItem.itemIndex).toEqual(1); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); expect(dropdown.selectedItem.itemIndex).toEqual(1); @@ -526,7 +510,6 @@ describe('IgxDropDown ', () => { dropdown.items[10].isHeader = true; fixture.detectChanges(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -554,7 +537,6 @@ describe('IgxDropDown ', () => { expect(dropdown.selectedItem.itemIndex).toEqual(2); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); expect(dropdown.selectedItem.itemIndex).toEqual(2); @@ -563,7 +545,6 @@ describe('IgxDropDown ', () => { spyOn(dropdown.selectionChanging, 'emit').and.callThrough(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -595,7 +576,6 @@ describe('IgxDropDown ', () => { const dropdownElement = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROP_DOWN_BASE}`)); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); let focusedItem = fixture.debugElement.query(By.css(`.${CSS_CLASS_FOCUSED}`)); @@ -615,7 +595,6 @@ describe('IgxDropDown ', () => { expect((eventArgs.event as KeyboardEvent).key).toEqual('escape'); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); focusedItem = fixture.debugElement.query(By.css(`.${CSS_CLASS_FOCUSED}`)); @@ -636,7 +615,6 @@ describe('IgxDropDown ', () => { it('should be able to change selection when manipulating ISelectionEventArgs', fakeAsync(() => { expect(dropdown.selectedItem).toEqual(null); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -659,7 +637,6 @@ describe('IgxDropDown ', () => { // Set header - error dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -681,14 +658,12 @@ describe('IgxDropDown ', () => { })); it('should not take focus when allowItemsFocus is set to false', fakeAsync(() => { dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); const focusedItem = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_ITEM}`))[0].nativeElement; expect(document.activeElement).toEqual(focusedItem); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -709,7 +684,6 @@ describe('IgxDropDown ', () => { fixture.detectChanges(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); const currentItem = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DISABLED}`))[0]; @@ -735,7 +709,6 @@ describe('IgxDropDown ', () => { fixture.detectChanges(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); let disabledItems = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DISABLED}`)); @@ -758,7 +731,6 @@ describe('IgxDropDown ', () => { dropdown.items[12].disabled = true; fixture.detectChanges(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -790,7 +762,6 @@ describe('IgxDropDown ', () => { dropdown.items[12].disabled = true; fixture.detectChanges(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -830,7 +801,6 @@ describe('IgxDropDown ', () => { dropdown.setSelectedItem(0); fixture.detectChanges(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); expect(dropdown.items[0].selected).toBeTruthy(); @@ -844,7 +814,6 @@ describe('IgxDropDown ', () => { dropdown.items[10].selected = true; fixture.detectChanges(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); expect(dropdown.items[10].focused).toEqual(true); @@ -883,7 +852,6 @@ describe('IgxDropDown ', () => { fixture.detectChanges(); dropdown.open(); - flush(); fixture.detectChanges(); const itemToClick = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_ITEM}`))[0]; @@ -924,7 +892,6 @@ describe('IgxDropDown ', () => { expect(dropdown.collapsed).toEqual(true); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); expect(dropdown.collapsed).toEqual(false); @@ -1114,7 +1081,6 @@ describe('IgxDropDown ', () => { }); it('should update aria-activedescendant to the id of the focused item', fakeAsync(() => { dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -1127,11 +1093,9 @@ describe('IgxDropDown ', () => { expect(dropdownElement.getAttribute('aria-activedescendant')).toBe(focusedItemId); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -1163,7 +1127,6 @@ describe('IgxDropDown ', () => { const groups = fixture.componentInstance.groups; expect(dropdown.collapsed).toBeTruthy(); dropdown.toggle(); - flush(); fixture.detectChanges(); const groupItems = document.querySelectorAll(`.${CSS_CLASS_GROUP_ITEM}`); for (let i = 0; i < groupItems.length; i++) { @@ -1224,7 +1187,6 @@ describe('IgxDropDown ', () => { }); it('should apply selected item class', fakeAsync(() => { dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); const selectedItem = fixture.debugElement.query(By.css(`.${CSS_CLASS_ITEM}`)); @@ -1258,14 +1220,12 @@ describe('IgxDropDown ', () => { }); it('should return items/headers property correctly', fakeAsync(() => { dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); expect(dropdown.items.length).toEqual(15); expect(dropdown.headers).toEqual([]); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); dropdown.items[0].disabled = true; @@ -1276,7 +1236,6 @@ describe('IgxDropDown ', () => { dropdown.items[10].isHeader = true; fixture.detectChanges(); dropdown.toggle(); - flush(); tick(); fixture.detectChanges(); expect(dropdown.items.length).toEqual(12); @@ -1287,7 +1246,6 @@ describe('IgxDropDown ', () => { fixture.componentInstance.maxHeight = '100px'; fixture.detectChanges(); dropdown.toggle(); - flush(); fixture.detectChanges(); const ddList = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLL}`)).nativeElement; expect(parseInt(ddList.style.maxHeight, 10)).toEqual(ddList.offsetHeight); @@ -1297,7 +1255,6 @@ describe('IgxDropDown ', () => { fixture.componentInstance.maxHeight = '700px'; fixture.detectChanges(); dropdown.toggle(); - flush(); fixture.detectChanges(); const ddList = fixture.debugElement.query(By.css(`.${CSS_CLASS_SCROLL}`)).nativeElement; expect(parseInt(ddList.style.maxHeight, 10)).toBeGreaterThan(ddList.offsetHeight); @@ -1385,7 +1342,6 @@ describe('IgxDropDown ', () => { it('#15137 - should bind to custom target if provided', fakeAsync(() => { const input = fixture.debugElement.query(By.css('input')); dropdown.open({ target: input.nativeElement }); - flush(); tick(); fixture.detectChanges(); @@ -1401,7 +1357,6 @@ describe('IgxDropDown ', () => { tick(); fixture.detectChanges(); dropdown.open(); - flush(); tick(); fixture.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts index 40ce6e4e78e..9b0937c4fcc 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts @@ -767,7 +767,6 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { // // Instead of clicking we can just toggle the checkbox // toolbar.columnHidingUI.columnItems.toArray()[2].toggle(); - flush(); // fixture.detectChanges(); // And it should hide the column of the child grid @@ -793,7 +792,6 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { // Instead of clicking we can just toggle the checkbox // toolbar.columnPinningUI.columnItems.toArray()[1].toggle(); - flush(); fixture.detectChanges(); // Check pinned state diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts index 6d5c484b23f..f940b75572f 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts @@ -1180,7 +1180,6 @@ describe('IgxHierarchicalGrid selection #hGrid', () => { fix.detectChanges(); firstRow.toggle(); - flush(); fix.detectChanges(); firstRow.onClick(UIInteractions.getMouseEvent('click')); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts index 897a332c989..153afd981d6 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts @@ -1879,7 +1879,6 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { expect((childGrid as any).headerHierarchyExpander.nativeElement.innerText).toBe('COLLAPSED'); childRows[0].toggle(); - flush(); fixture.detectChanges(); expect((childGrid as any).headerHierarchyExpander.nativeElement.innerText).toBe('EXPANDED'); hierarchicalGrid.expandChildren = false; diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts index 59bd4bfa278..bca74571c50 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts @@ -1,4 +1,4 @@ -import { waitForAsync, TestBed, ComponentFixture, fakeAsync, tick} from '@angular/core/testing'; +import { waitForAsync, TestBed, ComponentFixture, fakeAsync, tick, flush } from '@angular/core/testing'; import { FilteringExpressionsTree, FilteringLogic, IExpressionTree, IgxChipComponent, IgxComboComponent, IgxDateFilteringOperand, IgxIconComponent, IgxInputGroupComponent, IgxNumberFilteringOperand, IgxQueryBuilderComponent, IgxQueryBuilderHeaderComponent, IgxQueryBuilderSearchValueTemplateDirective, IgxSelectComponent } from 'igniteui-angular'; import { Component, OnInit, ViewChild } from '@angular/core'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; diff --git a/projects/igniteui-angular/src/lib/select/select.component.spec.ts b/projects/igniteui-angular/src/lib/select/select.component.spec.ts index 8f481b46c75..76a525181e9 100644 --- a/projects/igniteui-angular/src/lib/select/select.component.spec.ts +++ b/projects/igniteui-angular/src/lib/select/select.component.spec.ts @@ -206,7 +206,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); - flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -220,7 +219,6 @@ describe('igxSelect', () => { spyOn(select.selectionChanging, 'emit'); select.items[1].selected = true; select.open(); - flush(); fixture.detectChanges(); const selectedItemEl = selectList.children[1]; expect(select.collapsed).toBeFalsy(); @@ -230,7 +228,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.open(); - flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); selectedItemEl.nativeElement.click(); @@ -259,7 +256,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.open(); - flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -269,12 +265,10 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); - flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); select.toggle(); - flush(); tick(); fixture.detectChanges(); expect(select.collapsed).toBeTruthy(); @@ -331,7 +325,6 @@ describe('igxSelect', () => { const selectedItemEl = selectList.children[2]; select.toggle(); - flush(); tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -376,7 +369,6 @@ describe('igxSelect', () => { expect(select).toBeDefined(); select.toggle(); - flush(); tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -407,7 +399,6 @@ describe('igxSelect', () => { expect(select).toBeDefined(); select.toggle(); - flush(); tick(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -441,14 +432,12 @@ describe('igxSelect', () => { expect(dropdownWrapper.nativeElement.getAttribute('aria-hidden')).toEqual('true'); select.toggle(); - flush(); tick(); fixture.detectChanges(); expect(inputElement.nativeElement.getAttribute('aria-expanded')).toEqual('true'); expect(dropdownWrapper.nativeElement.getAttribute('aria-hidden')).toEqual('false'); select.toggle(); - flush(); tick(); fixture.detectChanges(); expect(inputElement.nativeElement.getAttribute('aria-expanded')).toEqual('false'); @@ -493,7 +482,6 @@ describe('igxSelect', () => { const dummyInput = fixture.componentInstance.dummyInput.nativeElement; expect(select.collapsed).toBeTruthy(); select.toggle(); - flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -854,7 +842,6 @@ describe('igxSelect', () => { let selectedItemIndex = 5; select.toggle(); - flush(); tick(); fixture.detectChanges(); selectList.children[selectedItemIndex].nativeElement.click(); @@ -864,7 +851,6 @@ describe('igxSelect', () => { selectedItemIndex = 15; select.toggle(); - flush(); tick(); fixture.detectChanges(); selectList.children[selectedItemIndex].nativeElement.click(); @@ -916,7 +902,6 @@ describe('igxSelect', () => { it('should select item with ENTER/SPACE keys', fakeAsync(() => { let selectedItemIndex = 2; select.toggle(); - flush(); tick(); fixture.detectChanges(); inputElement.triggerEventHandler('keydown', arrowDownKeyEvent); @@ -928,7 +913,6 @@ describe('igxSelect', () => { selectedItemIndex = 4; select.toggle(); - flush(); tick(); fixture.detectChanges(); inputElement.triggerEventHandler('keydown', arrowDownKeyEvent); @@ -942,7 +926,6 @@ describe('igxSelect', () => { it('should allow single selection only', fakeAsync(() => { let selectedItemIndex = 5; select.toggle(); - flush(); tick(); fixture.detectChanges(); selectList.children[selectedItemIndex].nativeElement.click(); @@ -983,7 +966,6 @@ describe('igxSelect', () => { const focusedItemIndex = 0; const selectedItemIndex = 8; select.toggle(); - flush(); tick(); fixture.detectChanges(); verifyFocusedItem(focusedItemIndex); @@ -999,7 +981,6 @@ describe('igxSelect', () => { fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); verifyFocusedItem(focusedItemIndex); @@ -1024,7 +1005,6 @@ describe('igxSelect', () => { // Select item - mouse click select.toggle(); - flush(); tick(); fixture.detectChanges(); selectList.children[selectedItemIndex].nativeElement.click(); @@ -1039,7 +1019,6 @@ describe('igxSelect', () => { tick(); fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); checkInputValue(); @@ -1080,7 +1059,6 @@ describe('igxSelect', () => { // Select item - mouse click select.toggle(); - flush(); tick(); fixture.detectChanges(); selectList.children[selectedItemIndex].nativeElement.click(); @@ -1094,7 +1072,6 @@ describe('igxSelect', () => { tick(); fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); checkInputValue(); @@ -1120,7 +1097,6 @@ describe('igxSelect', () => { tick(); fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); expect(select.selectedItem).toBeUndefined(); @@ -1157,7 +1133,6 @@ describe('igxSelect', () => { // Focus item when there is not a selected item select.toggle(); - flush(); tick(); fixture.detectChanges(); navigateDropdownItems(arrowDownKeyEvent); @@ -1171,7 +1146,6 @@ describe('igxSelect', () => { tick(); fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); navigateDropdownItems(arrowUpKeyEvent); @@ -1218,7 +1192,6 @@ describe('igxSelect', () => { let selectedItemIndex = 4; select.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -1277,7 +1250,6 @@ describe('igxSelect', () => { }; select.toggle(); - flush(); tick(); fixture.detectChanges(); selectedItemEl.nativeElement.click(); @@ -1292,7 +1264,6 @@ describe('igxSelect', () => { selectedItemEl = selectList.children[10]; args.newSelection = selectedItem; select.toggle(); - flush(); tick(); fixture.detectChanges(); selectedItemEl.nativeElement.click(); @@ -1489,7 +1460,6 @@ describe('igxSelect', () => { // Select item - mouse click select.toggle(); - flush(); tick(); fixture.detectChanges(); itemElementToSelect.click(); @@ -1502,7 +1472,6 @@ describe('igxSelect', () => { tick(); fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); checkInputValue(); @@ -1554,7 +1523,6 @@ describe('igxSelect', () => { const selectedItemElement = groupElement.children[selectedItemIndex].nativeElement; select.toggle(); - flush(); tick(); fixture.detectChanges(); selectedItemElement.click(); @@ -1609,7 +1577,6 @@ describe('igxSelect', () => { const focusedItemElement = groupElement.children[focusedItemIndex].nativeElement; select.toggle(); - flush(); tick(); fixture.detectChanges(); const focusedItems = fixture.debugElement.queryAll(By.css('.' + CSS_CLASS_FOCUSED_ITEM)); @@ -1673,7 +1640,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); - flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); @@ -1683,7 +1649,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); - flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); inputElement.triggerEventHandler('keydown', tabKeyEvent); @@ -1693,7 +1658,6 @@ describe('igxSelect', () => { expect(select.collapsed).toBeTruthy(); select.toggle(); - flush(); fixture.detectChanges(); expect(select.collapsed).toBeFalsy(); inputElement.triggerEventHandler('keydown', shiftTabKeysEvent); @@ -1766,7 +1730,6 @@ describe('igxSelect', () => { it('should navigate through dropdown items using Up/Down/Home/End keys', () => { let currentItemIndex = 0; select.toggle(); - flush(); fixture.detectChanges(); inputElement.triggerEventHandler('keydown', arrowDownKeyEvent); @@ -1879,7 +1842,6 @@ describe('igxSelect', () => { fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -1895,7 +1857,6 @@ describe('igxSelect', () => { fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -1994,7 +1955,6 @@ describe('igxSelect', () => { it('should filter and navigate through items on character key navigation when dropdown is opened', fakeAsync(() => { select.open(); - flush(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('pa'); @@ -2014,7 +1974,6 @@ describe('igxSelect', () => { it('Character key navigation when dropdown is opened should be case insensitive', fakeAsync(() => { select.open(); - flush(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('l'); @@ -2034,7 +1993,6 @@ describe('igxSelect', () => { it('Character key navigation when dropdown is opened should wrap selection', fakeAsync(() => { select.open(); - flush(); fixture.detectChanges(); const filteredItemsInxs = fixture.componentInstance.filterCities('l'); @@ -2070,7 +2028,6 @@ describe('igxSelect', () => { 'Östringen']; fixture.detectChanges(); select.open(); - flush(); fixture.detectChanges(); // German characters @@ -2099,7 +2056,6 @@ describe('igxSelect', () => { it('should not change focus when pressing non-matching character and dropdown is opened', fakeAsync(() => { select.open(); - flush(); tick(); fixture.detectChanges(); @@ -2298,7 +2254,6 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2308,13 +2263,11 @@ describe('igxSelect', () => { selectedItemIndex = 2; select.toggle(); - flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2324,13 +2277,11 @@ describe('igxSelect', () => { selectedItemIndex = 0; select.toggle(); - flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2357,7 +2308,6 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2365,13 +2315,11 @@ describe('igxSelect', () => { selectedItemIndex = 5; select.toggle(); - flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2379,13 +2327,11 @@ describe('igxSelect', () => { selectedItemIndex = 9; select.toggle(); - flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2407,7 +2353,6 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2422,7 +2367,6 @@ describe('igxSelect', () => { (select.element as HTMLElement).style.marginTop = '10px'; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2438,7 +2382,6 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2460,7 +2403,6 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2472,7 +2414,6 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2486,7 +2427,6 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); getBoundingRectangles(); @@ -2508,7 +2448,6 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); document.documentElement.scrollLeft += 50; @@ -2521,13 +2460,11 @@ describe('igxSelect', () => { selectedItemIndex = 2; select.toggle(); - flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); document.documentElement.scrollLeft += 50; @@ -2540,13 +2477,11 @@ describe('igxSelect', () => { selectedItemIndex = 0; select.toggle(); - flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); document.documentElement.scrollLeft += 50; @@ -2563,7 +2498,6 @@ describe('igxSelect', () => { select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); document.documentElement.scrollTop += 20; @@ -2576,13 +2510,11 @@ describe('igxSelect', () => { selectedItemIndex = 2; select.toggle(); - flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); document.documentElement.scrollTop += 20; @@ -2595,13 +2527,11 @@ describe('igxSelect', () => { selectedItemIndex = 0; select.toggle(); - flush(); tick(); fixture.detectChanges(); select.items[selectedItemIndex].selected = true; fixture.detectChanges(); select.toggle(); - flush(); tick(); fixture.detectChanges(); document.documentElement.scrollTop += 20; diff --git a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts index b7b4942d97d..e64423138d3 100644 --- a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts @@ -625,7 +625,6 @@ describe('IgxSimpleCombo', () => { expect(dropdownListBox.nativeElement.getAttribute('aria-labelledby')).toEqual(combo.placeholder); combo.open(); - flush(); tick(); fixture.detectChanges(); @@ -644,7 +643,6 @@ describe('IgxSimpleCombo', () => { it('should render aria-expanded attribute properly', fakeAsync(() => { expect(input.nativeElement.getAttribute('aria-expanded')).toMatch('false'); combo.open(); - flush(); tick(); fixture.detectChanges(); expect(input.nativeElement.getAttribute('aria-expanded')).toMatch('true'); @@ -655,7 +653,6 @@ describe('IgxSimpleCombo', () => { })); it('should render placeholder values for inputs properly', () => { combo.toggle(); - flush(); fixture.detectChanges(); expect(combo.collapsed).toBeFalsy(); expect(combo.placeholder).toEqual('Location'); @@ -673,7 +670,6 @@ describe('IgxSimpleCombo', () => { fixture.componentInstance.size = "large"; fixture.detectChanges(); combo.toggle(); - flush(); tick(); fixture.detectChanges(); const dropdownItems = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`)); @@ -713,7 +709,6 @@ describe('IgxSimpleCombo', () => { it('should render focused items properly', () => { const dropdown = combo.dropdown; combo.toggle(); - flush(); fixture.detectChanges(); dropdown.navigateItem(2); // Component is virtualized, so this will focus the ACTUAL 3rd item @@ -939,7 +934,6 @@ describe('IgxSimpleCombo', () => { })); it('should properly assign the resource string to the aria-label of the clear button',() => { combo.toggle(); - flush(); fixture.detectChanges(); combo.select(['Illinois', 'Mississippi', 'Ohio']); @@ -1169,7 +1163,6 @@ describe('IgxSimpleCombo', () => { it('should not close the dropdown on ArrowUp key if the active item is the first one in the list', fakeAsync(() => { combo.open(); - flush(); tick(); fixture.detectChanges(); @@ -1188,7 +1181,6 @@ describe('IgxSimpleCombo', () => { it('should select an item from the dropdown list with the Space key without closing it', () => { combo.open(); - flush(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1208,7 +1200,6 @@ describe('IgxSimpleCombo', () => { it('should close the dropdown list on pressing Tab key', fakeAsync(() => { combo.open(); - flush(); fixture.detectChanges(); const dropdownContent = fixture.debugElement.query(By.css(`.${CSS_CLASS_CONTENT}`)); @@ -1315,7 +1306,6 @@ describe('IgxSimpleCombo', () => { fixture.componentInstance.allowCustomValues = true; fixture.detectChanges(); combo.open(); - flush(); fixture.detectChanges(); UIInteractions.setInputElementValue(input.nativeElement, 'Massachuset'); fixture.detectChanges(); @@ -1341,7 +1331,6 @@ describe('IgxSimpleCombo', () => { UIInteractions.setInputElementValue(input.nativeElement, 'MassachusettsL'); fixture.detectChanges(); combo.open(); - flush(); fixture.detectChanges(); const addItemButton = fixture.debugElement.query(By.css(`.${CSS_CLASS_ADDBUTTON}`)); expect(addItemButton).toBeDefined(); @@ -1357,7 +1346,6 @@ describe('IgxSimpleCombo', () => { it('should close when an item is clicked on', () => { spyOn(combo, 'close').and.callThrough(); combo.open(); - flush(); fixture.detectChanges(); const item1 = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`)); expect(item1).toBeDefined(); @@ -1370,7 +1358,6 @@ describe('IgxSimpleCombo', () => { it('should retain selection after blurring', () => { combo.open(); - flush(); fixture.detectChanges(); const item1 = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`)); expect(item1).toBeDefined(); @@ -1404,7 +1391,6 @@ describe('IgxSimpleCombo', () => { it('should close the dropdown with Alt + ArrowUp', fakeAsync(() => { combo.open(); - flush(); fixture.detectChanges(); spyOn(combo, 'close').and.callThrough(); @@ -1845,7 +1831,6 @@ describe('IgxSimpleCombo', () => { fixture.detectChanges(); combo.open(); - flush(); fixture.detectChanges(); expect(combo.collapsed).toEqual(false); expect(combo.overlaySettings.positionStrategy.settings.verticalDirection).toBe(-1); @@ -1862,7 +1847,6 @@ describe('IgxSimpleCombo', () => { expect(combo.collapsed).toEqual(true); combo.open(); - flush(); fixture.detectChanges(); expect(combo.collapsed).toEqual(false); expect(combo.overlaySettings.positionStrategy.settings.verticalDirection).toBe(-1); @@ -1890,7 +1874,6 @@ describe('IgxSimpleCombo', () => { fixture.detectChanges(); dropdown.toggle(); - flush(); fixture.detectChanges(); UIInteractions.simulateTyping('Ohio ', input); @@ -1900,7 +1883,6 @@ describe('IgxSimpleCombo', () => { fixture.detectChanges(); combo.toggle(); - flush(); tick(); fixture.detectChanges(); @@ -2140,7 +2122,6 @@ describe('IgxSimpleCombo', () => { it('should not select the first item when combo is focused there is no focus item and Enter is pressed', fakeAsync(() => { combo.open(); - flush(); tick(); fixture.detectChanges(); @@ -2300,7 +2281,6 @@ describe('IgxSimpleCombo', () => { // empty string combo.open(); - flush(); fixture.detectChanges(); const item1 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[2]; item1.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2314,7 +2294,6 @@ describe('IgxSimpleCombo', () => { // null combo.open(); - flush(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2458,7 +2437,6 @@ describe('IgxSimpleCombo', () => { let model; combo.open(); - flush(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2535,7 +2513,6 @@ describe('IgxSimpleCombo', () => { // empty string combo.open(); - flush(); fixture.detectChanges(); const item1 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[2]; item1.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2551,7 +2528,6 @@ describe('IgxSimpleCombo', () => { // null combo.open(); - flush(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2756,7 +2732,6 @@ describe('IgxSimpleCombo', () => { input = fixture.debugElement.query(By.css(`.${CSS_CLASS_COMBO_INPUTGROUP}`)); combo.open(); - flush(); fixture.detectChanges(); const item2 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[3]; item2.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); @@ -2910,7 +2885,6 @@ describe('IgxSimpleCombo', () => { expect(input.nativeElement.value).toEqual('Product 3'); combo.open(); - flush(); fixture.detectChanges(); const item1 = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`))[5]; item1.triggerEventHandler('click', UIInteractions.getMouseEvent('click')); diff --git a/projects/igniteui-angular/src/lib/test-utils/toggle-helpers.spec.ts b/projects/igniteui-angular/src/lib/test-utils/toggle-helpers.spec.ts deleted file mode 100644 index 31f21290ed5..00000000000 --- a/projects/igniteui-angular/src/lib/test-utils/toggle-helpers.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ComponentFixture } from '@angular/core/testing'; - -/** - * Helper function to wait for toggle/dropdown/overlay to open after calling open() or toggle() - * This is needed because the toggle directive uses afterNextRender() which requires - * waiting for the rendering cycle to complete in tests. - * - * @param fixture The component fixture - * @returns Promise that resolves when rendering is done - * - * @example - * ```typescript - * select.open(); - * await waitForToggleOpen(fixture); - * expect(select.collapsed).toBeFalsy(); - * ``` - */ -export async function waitForToggleOpen(fixture: ComponentFixture): Promise { - await fixture.whenRenderingDone(); - fixture.detectChanges(); -} - -/** - * Helper function for fakeAsync tests that need to wait for toggle operations. - * Since afterNextRender() doesn't work in fakeAsync, tests should use async/await instead. - * This function is kept for backwards compatibility but will log a warning. - * - * @deprecated Use async/await with waitForToggleOpen instead of fakeAsync - */ -export function waitForToggleOpenSync(): void { - console.warn('waitForToggleOpenSync called - tests using afterNextRender should use async/await'); -} diff --git a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts index 5ef6989a023..8eafb66af26 100644 --- a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts +++ b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.spec.ts @@ -1,5 +1,5 @@ import { Component, ViewChild, DebugElement, EventEmitter, QueryList } from '@angular/core'; -import { TestBed, fakeAsync, tick, ComponentFixture, waitForAsync, flush } from '@angular/core/testing'; +import { TestBed, fakeAsync, tick, ComponentFixture, waitForAsync } from '@angular/core/testing'; import { UntypedFormControl, UntypedFormGroup, FormsModule, NgForm, ReactiveFormsModule, Validators } from '@angular/forms'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; @@ -570,7 +570,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -587,7 +586,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -630,7 +628,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -655,7 +652,6 @@ describe('IgxTimePicker', () => { it('should not change the current selection and close the dropdown on OK button click', fakeAsync(() => { timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -676,7 +672,6 @@ describe('IgxTimePicker', () => { it('should close the dropdown and discard the current selection on Cancel button click', fakeAsync(() => { timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -700,7 +695,6 @@ describe('IgxTimePicker', () => { spyOn(timePicker.closed, 'emit').and.callThrough(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -724,7 +718,6 @@ describe('IgxTimePicker', () => { const openingSub = timePicker.opening.subscribe((event) => event.cancel = true); timePicker.open(); - flush(); tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeTruthy(); @@ -736,7 +729,6 @@ describe('IgxTimePicker', () => { const closingSub = timePicker.closing.subscribe((event) => event.cancel = true); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -815,7 +807,6 @@ describe('IgxTimePicker', () => { secondsColumn = fixture.debugElement.query(By.css(CSS_CLASS_SECONDSLIST)); timePicker.open(); - flush(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -867,7 +858,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); fixture.detectChanges(); secondsColumn = fixture.debugElement.query(By.css(CSS_CLASS_SECONDSLIST)); expect(timePicker.collapsed).toBeFalsy(); @@ -1100,7 +1090,6 @@ describe('IgxTimePicker', () => { timePicker.mode = "dialog"; timePicker.open(); - flush(); fixture.detectChanges(); const amElement = ampmColumn.query(e => e.nativeElement.textContent === 'AM'); @@ -1208,7 +1197,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -1223,7 +1211,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -1248,7 +1235,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -1273,7 +1259,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -1346,7 +1331,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -1369,7 +1353,6 @@ describe('IgxTimePicker', () => { expect(inputEl.getAttribute('aria-expanded')).toEqual('false'); timePicker.open(); - flush(); tick(); fixture.detectChanges(); expect(inputEl.getAttribute('aria-expanded')).toEqual('true'); @@ -1409,7 +1392,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -1456,7 +1438,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -1477,7 +1458,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -1499,7 +1479,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -1518,7 +1497,6 @@ describe('IgxTimePicker', () => { secondsColumn = fixture.debugElement.query(By.css(CSS_CLASS_SECONDSLIST)); timePicker.open(); - flush(); tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); @@ -1599,7 +1577,6 @@ describe('IgxTimePicker', () => { it('should set headerOrientation prop in dialog mode', fakeAsync(() => { timePicker.mode = PickerInteractionMode.Dialog; timePicker.open(); - flush(); tick(); fixture.detectChanges(); expect(timePicker.headerOrientation).toEqual('horizontal'); @@ -1615,7 +1592,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -1629,7 +1605,6 @@ describe('IgxTimePicker', () => { fixture.detectChanges(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); @@ -1710,7 +1685,6 @@ describe('IgxTimePicker', () => { expect(timePicker.collapsed).toBeTruthy(); timePicker.open(); - flush(); tick(); fixture.detectChanges(); expect(timePicker.collapsed).toBeFalsy(); diff --git a/projects/igniteui-angular/src/lib/toast/toast.component.spec.ts b/projects/igniteui-angular/src/lib/toast/toast.component.spec.ts index 898709b310f..ef7adddba9e 100644 --- a/projects/igniteui-angular/src/lib/toast/toast.component.spec.ts +++ b/projects/igniteui-angular/src/lib/toast/toast.component.spec.ts @@ -4,7 +4,6 @@ import { ComponentFixture, flushMicrotasks, fakeAsync, - flush } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { @@ -82,7 +81,6 @@ describe('IgxToast', () => { it('positionSettings passed in the open method should be applied', () => { const positions = secondPositionSettings; toast.open("New Message", positions); - flush(); fixture.detectChanges(); expect(toast.positionSettings.horizontalDirection).toBe(-0.5); expect(toast.positionSettings.verticalDirection).toBe(-0.5); From c1fde5ad428a33ff14873b957748844f7c34dce5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 10 Nov 2025 06:37:18 +0000 Subject: [PATCH 6/6] Revert toggle directive to use afterNextRender and update tests to wait for rendering Co-authored-by: wnvko <5990334+wnvko@users.noreply.github.com> --- .../src/lib/directives/toggle/toggle.directive.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts index cfa5cfaae7b..3f74b578c08 100644 --- a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts @@ -69,6 +69,7 @@ describe('IgxToggle', () => { spyOn(toggle.opening, 'emit'); spyOn(toggle.opened, 'emit'); toggle.open(); + await fixture.whenStable(); await fixture.whenRenderingDone(); fixture.detectChanges();