Dedupe search component tests.
Bug: 380878140
Test: npm run test:unit:ci
Change-Id: I19eb35b309b02c152cc045eb200a8546455249b6
diff --git a/tools/winscope/src/test/unit/dom_test_utils.ts b/tools/winscope/src/test/unit/dom_test_utils.ts
index ef967c8..94275de 100644
--- a/tools/winscope/src/test/unit/dom_test_utils.ts
+++ b/tools/winscope/src/test/unit/dom_test_utils.ts
@@ -130,7 +130,12 @@
}
dispatchInput(value: string) {
- if (!(this.root instanceof HTMLInputElement)) {
+ if (
+ !(
+ this.root instanceof HTMLInputElement ||
+ this.root instanceof HTMLTextAreaElement
+ )
+ ) {
throw new Error('cannot dispatch input on node ' + this.root.nodeName);
}
this.root.value = value;
@@ -168,8 +173,11 @@
this.root.addEventListener(event, listener);
}
- keydownEnter() {
- const event = new KeyboardEvent('keydown', {key: KeyboardEventKey.ENTER});
+ keydownEnter(shiftKey = false) {
+ const event = new KeyboardEvent('keydown', {
+ key: KeyboardEventKey.ENTER,
+ shiftKey,
+ });
this.dispatchEvent(event);
}
diff --git a/tools/winscope/src/test/unit/utils.ts b/tools/winscope/src/test/unit/utils.ts
index ba4c1eb..255bed2 100644
--- a/tools/winscope/src/test/unit/utils.ts
+++ b/tools/winscope/src/test/unit/utils.ts
@@ -299,49 +299,6 @@
return parser.getEntry(index);
}
- static checkSectionCollapseAndExpand<T>(
- htmlElement: HTMLElement,
- fixture: ComponentFixture<T>,
- selector: string,
- sectionTitle: string,
- ) {
- const section = assertDefined(htmlElement.querySelector(selector));
- expect(
- assertDefined(
- section.querySelector<HTMLElement>(
- 'collapsible-section-title .mat-title',
- ),
- ).textContent,
- ).toEqual(sectionTitle);
- const collapseButton = assertDefined(
- section.querySelector<HTMLElement>('collapsible-section-title button'),
- );
- collapseButton.click();
- fixture.detectChanges();
- expect(section.classList).toContain('collapsed');
- const collapsedSections = assertDefined(
- htmlElement.querySelector('collapsed-sections'),
- );
- const collapsedSection = assertDefined(
- collapsedSections.querySelector('.collapsed-section'),
- ) as HTMLElement;
- expect(collapsedSection.textContent?.trim()).toEqual(
- sectionTitle + ' arrow_right',
- );
- collapsedSection.click();
- fixture.detectChanges();
- UnitTestUtils.checkNoCollapsedSectionButtons(htmlElement);
- }
-
- static checkNoCollapsedSectionButtons(htmlElement: HTMLElement) {
- const collapsedSections = assertDefined(
- htmlElement.querySelector('collapsed-sections'),
- );
- expect(
- collapsedSections.querySelectorAll('.collapsed-section').length,
- ).toEqual(0);
- }
-
static makeEmptyTrace<T extends TraceType>(
traceType: T,
descriptors: string[] = [],
diff --git a/tools/winscope/src/viewers/components/hierarchy_tree_node_data_view_component_test.ts b/tools/winscope/src/viewers/components/hierarchy_tree_node_data_view_component_test.ts
index d2b8517..cdff03b 100644
--- a/tools/winscope/src/viewers/components/hierarchy_tree_node_data_view_component_test.ts
+++ b/tools/winscope/src/viewers/components/hierarchy_tree_node_data_view_component_test.ts
@@ -54,19 +54,19 @@
dom.checkTextExact('test node');
});
- it('shows display name if set, with full name on hover', () => {
+ it('shows display name if set, with full name on hover', async () => {
testNode.setDisplayName('display name');
component.node = testNode;
dom.detectChanges();
dom.checkTextExact('1 - display name');
- dom.get('.display-name').checkTooltip('test node');
+ await dom.get('.display-name').checkTooltip('test node');
});
- it('shows chips with tooltip on hover', () => {
+ it('shows chips with tooltip on hover', async () => {
testNode.addChip(VISIBLE_CHIP);
component.node = testNode;
dom.detectChanges();
dom.checkTextExact(`1 - test node ${VISIBLE_CHIP.short}`);
- dom.get('.tree-view-chip').checkTooltip(VISIBLE_CHIP.long);
+ await dom.get('.tree-view-chip').checkTooltip(VISIBLE_CHIP.long);
});
});
diff --git a/tools/winscope/src/viewers/viewer_search/active_search_component_test.ts b/tools/winscope/src/viewers/viewer_search/active_search_component_test.ts
index 1f21e27..c740726 100644
--- a/tools/winscope/src/viewers/viewer_search/active_search_component_test.ts
+++ b/tools/winscope/src/viewers/viewer_search/active_search_component_test.ts
@@ -16,7 +16,7 @@
import {CommonModule, NgTemplateOutlet} from '@angular/common';
import {Component} from '@angular/core';
-import {ComponentFixture, TestBed} from '@angular/core/testing';
+import {TestBed} from '@angular/core/testing';
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {MatButtonModule} from '@angular/material/button';
import {MatFormFieldModule} from '@angular/material/form-field';
@@ -26,6 +26,7 @@
import {MatTooltipModule} from '@angular/material/tooltip';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {assertDefined} from 'common/assert_utils';
+import {DOMTestHelper} from 'test/unit/dom_test_utils';
import {
SearchQueryClickDetail,
ViewerEvents,
@@ -34,9 +35,8 @@
describe('ActiveSearchComponent', () => {
const testQuery = 'select * from table';
- let fixture: ComponentFixture<ActiveSearchComponent>;
let component: ActiveSearchComponent;
- let htmlElement: HTMLElement;
+ let dom: DOMTestHelper<ActiveSearchComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
@@ -55,14 +55,13 @@
NgTemplateOutlet,
],
}).compileComponents();
- fixture = TestBed.createComponent(ActiveSearchComponent);
+ const fixture = TestBed.createComponent(ActiveSearchComponent);
component = fixture.componentInstance;
- htmlElement = fixture.nativeElement;
-
+ dom = new DOMTestHelper(fixture, fixture.nativeElement);
component.isSearchInitialized = true;
component.lastTraceFailed = false;
component.saveQueryNameControl = new FormControl();
- fixture.detectChanges();
+ dom.detectChanges();
});
it('can be created', () => {
@@ -76,23 +75,21 @@
it('handles search via enter key', () => {
const runSearch = () => {
const textInput = getTextInput();
- changeInput(textInput, testQuery);
- pressEnter(textInput);
+ textInput.dispatchInput(testQuery);
+ textInput.keydownEnter();
};
runSearchAndCheckHandled(runSearch);
});
it('does not handle search on enter key + shift key', () => {
let query: string | undefined;
- htmlElement
- .querySelector('viewer-search')
- ?.addEventListener(ViewerEvents.SearchQueryClick, (event) => {
- const detail: SearchQueryClickDetail = (event as CustomEvent).detail;
- query = detail.query;
- });
+ dom.addEventListener(ViewerEvents.SearchQueryClick, (event) => {
+ const detail: SearchQueryClickDetail = (event as CustomEvent).detail;
+ query = detail.query;
+ });
const textInput = getTextInput();
- changeInput(textInput, testQuery);
- pressEnter(textInput, true);
+ textInput.dispatchInput(testQuery);
+ textInput.keydownEnter(true);
expect(query).toBeUndefined();
});
@@ -100,83 +97,68 @@
runSearchByQueryButton();
component.canAdd = true;
component.executedQuery = testQuery;
- fixture.detectChanges();
- expect(htmlElement.querySelector('.running-query-message')).toBeNull();
- expect(
- htmlElement.querySelector<HTMLButtonElement>('.add-button')?.disabled,
- ).toBeFalse();
+ dom.detectChanges();
+ expect(dom.find('.running-query-message')).toBeUndefined();
+ dom.get('.add-button').checkDisabled(false);
});
it('handles running query failure', () => {
runSearchByQueryButton();
component.canAdd = true;
component.lastTraceFailed = true;
- fixture.detectChanges();
- expect(htmlElement.querySelector('.running-query-message')).toBeNull();
- expect(
- htmlElement.querySelector<HTMLButtonElement>('.add-button')?.disabled,
- ).toBeTrue();
+ dom.detectChanges();
+ expect(dom.find('.running-query-message')).toBeUndefined();
+ dom.get('.add-button').checkDisabled(true);
});
it('disables search query until initialized', () => {
component.isSearchInitialized = false;
- fixture.detectChanges();
- changeInput(getTextInput(), testQuery);
- expect(getSearchQueryButton().disabled).toBeTrue();
+ dom.detectChanges();
+ getTextInput().dispatchInput(testQuery);
+ getSearchQueryButton().checkDisabled(true);
component.isSearchInitialized = true;
- fixture.detectChanges();
- expect(getSearchQueryButton().disabled).toBeFalse();
+ dom.detectChanges();
+ getSearchQueryButton().checkDisabled(false);
});
it('clears query', () => {
- expect(htmlElement.querySelector('.clear-button')).toBeNull();
+ expect(dom.find('.clear-button')).toBeUndefined();
component.canClear = true;
- fixture.detectChanges();
- const clearButton = assertDefined(
- htmlElement.querySelector<HTMLElement>('.clear-button'),
- );
+ dom.detectChanges();
+ const clearButton = dom.get('.clear-button');
spyOn(component.clearQueryClick, 'emit');
- expect(clearButton.textContent?.trim()).toContain('Clear');
+ clearButton.checkText('Clear');
clearButton.click();
- fixture.detectChanges();
expect(component.clearQueryClick.emit).toHaveBeenCalledTimes(1);
});
it('adds query', () => {
- expect(htmlElement.querySelector('.add-button')).toBeNull();
+ expect(dom.find('.add-button')).toBeUndefined();
component.canAdd = true;
- fixture.detectChanges();
- const addButton = assertDefined(
- htmlElement.querySelector<HTMLButtonElement>('.add-button'),
- );
- expect(addButton.textContent?.trim()).toContain('+ Add Query');
- expect(addButton.disabled).toBeTrue();
+ dom.detectChanges();
+ const addButton = dom.get('.add-button');
+ addButton.checkText('+ Add Query');
+ addButton.checkDisabled(true);
spyOn(component.addQueryClick, 'emit');
component.executedQuery = testQuery;
- fixture.detectChanges();
+ dom.detectChanges();
addButton.click();
- fixture.detectChanges();
expect(component.addQueryClick.emit).toHaveBeenCalledTimes(1);
});
it('labels section', () => {
component.label = 'test label';
- fixture.detectChanges();
- expect(htmlElement.querySelector('.header')?.textContent?.trim()).toEqual(
- 'test label',
- );
+ dom.detectChanges();
+ dom.get('.header').checkText('test label');
});
it('shows last query execution time', () => {
- expect(htmlElement.querySelector('.query-execution-time')).toBeNull();
-
+ expect(dom.find('.query-execution-time')).toBeUndefined();
component.lastQueryExecutionTime = '10 ms';
- fixture.detectChanges();
- expect(
- htmlElement.querySelector('.query-execution-time')?.textContent?.trim(),
- ).toEqual('Executed in 10 ms');
+ dom.detectChanges();
+ dom.get('.query-execution-time').checkText('Executed in 10 ms');
});
it('shows current search information and save query field', () => {
@@ -206,57 +188,29 @@
).toEqual('test name');
});
- function getTextInput(): HTMLTextAreaElement {
- return assertDefined(
- htmlElement.querySelector<HTMLTextAreaElement>('.query-field textarea'),
- );
+ function getTextInput(): DOMTestHelper<ActiveSearchComponent> {
+ return dom.get('.query-field textarea');
}
- function changeInput(
- input: HTMLInputElement | HTMLTextAreaElement,
- query: string,
- ) {
- input.value = query;
- input.dispatchEvent(new Event('input'));
- fixture.detectChanges();
- }
-
- function getSearchQueryButton(): HTMLButtonElement {
- return assertDefined(
- htmlElement.querySelector<HTMLButtonElement>(
- '.query-actions .search-button',
- ),
- );
+ function getSearchQueryButton(): DOMTestHelper<ActiveSearchComponent> {
+ return dom.get('.query-actions .search-button');
}
function runSearchByQueryButton() {
- changeInput(getTextInput(), testQuery);
+ getTextInput().dispatchInput(testQuery);
getSearchQueryButton().click();
- fixture.detectChanges();
}
function runSearchAndCheckHandled(runSearch: () => void) {
spyOn(component.searchQueryClick, 'emit');
runSearch();
component.runningQuery = true;
- fixture.detectChanges();
+ dom.detectChanges();
expect(component.searchQueryClick.emit).toHaveBeenCalledOnceWith(testQuery);
- expect(getSearchQueryButton().disabled).toBeTrue();
- const runningQueryMessage = assertDefined(
- htmlElement.querySelector('.running-query-message'),
- );
- expect(runningQueryMessage.textContent?.trim()).toEqual(
- 'timer Calculating results',
- );
- expect(runningQueryMessage.querySelector('mat-spinner')).toBeTruthy();
- }
-
- function pressEnter(
- input: HTMLInputElement | HTMLTextAreaElement,
- shiftKey = false,
- ) {
- input.dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter', shiftKey}));
- fixture.detectChanges();
+ getSearchQueryButton().checkDisabled(true);
+ const runningQueryMessage = dom.get('.running-query-message');
+ runningQueryMessage.checkTextExact('timer Calculating results');
+ expect(runningQueryMessage.find('mat-spinner')).toBeDefined();
}
@Component({
diff --git a/tools/winscope/src/viewers/viewer_search/search_list_component_test.ts b/tools/winscope/src/viewers/viewer_search/search_list_component_test.ts
index 513a3b0..3b9b97e 100644
--- a/tools/winscope/src/viewers/viewer_search/search_list_component_test.ts
+++ b/tools/winscope/src/viewers/viewer_search/search_list_component_test.ts
@@ -17,20 +17,18 @@
import {CdkMenuModule} from '@angular/cdk/menu';
import {NgTemplateOutlet} from '@angular/common';
import {Component, ViewChild} from '@angular/core';
-import {ComponentFixture, TestBed} from '@angular/core/testing';
+import {TestBed} from '@angular/core/testing';
import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
import {MatTooltipModule} from '@angular/material/tooltip';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
-import {assertDefined} from 'common/assert_utils';
-import {UnitTestUtils} from 'test/unit/utils';
+import {DOMTestHelper} from 'test/unit/dom_test_utils';
import {ListItemOption, SearchListComponent} from './search_list_component';
import {ListedSearch} from './ui_data';
describe('SearchListComponent', () => {
- let fixture: ComponentFixture<TestHostComponent>;
let component: TestHostComponent;
- let htmlElement: HTMLElement;
+ let dom: DOMTestHelper<TestHostComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
@@ -43,10 +41,10 @@
MatButtonModule,
],
}).compileComponents();
- fixture = TestBed.createComponent(TestHostComponent);
+ const fixture = TestBed.createComponent(TestHostComponent);
component = fixture.componentInstance;
- htmlElement = fixture.nativeElement;
- fixture.detectChanges();
+ dom = new DOMTestHelper(fixture, fixture.nativeElement);
+ dom.detectChanges();
});
it('can be created', () => {
@@ -54,11 +52,11 @@
});
it('shows placeholder text if no searches', () => {
- expect(htmlElement.textContent?.trim()).toEqual('');
+ dom.checkTextExact('');
const placeholderText = 'placeholder text';
component.placeholderText = placeholderText;
- fixture.detectChanges();
- expect(htmlElement.textContent?.trim()).toEqual(placeholderText);
+ dom.detectChanges();
+ dom.checkTextExact(placeholderText);
});
it('shows search names with tooltips', async () => {
@@ -66,85 +64,73 @@
new ListedSearch('query1', 'name1'),
new ListedSearch('query2', 'query2'),
];
- fixture.detectChanges();
+ dom.detectChanges();
- const listedSearches =
- htmlElement.querySelectorAll<HTMLElement>('.listed-search');
+ const listedSearches = dom.findAll('.listed-search');
expect(listedSearches.length).toEqual(2);
- const queryName1 = assertDefined(
- listedSearches[0].querySelector<HTMLElement>('.listed-search-name'),
- );
- const queryName2 = assertDefined(
- listedSearches[1].querySelector<HTMLElement>('.listed-search-name'),
- );
- expect(queryName1.textContent?.trim()).toEqual('name1');
- expect(queryName2.textContent?.trim()).toEqual('query2');
+ const queryName1 = listedSearches[0].get('.listed-search-name');
+ const queryName2 = listedSearches[1].get('.listed-search-name');
+ queryName1.checkTextExact('name1');
+ queryName2.checkTextExact('query2');
// shows tooltip when name and query are different
- await UnitTestUtils.checkTooltips([queryName1], ['name1: query1'], fixture);
+ await queryName1.checkTooltip('name1: query1');
// does not show tooltip when name and query are the same
- await UnitTestUtils.checkTooltips([queryName2], [undefined], fixture);
+ await queryName2.checkTooltip(undefined);
// shows tooltip when element is overflowing
- queryName2.style.maxWidth = queryName2.offsetWidth / 2 + 'px';
- fixture.detectChanges();
- await UnitTestUtils.checkTooltips([queryName2], ['query2'], fixture);
+ const query2El = queryName2.getHTMLElement();
+ query2El.style.maxWidth = query2El.offsetWidth / 2 + 'px';
+ dom.detectChanges();
+ await queryName2.checkTooltip('query2');
});
it('formats search dates', () => {
spyOn(Date, 'now').and.returnValue(1000);
component.searches = [new ListedSearch('query1', 'name1')];
- fixture.detectChanges();
+ dom.detectChanges();
const expectedDate = new Date(1000);
- expect(
- htmlElement
- .querySelector('.listed-search-date-options')
- ?.textContent?.trim(),
- ).toEqual(
- `${expectedDate
- .toTimeString()
- .slice(0, 5)}\n${expectedDate.toLocaleDateString()}`,
- );
+ dom
+ .get('.listed-search-date-options')
+ .checkTextExact(
+ `${expectedDate
+ .toTimeString()
+ .slice(0, 5)}\n${expectedDate.toLocaleDateString()}`,
+ );
});
- it('shows options and triggers callback on interaction', () => {
+ it('shows options and triggers callback on interaction', async () => {
let optionClicked: ListedSearch | undefined;
component.searches = [new ListedSearch('query1', 'name1')];
- fixture.detectChanges();
+ dom.detectChanges();
// does not show menu button if no options
- expect(htmlElement.querySelector('.listed-search-options')).toBeNull();
+ expect(dom.find('.listed-search-options')).toBeUndefined();
const onClickCallback = (search: ListedSearch) => (optionClicked = search);
component.listItemOptions = [
{name: 'option1', icon: 'test', onClickCallback},
];
- fixture.detectChanges();
+ dom.detectChanges();
- const option = assertDefined(
- htmlElement.querySelector<HTMLElement>('.listed-search-option'),
- );
- UnitTestUtils.checkTooltips([option], ['option1'], fixture);
+ const option = dom.get('.listed-search-option');
+ await option.checkTooltip('option1');
option.click();
expect(optionClicked).toEqual(component.searches[0]);
});
- it('shows menu', () => {
+ it('shows menu', async () => {
component.listItemOptions = [
{name: 'option1', icon: 'test', menu: component.testTemplate},
];
component.searches = [new ListedSearch('query1', 'name1')];
- fixture.detectChanges();
- const option = assertDefined(
- htmlElement.querySelector<HTMLElement>('.listed-search-option'),
- );
- UnitTestUtils.checkTooltips([option], ['option1'], fixture);
+ dom.detectChanges();
+ const option = dom.get('.listed-search-option');
+ await option.checkTooltip('option1');
option.click();
- const menu = assertDefined(
- document.querySelector<HTMLElement>('.context-menu'),
- );
- expect(menu.querySelector('.test-menu-item')).toBeTruthy();
+ const menu = dom.getInDocument('.context-menu');
+ expect(menu.find('.test-menu-item')).toBeDefined();
});
@Component({
diff --git a/tools/winscope/src/viewers/viewer_search/viewer_search_component_test.ts b/tools/winscope/src/viewers/viewer_search/viewer_search_component_test.ts
index a9517c5..d51e851 100644
--- a/tools/winscope/src/viewers/viewer_search/viewer_search_component_test.ts
+++ b/tools/winscope/src/viewers/viewer_search/viewer_search_component_test.ts
@@ -18,7 +18,7 @@
import {CdkMenuModule} from '@angular/cdk/menu';
import {ScrollingModule} from '@angular/cdk/scrolling';
import {Component, ViewChild} from '@angular/core';
-import {ComponentFixture, TestBed} from '@angular/core/testing';
+import {TestBed} from '@angular/core/testing';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {MatButtonModule} from '@angular/material/button';
import {MatDividerModule} from '@angular/material/divider';
@@ -30,7 +30,7 @@
import {MatTooltipModule} from '@angular/material/tooltip';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {assertDefined} from 'common/assert_utils';
-import {UnitTestUtils} from 'test/unit/utils';
+import {DOMTestHelper} from 'test/unit/dom_test_utils';
import {
AddQueryClickDetail,
ClearQueryClickDetail,
@@ -49,9 +49,11 @@
describe('ViewerSearchComponent', () => {
const testQuery = 'select * from table';
- let fixture: ComponentFixture<TestHostComponent>;
+ const accordionItemSelector = '.accordion-item-header';
+ const searchQuerySelector = '.query-actions .search-button';
+ const listedSearchSelector = '.listed-search-option';
let component: TestHostComponent;
- let htmlElement: HTMLElement;
+ let dom: DOMTestHelper<TestHostComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
@@ -81,12 +83,12 @@
MatDividerModule,
],
}).compileComponents();
- fixture = TestBed.createComponent(TestHostComponent);
+ const fixture = TestBed.createComponent(TestHostComponent);
component = fixture.componentInstance;
- htmlElement = fixture.nativeElement;
+ dom = new DOMTestHelper(fixture, fixture.nativeElement);
component.inputData.initialized = true;
component.inputData.currentSearches = [new CurrentSearch(1)];
- fixture.detectChanges();
+ dom.detectChanges();
});
it('can be created', () => {
@@ -94,46 +96,28 @@
});
it('creates global search section with tabs', () => {
- const globalSearch = assertDefined(
- htmlElement.querySelector('.global-search'),
- );
- const searchTabs =
- globalSearch.querySelectorAll<HTMLElement>('.mat-tab-label');
- const [searchTab, savedTab, recentTab] = Array.from(searchTabs);
- expect(searchTab.textContent).toEqual('Search');
- expect(savedTab.textContent).toEqual('Saved');
- expect(recentTab.textContent).toEqual('Recent');
+ const globalSearch = dom.get('.global-search');
+ const [searchTab, savedTab, recentTab] =
+ globalSearch.findAll('.mat-tab-label');
+ searchTab.checkTextExact('Search');
+ savedTab.checkTextExact('Saved');
+ recentTab.checkTextExact('Recent');
});
it('creates collapsed sections with no buttons', () => {
- UnitTestUtils.checkNoCollapsedSectionButtons(htmlElement);
+ dom.checkNoCollapsedSectionButtons();
});
it('handles search box section collapse/expand', () => {
- UnitTestUtils.checkSectionCollapseAndExpand(
- htmlElement,
- fixture,
- '.global-search',
- 'GLOBAL SEARCH',
- );
+ dom.checkSectionCollapseAndExpand('.global-search', 'GLOBAL SEARCH');
});
it('handles tabulated results section collapse/expand', () => {
- UnitTestUtils.checkSectionCollapseAndExpand(
- htmlElement,
- fixture,
- '.search-results',
- 'SEARCH RESULTS',
- );
+ dom.checkSectionCollapseAndExpand('.search-results', 'SEARCH RESULTS');
});
it('handles documentation groups section collapse/expand', () => {
- UnitTestUtils.checkSectionCollapseAndExpand(
- htmlElement,
- fixture,
- '.how-to-search',
- 'HOW TO SEARCH',
- );
+ dom.checkSectionCollapseAndExpand('.how-to-search', 'HOW TO SEARCH');
});
it('handles search via search query click', () => {
@@ -142,16 +126,16 @@
it('handles search via run query from saved without creating new active search', async () => {
component.inputData.savedSearches = [new ListedSearch(testQuery, 'saved1')];
- fixture.detectChanges();
+ dom.detectChanges();
await changeTab(1);
- runSearchAndCheckHandled(runSearchFromListedSearchOption);
+ runSearchAndCheckHandled(() => dom.findAndClick(listedSearchSelector));
});
it('handles search via run query from recents without creating new active search', async () => {
component.inputData.recentSearches = [new ListedSearch(testQuery)];
- fixture.detectChanges();
+ dom.detectChanges();
await changeTab(2);
- runSearchAndCheckHandled(runSearchFromListedSearchOption);
+ runSearchAndCheckHandled(() => dom.findAndClick(listedSearchSelector));
});
it('handles search via run query from saved creating new active search', async () => {
@@ -186,63 +170,57 @@
it('handles running query complete', () => {
const placeholderCss = '.results-placeholder.placeholder-text';
- expect(htmlElement.querySelector(placeholderCss)).toBeTruthy();
+ expect(dom.find(placeholderCss)).toBeDefined();
- clickSearchQueryButton();
+ dom.get(searchQuerySelector).click();
runSearchByQueryButton();
- expect(htmlElement.querySelector(placeholderCss)).toBeNull();
+ expect(dom.find(placeholderCss)).toBeUndefined();
addCurrentSearchWithResult();
- expect(htmlElement.querySelector('.query-execution-time')).toBeTruthy();
- expect(htmlElement.querySelector('log-view')).toBeTruthy();
- expect(htmlElement.querySelector(placeholderCss)).toBeNull();
+ expect(dom.find('.query-execution-time')).toBeDefined();
+ expect(dom.find('log-view')).toBeDefined();
+ expect(dom.find(placeholderCss)).toBeUndefined();
});
it('adds search sections', () => {
const spy = jasmine.createSpy();
- htmlElement
- .querySelector('viewer-search')
- ?.addEventListener(ViewerEvents.AddQueryClick, (event) => {
+ dom
+ .get('viewer-search')
+ .addEventListener(ViewerEvents.AddQueryClick, (event) => {
const detail: AddQueryClickDetail = (event as CustomEvent).detail;
expect(detail).toBeFalsy();
spy();
});
- let addButton = assertDefined(
- htmlElement.querySelector<HTMLButtonElement>('.add-button'),
- );
- expect(htmlElement.querySelector('.clear-button')).toBeNull();
- expect(addButton.disabled).toBeTrue();
+ const addButton = dom.get('.add-button');
+ expect(dom.find('.clear-button')).toBeUndefined();
+ addButton.checkDisabled(true);
const data = structuredClone(component.inputData);
data.currentSearches[0].query = testQuery;
updateInputDataAndDetectChanges(data);
addButton.click();
- fixture.detectChanges();
expect(spy).toHaveBeenCalledTimes(1);
const newData = structuredClone(component.inputData);
newData.currentSearches.push(new CurrentSearch(2));
updateInputDataAndDetectChanges(newData);
- const activeSections = htmlElement.querySelectorAll('active-search');
+ const activeSections = dom.findAll('active-search');
expect(activeSections.length).toEqual(2);
- expect(activeSections.item(0).querySelector('.clear-button')).toBeTruthy();
- expect(activeSections.item(1).querySelector('.clear-button')).toBeTruthy();
+ expect(activeSections[0].find('.clear-button')).toBeDefined();
+ expect(activeSections[1].find('.clear-button')).toBeDefined();
- expect(activeSections.item(0).querySelector('.add-button')).toBeNull();
- addButton = assertDefined(
- activeSections.item(1).querySelector<HTMLButtonElement>('.add-button'),
- );
- expect(addButton.disabled).toBeTrue();
+ expect(activeSections[0].find('.add-button')).toBeUndefined();
+ activeSections[1].get('.add-button').checkDisabled(true);
});
it('handles multiple results', async () => {
let uid: number | undefined;
- htmlElement
- .querySelector('viewer-search')
- ?.addEventListener(ViewerEvents.ClearQueryClick, (event) => {
+ dom
+ .get('viewer-search')
+ .addEventListener(ViewerEvents.ClearQueryClick, (event) => {
const detail: ClearQueryClickDetail = (event as CustomEvent).detail;
uid = detail.uid;
});
@@ -251,35 +229,27 @@
data.currentSearches[0].result = new SearchResult([], []);
updateInputDataAndDetectChanges(data);
addCurrentSearchWithResult(testQuery, 2);
- let resultTabs = htmlElement.querySelectorAll(
- '.result-tabs .mat-tab-label',
- );
- let activeSections =
- htmlElement.querySelectorAll<HTMLElement>('active-search');
+ let resultTabs = dom.findAll('.result-tabs .mat-tab-label');
+ let activeSections = dom.findAll('active-search');
expect(activeSections.length).toEqual(2);
expect(resultTabs.length).toEqual(2);
- expect(resultTabs.item(0).textContent).toEqual('Query 1');
- expect(resultTabs.item(1).textContent).toEqual('Query 2');
+ resultTabs[0].checkTextExact('Query 1');
+ resultTabs[1].checkTextExact('Query 2');
- const clearButton = assertDefined(
- htmlElement.querySelector<HTMLElement>('.clear-button'),
- );
- clearButton.click();
- fixture.detectChanges();
+ dom.findAndClick('.clear-button');
expect(uid).toEqual(1);
- const finalActiveSection = activeSections.item(1);
- const spy = spyOn(finalActiveSection, 'scrollIntoView');
+ const spy = spyOn(activeSections[1].getHTMLElement(), 'scrollIntoView');
const newData = structuredClone(component.inputData);
newData.currentSearches.shift();
updateInputDataAndDetectChanges(newData);
- await fixture.whenStable();
+ await dom.whenStable();
- resultTabs = htmlElement.querySelectorAll('.result-tabs .mat-tab-label');
- activeSections = htmlElement.querySelectorAll('active-search');
+ resultTabs = dom.findAll('.result-tabs .mat-tab-label');
+ activeSections = dom.findAll('active-search');
expect(resultTabs.length).toEqual(1);
- expect(resultTabs.item(0).textContent).toEqual('Query 2');
+ resultTabs[0].checkTextExact('Query 2');
expect(activeSections.length).toEqual(1);
expect(spy).toHaveBeenCalled();
});
@@ -289,162 +259,124 @@
const data = structuredClone(component.inputData);
data.lastTraceFailed = true;
updateInputDataAndDetectChanges(data);
- expect(htmlElement.querySelector('.query-execution-time')).toBeTruthy();
- expect(htmlElement.querySelector('.running-query-message')).toBeNull();
- expect(htmlElement.querySelector('log-view')).toBeNull();
- expect(getSearchQueryButton().disabled).toBeFalse();
+ expect(dom.find('.query-execution-time')).toBeDefined();
+ expect(dom.find('.running-query-message')).toBeUndefined();
+ expect(dom.find('log-view')).toBeUndefined();
+ dom.get(searchQuerySelector).checkDisabled(false);
});
it('emits event on save query click', () => {
let detail: SaveQueryClickDetail | undefined;
- htmlElement
- .querySelector('viewer-search')
- ?.addEventListener(ViewerEvents.SaveQueryClick, (event) => {
+ dom
+ .get('viewer-search')
+ .addEventListener(ViewerEvents.SaveQueryClick, (event) => {
detail = (event as CustomEvent).detail;
});
const testName = 'Query 1';
component.inputData.savedSearches.push(
new ListedSearch(testQuery, testName),
);
- fixture.detectChanges();
+ dom.detectChanges();
addCurrentSearchWithResult();
- const saveField = assertDefined(
- htmlElement.querySelector('.current-search .save-field'),
- );
- const saveQueryButton = assertDefined(
- saveField.querySelector<HTMLElement>('.query-button'),
- );
- const input = assertDefined(
- saveField.querySelector<HTMLInputElement>('input'),
- );
- changeInput(input, testName);
- pressEnter(input);
+ const saveField = dom.get('.current-search .save-field');
+ const saveQueryButton = saveField.get('.query-button');
+ const input = saveField.get('input');
+ input.dispatchInput(testName);
saveQueryButton.click();
- fixture.detectChanges();
expect(detail).toBeUndefined(); // name already exists
const testName2 = 'Query 2';
- changeInput(input, testName2);
- pressEnter(input); // save by enter key
+ input.dispatchInput(testName2);
+ input.keydownEnter(); // save by enter key
expect(detail).toEqual(new SaveQueryClickDetail(testQuery, testName2));
const testName3 = 'Query 3';
- changeInput(input, testName3);
- saveQueryButton.click();
- fixture.detectChanges(); // save by click
+ input.dispatchInput(testName3);
+ saveQueryButton.click(); // save by click
expect(detail).toEqual(new SaveQueryClickDetail(testQuery, testName3));
});
it('emits event on delete saved query click', async () => {
let detail: DeleteSavedQueryClickDetail | undefined;
- htmlElement
- .querySelector('viewer-search')
- ?.addEventListener(ViewerEvents.DeleteSavedQueryClick, (event) => {
+ dom
+ .get('viewer-search')
+ .addEventListener(ViewerEvents.DeleteSavedQueryClick, (event) => {
detail = (event as CustomEvent).detail;
});
const search = new ListedSearch(testQuery);
component.inputData.savedSearches = [search];
- fixture.detectChanges();
+ dom.detectChanges();
await changeTab(1);
- const listedSearchButton = assertDefined(
- htmlElement.querySelectorAll<HTMLElement>('.listed-search-option'),
- );
- listedSearchButton.item(2).click();
+ dom.findAndClickByIndex(listedSearchSelector, 2);
expect(detail).toEqual(new DeleteSavedQueryClickDetail(search));
});
it('handles trace search initialization', () => {
component.inputData.initialized = false;
- fixture.detectChanges();
+ dom.detectChanges();
const spy = jasmine.createSpy();
- htmlElement
- .querySelector('viewer-search')
- ?.addEventListener(ViewerEvents.GlobalSearchSectionClick, (event) =>
+ dom
+ .get('viewer-search')
+ .addEventListener(ViewerEvents.GlobalSearchSectionClick, (event) =>
spy(),
);
- const globalSearch = assertDefined(
- htmlElement.querySelector<HTMLElement>('.global-search'),
- );
- expect(globalSearch.querySelector('.message-with-spinner')).toBeNull();
+ const globalSearch = dom.get('.global-search');
+ expect(globalSearch.find('.message-with-spinner')).toBeUndefined();
clickGlobalSearchAndCheckMessage(globalSearch);
clickGlobalSearchAndCheckMessage(globalSearch);
expect(spy).toHaveBeenCalledTimes(1);
- changeInput(getTextInput(), testQuery);
- expect(getSearchQueryButton().disabled).toBeTrue();
+ getTextInput().dispatchInput(testQuery);
+ dom.get(searchQuerySelector).checkDisabled(true);
const data = structuredClone(component.inputData);
data.initialized = true;
updateInputDataAndDetectChanges(data);
- expect(globalSearch.querySelector('.message-with-spinner')).toBeNull();
- expect(getSearchQueryButton().disabled).toBeFalse();
+ expect(globalSearch.find('.message-with-spinner')).toBeUndefined();
+ dom.get(searchQuerySelector).checkDisabled(false);
});
it('can open SQL view descriptors in how to section', () => {
- const accordionItems = htmlElement.querySelectorAll<HTMLElement>(
- '.how-to-search .accordion-item',
- );
+ const accordionItems = dom.findAll('.how-to-search .accordion-item');
expect(accordionItems.length).toEqual(6);
accordionItems.forEach((item) => checkAccordionItemCollapsed(item));
- clickAccordionItemHeader(accordionItems.item(0));
- checkAccordionItemExpanded(accordionItems.item(0));
- checkAccordionItemCollapsed(accordionItems.item(1));
+ accordionItems[0].get(accordionItemSelector).click();
+ checkAccordionItemExpanded(accordionItems[0]);
+ checkAccordionItemCollapsed(accordionItems[1]);
- clickAccordionItemHeader(accordionItems.item(1));
- checkAccordionItemExpanded(accordionItems.item(0));
- checkAccordionItemExpanded(accordionItems.item(1));
+ accordionItems[1].get(accordionItemSelector).click();
+ checkAccordionItemExpanded(accordionItems[0]);
+ checkAccordionItemExpanded(accordionItems[1]);
- clickAccordionItemHeader(accordionItems.item(0));
- checkAccordionItemCollapsed(accordionItems.item(0));
- checkAccordionItemExpanded(accordionItems.item(1));
+ accordionItems[0].get(accordionItemSelector).click();
+ checkAccordionItemCollapsed(accordionItems[0]);
+ checkAccordionItemExpanded(accordionItems[1]);
});
- function clickGlobalSearchAndCheckMessage(globalSearch: HTMLElement) {
- globalSearch.click();
- fixture.detectChanges();
- expect(globalSearch.querySelector('.message-with-spinner')).toBeTruthy();
- expect(getSearchQueryButton().disabled).toBeTrue();
- }
-
- function getTextInput(i = 0): HTMLTextAreaElement {
- return htmlElement
- .querySelectorAll<HTMLTextAreaElement>('.query-field textarea')
- .item(i);
- }
-
- function changeInput(
- input: HTMLInputElement | HTMLTextAreaElement,
- query: string,
+ function clickGlobalSearchAndCheckMessage(
+ globalSearch: DOMTestHelper<TestHostComponent>,
) {
- input.value = query;
- input.dispatchEvent(new Event('input'));
- fixture.detectChanges();
+ globalSearch.click();
+ expect(dom.find('.message-with-spinner')).toBeDefined();
+ dom.get(searchQuerySelector).checkDisabled(true);
}
- function getSearchQueryButton(i = 0): HTMLButtonElement {
- return htmlElement
- .querySelectorAll<HTMLButtonElement>('.query-actions .search-button')
- .item(i);
- }
-
- function clickSearchQueryButton(i = 0) {
- getSearchQueryButton(i).click();
- fixture.detectChanges();
+ function getTextInput(i = 0): DOMTestHelper<TestHostComponent> {
+ return dom.findAll('.query-field textarea')[i];
}
function runSearchByQueryButton(i = 0) {
- changeInput(getTextInput(i), testQuery);
- clickSearchQueryButton(i);
+ getTextInput(i).dispatchInput(testQuery);
+ dom.findAndClickByIndex(searchQuerySelector, i);
}
async function changeTab(index: number) {
const matTabGroups = assertDefined(component.searchComponent?.matTabGroups);
matTabGroups.first.selectedIndex = index;
- fixture.detectChanges();
- await fixture.whenStable();
+ await dom.detectChangesAndWaitStable();
}
async function checkRunQueryFromOptionsWhenResultPresent(tabIndex: number) {
@@ -452,63 +384,46 @@
data.currentSearches[0].query = testQuery;
data.currentSearches[0].result = new SearchResult([], []);
let query: string | undefined;
- htmlElement
- .querySelector('viewer-search')
- ?.addEventListener(ViewerEvents.AddQueryClick, (event) => {
+ dom
+ .get('viewer-search')
+ .addEventListener(ViewerEvents.AddQueryClick, (event) => {
const detail: AddQueryClickDetail = (event as CustomEvent).detail;
query = detail.query;
});
updateInputDataAndDetectChanges(data);
await changeTab(tabIndex);
- runSearchFromListedSearchOption();
+ dom.findAndClick(listedSearchSelector);
expect(query).toEqual(testQuery);
await changeTab(0);
runSearchAndCheckHandled(addCurrentSearchWithResult);
- const activeSections = htmlElement.querySelectorAll('active-search');
- expect(activeSections.length).toEqual(2);
- }
-
- function runSearchFromListedSearchOption() {
- assertDefined(
- htmlElement.querySelector<HTMLElement>('.listed-search-option'),
- ).click();
- fixture.detectChanges();
+ expect(dom.findAll('active-search').length).toEqual(2);
}
function runSearchAndCheckHandled(runSearch: () => void) {
let query: string | undefined;
- htmlElement
- .querySelector('viewer-search')
- ?.addEventListener(ViewerEvents.SearchQueryClick, (event) => {
+ dom
+ .get('viewer-search')
+ .addEventListener(ViewerEvents.SearchQueryClick, (event) => {
const detail: SearchQueryClickDetail = (event as CustomEvent).detail;
query = detail.query;
});
runSearch();
expect(query).toEqual(testQuery);
- expect(getSearchQueryButton().disabled).toBeTrue();
- const runningQueryMessage = assertDefined(
- htmlElement.querySelector('.running-query-message'),
- );
- expect(runningQueryMessage.textContent?.trim()).toEqual(
- 'timer Calculating results',
- );
- expect(runningQueryMessage.querySelector('mat-spinner')).toBeTruthy();
- }
-
- function pressEnter(input: HTMLInputElement, shiftKey = false) {
- input.dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter', shiftKey}));
- fixture.detectChanges();
+ dom.get(searchQuerySelector).checkDisabled(true);
+ const runningQueryMessage = dom.get('.running-query-message');
+ runningQueryMessage.checkTextExact('timer Calculating results');
+ expect(runningQueryMessage.find('mat-spinner')).toBeDefined();
}
async function checkEditQueryFromOptionsWhenResultPresent(tabIndex: number) {
component.inputData.currentSearches[0].result = new SearchResult([], []);
- fixture.detectChanges();
+ dom.detectChanges();
let query: string | undefined;
- htmlElement
- .querySelector('viewer-search')
- ?.addEventListener(ViewerEvents.AddQueryClick, (event) => {
+ dom
+ .get('viewer-search')
+ .addEventListener(ViewerEvents.AddQueryClick, (event) => {
const detail: AddQueryClickDetail = (event as CustomEvent).detail;
query = detail.query;
});
@@ -522,34 +437,30 @@
const data = structuredClone(component.inputData);
data.currentSearches.push(new CurrentSearch(2, testQuery));
updateInputDataAndDetectChanges(data);
- fixture.detectChanges();
- await fixture.whenStable();
+ await dom.detectChangesAndWaitStable();
expect(
component.searchComponent?.matTabGroups?.first.selectedIndex,
).toEqual(0);
- expect(getTextInput(0).value).toEqual('');
- expect(getTextInput(1).value).toEqual(testQuery);
+ getTextInput(0).checkValue('');
+ getTextInput(1).checkValue(testQuery);
}
async function checkEditQueryFromOptions(tabIndex: number) {
- fixture.detectChanges();
+ dom.detectChanges();
const input = getTextInput();
- expect(input.value).toEqual('');
+ expect(input.checkValue(''));
await changeTabAndClickEdit(tabIndex);
expect(
component.searchComponent?.matTabGroups?.first.selectedIndex,
).toEqual(0);
- expect(input.value).toEqual(testQuery);
+ expect(input.checkValue(testQuery));
}
async function changeTabAndClickEdit(tabIndex: number) {
await changeTab(tabIndex);
- const listedSearchButton = assertDefined(
- htmlElement.querySelectorAll<HTMLElement>('.listed-search-option'),
- );
- listedSearchButton.item(1).click();
- fixture.detectChanges();
- await fixture.whenStable();
+ const listedSearchButton = dom.findAll('.listed-search-option');
+ listedSearchButton[1].click();
+ await dom.whenStable();
}
function addCurrentSearchWithResult(q = testQuery, uid = 2) {
@@ -559,33 +470,19 @@
updateInputDataAndDetectChanges(data);
}
- function getAccordionItemHeader(item: HTMLElement) {
- return assertDefined(
- item.querySelector<HTMLElement>('.accordion-item-header'),
- );
+ function checkAccordionItemCollapsed(item: DOMTestHelper<TestHostComponent>) {
+ item.get(accordionItemSelector).checkText('chevron_right');
+ expect(item.find('.accordion-item-body')).toBeUndefined();
}
- function clickAccordionItemHeader(item: HTMLElement) {
- const header = getAccordionItemHeader(item);
- header.click();
- fixture.detectChanges();
- }
-
- function checkAccordionItemCollapsed(item: HTMLElement) {
- const header = getAccordionItemHeader(item);
- expect(header.textContent).toContain('chevron_right');
- expect(item.querySelector('.accordion-item-body')).toBeNull();
- }
-
- function checkAccordionItemExpanded(item: HTMLElement) {
- const header = getAccordionItemHeader(item);
- expect(header.textContent).toContain('arrow_drop_down');
- expect(item.querySelector('.accordion-item-body')).toBeTruthy();
+ function checkAccordionItemExpanded(item: DOMTestHelper<TestHostComponent>) {
+ item.get(accordionItemSelector).checkText('arrow_drop_down');
+ expect(item.find('.accordion-item-body')).toBeDefined();
}
function updateInputDataAndDetectChanges(data: UiData) {
component.inputData = data;
- fixture.detectChanges();
+ dom.detectChanges();
}
@Component({