Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Serverless] New UX for Global Search bar #158978

Merged
merged 8 commits into from
Jun 21, 2023
Merged
342 changes: 204 additions & 138 deletions x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
* 2.0.
*/

import React from 'react';
import { act, render, screen, fireEvent } from '@testing-library/react';
import { of, BehaviorSubject } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import type { ChromeStyle } from '@kbn/core-chrome-browser';
import { applicationServiceMock } from '@kbn/core/public/mocks';
import { globalSearchPluginMock } from '@kbn/global-search-plugin/public/mocks';
import { GlobalSearchBatchedResults, GlobalSearchResult } from '@kbn/global-search-plugin/public';
import { SearchBar } from './search_bar';
import { globalSearchPluginMock } from '@kbn/global-search-plugin/public/mocks';
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
import { TrackUiMetricFn } from '../types';
import { act, fireEvent, render, screen } from '@testing-library/react';
import React from 'react';
import { BehaviorSubject, of } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import type { TrackUiMetricFn } from '../types';
import { SearchBar } from './search_bar';

jest.mock(
'react-virtualized-auto-sizer',
Expand Down Expand Up @@ -87,145 +88,210 @@ describe('SearchBar', () => {
expect(await screen.findAllByTestId('nav-search-option')).toHaveLength(list.length);
};

it('correctly filters and sorts results', async () => {
searchService.find
.mockReturnValueOnce(
of(
createBatch('Discover', 'Canvas'),
createBatch({ id: 'Visualize', type: 'test' }, 'Graph')
)
)
.mockReturnValueOnce(of(createBatch('Discover', { id: 'My Dashboard', type: 'test' })));

render(
<IntlProvider locale="en">
<SearchBar
globalSearch={searchService}
navigateToUrl={applications.navigateToUrl}
basePathUrl={basePathUrl}
darkMode={darkMode}
trackUiMetric={trackUiMetric}
/>
</IntlProvider>
);

expect(searchService.find).toHaveBeenCalledTimes(0);

await focusAndUpdate();

expect(searchService.find).toHaveBeenCalledTimes(1);
expect(searchService.find).toHaveBeenCalledWith({}, {});
await assertSearchResults(['Canvas • Kibana', 'Discover • Kibana', 'Graph • Kibana']);

simulateTypeChar('d');

await assertSearchResults(['Discover • Kibana', 'My Dashboard • Test']);
expect(searchService.find).toHaveBeenCalledTimes(2);
expect(searchService.find).toHaveBeenLastCalledWith({ term: 'd' }, {});

expect(trackUiMetric).nthCalledWith(1, 'count', 'search_focus');
expect(trackUiMetric).nthCalledWith(2, 'count', 'search_request');
expect(trackUiMetric).toHaveBeenCalledTimes(2);
});
describe('chromeStyle: classic', () => {
const chromeStyle$ = of<ChromeStyle>('classic');

it('supports keyboard shortcuts', async () => {
render(
<IntlProvider locale="en">
<SearchBar
globalSearch={searchService}
navigateToUrl={applications.navigateToUrl}
basePathUrl={basePathUrl}
darkMode={darkMode}
trackUiMetric={trackUiMetric}
/>
</IntlProvider>
);
act(() => {
fireEvent.keyDown(window, { key: '/', ctrlKey: true, metaKey: true });
it('correctly filters and sorts results', async () => {
searchService.find
.mockReturnValueOnce(
of(
createBatch('Discover', 'Canvas'),
createBatch({ id: 'Visualize', type: 'test' }, 'Graph')
)
)
.mockReturnValueOnce(of(createBatch('Discover', { id: 'My Dashboard', type: 'test' })));

render(
<IntlProvider locale="en">
<SearchBar
globalSearch={searchService}
navigateToUrl={applications.navigateToUrl}
basePathUrl={basePathUrl}
darkMode={darkMode}
chromeStyle$={chromeStyle$}
trackUiMetric={trackUiMetric}
/>
</IntlProvider>
);

expect(searchService.find).toHaveBeenCalledTimes(0);

await focusAndUpdate();

expect(searchService.find).toHaveBeenCalledTimes(1);
expect(searchService.find).toHaveBeenCalledWith({}, {});
await assertSearchResults(['Canvas • Kibana', 'Discover • Kibana', 'Graph • Kibana']);

simulateTypeChar('d');

await assertSearchResults(['Discover • Kibana', 'My Dashboard • Test']);
expect(searchService.find).toHaveBeenCalledTimes(2);
expect(searchService.find).toHaveBeenLastCalledWith({ term: 'd' }, {});

expect(trackUiMetric).nthCalledWith(1, 'count', 'search_focus');
expect(trackUiMetric).nthCalledWith(2, 'count', 'search_request');
expect(trackUiMetric).toHaveBeenCalledTimes(2);
});

const inputElement = await screen.findByTestId('nav-search-input');

expect(document.activeElement).toEqual(inputElement);
it('supports keyboard shortcuts', async () => {
render(
<IntlProvider locale="en">
<SearchBar
globalSearch={searchService}
navigateToUrl={applications.navigateToUrl}
basePathUrl={basePathUrl}
darkMode={darkMode}
chromeStyle$={chromeStyle$}
trackUiMetric={trackUiMetric}
/>
</IntlProvider>
);
act(() => {
fireEvent.keyDown(window, { key: '/', ctrlKey: true, metaKey: true });
});

const inputElement = await screen.findByTestId('nav-search-input');

expect(document.activeElement).toEqual(inputElement);

expect(trackUiMetric).nthCalledWith(1, 'count', 'shortcut_used');
expect(trackUiMetric).nthCalledWith(2, 'count', 'search_focus');
expect(trackUiMetric).toHaveBeenCalledTimes(2);
});

expect(trackUiMetric).nthCalledWith(1, 'count', 'shortcut_used');
expect(trackUiMetric).nthCalledWith(2, 'count', 'search_focus');
expect(trackUiMetric).toHaveBeenCalledTimes(2);
});
it('only display results from the last search', async () => {
const firstSearchTrigger = new BehaviorSubject<boolean>(false);
const firstSearch = firstSearchTrigger.pipe(
filter((event) => event),
map(() => {
return createBatch('Discover', 'Canvas');
})
);
const secondSearch = of(createBatch('Visualize', 'Map'));

searchService.find.mockReturnValueOnce(firstSearch).mockReturnValueOnce(secondSearch);

render(
<IntlProvider locale="en">
<SearchBar
globalSearch={searchService}
navigateToUrl={applications.navigateToUrl}
basePathUrl={basePathUrl}
darkMode={darkMode}
chromeStyle$={chromeStyle$}
trackUiMetric={trackUiMetric}
/>
</IntlProvider>
);

await focusAndUpdate();

expect(searchService.find).toHaveBeenCalledTimes(1);
//
simulateTypeChar('d');
await assertSearchResults(['Visualize • Kibana', 'Map • Kibana']);

firstSearchTrigger.next(true);

update();

await assertSearchResults(['Visualize • Kibana', 'Map • Kibana']);
});

it('only display results from the last search', async () => {
const firstSearchTrigger = new BehaviorSubject<boolean>(false);
const firstSearch = firstSearchTrigger.pipe(
filter((event) => event),
map(() => {
return createBatch('Discover', 'Canvas');
})
);
const secondSearch = of(createBatch('Visualize', 'Map'));

searchService.find.mockReturnValueOnce(firstSearch).mockReturnValueOnce(secondSearch);

render(
<IntlProvider locale="en">
<SearchBar
globalSearch={searchService}
navigateToUrl={applications.navigateToUrl}
basePathUrl={basePathUrl}
darkMode={darkMode}
trackUiMetric={trackUiMetric}
/>
</IntlProvider>
);

await focusAndUpdate();

expect(searchService.find).toHaveBeenCalledTimes(1);
//
simulateTypeChar('d');
await assertSearchResults(['Visualize • Kibana', 'Map • Kibana']);

firstSearchTrigger.next(true);

update();

await assertSearchResults(['Visualize • Kibana', 'Map • Kibana']);
it('tracks the application navigated to', async () => {
searchService.find.mockReturnValueOnce(
of(createBatch('Discover', { id: 'My Dashboard', type: 'test' }))
);

render(
<IntlProvider locale="en">
<SearchBar
globalSearch={searchService}
navigateToUrl={applications.navigateToUrl}
basePathUrl={basePathUrl}
darkMode={darkMode}
chromeStyle$={chromeStyle$}
trackUiMetric={trackUiMetric}
/>
</IntlProvider>
);

expect(searchService.find).toHaveBeenCalledTimes(0);

await focusAndUpdate();

expect(searchService.find).toHaveBeenCalledTimes(1);
expect(searchService.find).toHaveBeenCalledWith({}, {});
await assertSearchResults(['Discover • Kibana']);

const navSearchOptionToClick = await screen.findByTestId('nav-search-option');
act(() => {
fireEvent.click(navSearchOptionToClick);
});

expect(trackUiMetric).nthCalledWith(1, 'count', 'search_focus');
expect(trackUiMetric).nthCalledWith(2, 'click', [
'user_navigated_to_application',
'user_navigated_to_application_discover',
]);
expect(trackUiMetric).toHaveBeenCalledTimes(2);
});
});

it('tracks the application navigated to', async () => {
searchService.find.mockReturnValueOnce(
of(createBatch('Discover', { id: 'My Dashboard', type: 'test' }))
);

render(
<IntlProvider locale="en">
<SearchBar
globalSearch={searchService}
navigateToUrl={applications.navigateToUrl}
basePathUrl={basePathUrl}
darkMode={darkMode}
trackUiMetric={trackUiMetric}
/>
</IntlProvider>
);

expect(searchService.find).toHaveBeenCalledTimes(0);

await focusAndUpdate();

expect(searchService.find).toHaveBeenCalledTimes(1);
expect(searchService.find).toHaveBeenCalledWith({}, {});
await assertSearchResults(['Discover • Kibana']);

const navSearchOptionToClick = await screen.findByTestId('nav-search-option');
act(() => {
fireEvent.click(navSearchOptionToClick);
describe('chromeStyle: project', () => {
const chromeStyle$ = of<ChromeStyle>('project');

it('supports keyboard shortcuts', async () => {
render(
<IntlProvider locale="en">
<SearchBar
globalSearch={searchService}
navigateToUrl={applications.navigateToUrl}
basePathUrl={basePathUrl}
darkMode={darkMode}
chromeStyle$={chromeStyle$}
trackUiMetric={trackUiMetric}
/>
</IntlProvider>
);

act(() => {
fireEvent.keyDown(window, { key: '/', ctrlKey: true, metaKey: true });
});

const inputElement = await screen.findByTestId('nav-search-input');

expect(document.activeElement).toEqual(inputElement);

fireEvent.click(await screen.findByTestId('nav-search-conceal'));
expect(screen.queryAllByTestId('nav-search-input')).toHaveLength(0);

expect(trackUiMetric).nthCalledWith(1, 'count', 'shortcut_used');
expect(trackUiMetric).nthCalledWith(2, 'count', 'search_focus');
expect(trackUiMetric).toHaveBeenCalledTimes(2);
});

expect(trackUiMetric).nthCalledWith(1, 'count', 'search_focus');
expect(trackUiMetric).nthCalledWith(2, 'click', [
'user_navigated_to_application',
'user_navigated_to_application_discover',
]);
expect(trackUiMetric).toHaveBeenCalledTimes(2);
it('supports show/hide', async () => {
render(
<IntlProvider locale="en">
<SearchBar
globalSearch={searchService}
navigateToUrl={applications.navigateToUrl}
basePathUrl={basePathUrl}
darkMode={darkMode}
chromeStyle$={chromeStyle$}
trackUiMetric={trackUiMetric}
/>
</IntlProvider>
);

fireEvent.click(await screen.findByTestId('nav-search-reveal'));
expect(await screen.findByTestId('nav-search-input')).toBeVisible();

fireEvent.click(await screen.findByTestId('nav-search-conceal'));
expect(screen.queryAllByTestId('nav-search-input')).toHaveLength(0);

expect(trackUiMetric).nthCalledWith(1, 'count', 'search_focus');
});
});
});
Loading