[Log Explorer] Add test suite for Dataset Selector (#163079)

## 📓 Summary

Closes #160627 

This implementation adds the majority of the tests listed down here for
the Log Explorer current implementation.

 [**Flaky Test Runner - x50
executions**](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2844#_)

```
↳ Discover Log-Explorer profile
   ↳ Columns selection initialization and update
     ↳ when the log explorer profile loads
       ↳ should initialize the table columns to logs' default selection
       ↳ should restore the table columns from the URL state if exists
   ↳ Customizations
     ↳ when Discover is loaded with the log-explorer profile
       ↳ DatasetSelector should replace the DataViewPicker
       ↳ the TopNav bar should hide the New, Open and Save options
       ↳ should add a searchable deep link to the profile page
       ↳ should render a filter controls section as part of the unified search bar
   ↳ DatasetSelection initialization and update
     ↳ when the "index" query param does not exist
       ↳ should initialize the "All log datasets" selection
     ↳ when the "index" query param exists
       ↳ should decode and restore the selection from a valid encoded index
       ↳ should fallback to the "All log datasets" selection and notify the user of an invalid encoded index
     ↳ when navigating back and forth on the page history
       ↳ should decode and restore the selection for the current index
   ↳ Dataset Selector
     ↳ without installed integrations or uncategorized data streams
       ↳ when open on the first navigation level
         ↳ should always display the "All log datasets" entry as the first item
         ↳ should always display the unmanaged datasets entry as the second item
         ↳ should display an error prompt if could not retrieve the integrations
         ↳ should display an empty prompt for no integrations
       ↳ when navigating into Uncategorized data streams
         ↳ should display a loading skeleton while loading
         ↳ should display an error prompt if could not retrieve the data streams
         ↳ should display an empty prompt for no data streams
     ↳ with installed integrations and uncategorized data streams
       ↳ when open on the first navigation level
         ↳ should always display the "All log datasets" entry as the first item
         ↳ should always display the unmanaged datasets entry as the second item
         ↳ should display a list of installed integrations
         ↳ should sort the integrations list by the clicked sorting option
         ↳ should filter the integrations list by the typed integration name
         ↳ should display an empty prompt when the search does not match any result
         ↳ should load more integrations by scrolling to the end of the list
       ↳ when clicking on integration and moving into the second navigation level
         ↳ should display a list of available datasets
         ↳ should sort the datasets list by the clicked sorting option
         ↳ should filter the datasets list by the typed dataset name
         ↳ should update the current selection with the clicked dataset
       ↳ when navigating into Uncategorized data streams
         ↳ should display a list of available datasets
         ↳ should sort the datasets list by the clicked sorting option
         ↳ should filter the datasets list by the typed dataset name
         ↳ should update the current selection with the clicked dataset
       ↳ when open/close the selector
         ↳ should restore the latest navigation panel
         ↳ should restore the latest search results
       ↳ when switching between integration panels
         ↳ should remember the latest search and restore its results for each integration
```

## Note on serverless tests suite

For testing the feature in a serverless environment, we are copying all
the tests into the `x-pack/test_serverless` folder until
https://github.com/elastic/kibana/pull/161574 is merged, which will
provide a new space to write tests independently from the deployment
type, avoiding then tests duplication.

## New `browser` service utils for Network conditions simulation

To properly test that this feature works correctly under poor network
conditions or offline scenarios, the `browser` service now exposes some
new methods for altering network conditions on demand.

Also, network profiles to match the [network profiles provided by Chrome
debugger](da276a3fae/front_end/core/sdk/NetworkManager.ts (L363-L393))
have been created.

In case the browser is not of `chromium` type and the driver does not
support the network simulation, these methods throw an error that can be
caught for skipping the affected test.

---------

Co-authored-by: Marco Antonio Ghiani <marcoantonio.ghiani@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Marco Antonio Ghiani 2023-08-11 15:32:42 +02:00 committed by GitHub
parent 27c394c936
commit f09a5c976c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 2198 additions and 15 deletions

View file

@ -168,6 +168,7 @@ export function DatasetSelector({
onPanelChange={changePanel}
className="eui-yScroll"
css={contextMenuStyles}
data-test-subj="datasetSelectorContextMenu"
size="s"
/>
</DatasetsPopover>

View file

@ -44,6 +44,7 @@ export const DatasetsList = ({
if (hasError) {
return (
<EuiEmptyPrompt
data-test-subj="datasetErrorPrompt"
iconType="warning"
iconColor="danger"
paddingSize="m"
@ -70,6 +71,7 @@ export const DatasetsList = ({
if (isEmpty) {
return (
<EuiEmptyPrompt
data-test-subj="emptyDatasetPrompt"
iconType="search"
paddingSize="m"
title={<h2>{noDatasetsLabel}</h2>}

View file

@ -45,7 +45,8 @@ export const DatasetsPopover = ({
return (
<EuiPopover
id={POPOVER_ID}
data-test-subj={POPOVER_ID}
data-test-subj="datasetSelectorPopover"
anchorPosition={isMobile ? 'downCenter' : 'downLeft'}
button={
<EuiButton
css={buttonStyles}
@ -53,7 +54,7 @@ export const DatasetsPopover = ({
iconSide="right"
onClick={onClick}
fullWidth={isMobile}
data-test-subj={`${POPOVER_ID}-button`}
data-test-subj="datasetSelectorPopoverButton"
>
{iconType ? (
<EuiIcon type={iconType} />
@ -74,7 +75,12 @@ export const DatasetsPopover = ({
{...(isMobile && { display: 'block' })}
{...props}
>
<EuiPanel paddingSize="none" hasShadow={false} css={panelStyle}>
<EuiPanel
paddingSize="none"
hasShadow={false}
css={panelStyle}
data-test-subj="datasetSelectorContent"
>
<Title size="xxs">
<span>{selectDatasetLabel}</span>
</Title>

View file

@ -10,7 +10,7 @@ import { EuiPanel, EuiSkeletonText } from '@elastic/eui';
import { uncategorizedLabel } from '../constants';
export const DatasetSkeleton = () => (
<EuiPanel>
<EuiPanel data-test-subj="datasetSelectorSkeleton">
<EuiSkeletonText lines={7} isLoading contentAriaLabel={uncategorizedLabel} />
</EuiPanel>
);

View file

@ -34,6 +34,7 @@ export const IntegrationsListStatus = ({
if (hasError) {
return (
<EuiEmptyPrompt
data-test-subj="integrationsErrorPrompt"
iconType="warning"
iconColor="danger"
paddingSize="m"

View file

@ -33,7 +33,12 @@ export const SearchControls = ({ search, onSearch, onSort, isLoading }: SearchCo
};
return (
<EuiPanel paddingSize="s" hasShadow={false} css={{ width: DATA_VIEW_POPOVER_CONTENT_WIDTH }}>
<EuiPanel
paddingSize="s"
hasShadow={false}
css={{ width: DATA_VIEW_POPOVER_CONTENT_WIDTH }}
data-test-subj="datasetSelectorSearchControls"
>
<EuiFlexGroup gutterSize="xs" responsive={false}>
<EuiFlexItem>
<EuiFieldSearch

View file

@ -61,6 +61,7 @@ export const buildIntegrationsTree = ({
integrationsTree.items.push({
name: title,
icon: <PackageIcon packageName={name} version={version} size="m" icons={icons} tryApi />,
'data-test-subj': integration.id,
panel: integration.id,
...(isLastIntegration && { buttonRef: spyRef }),
});
@ -85,6 +86,7 @@ export const createAllLogDatasetsItem = ({ onClick }: { onClick(): void }) => {
const allLogDataset = Dataset.createAllLogsDataset();
return {
name: allLogDataset.title,
'data-test-subj': 'allLogDatasets',
icon: allLogDataset.iconType && <EuiIcon type={allLogDataset.iconType} />,
onClick,
};
@ -93,6 +95,7 @@ export const createAllLogDatasetsItem = ({ onClick }: { onClick(): void }) => {
export const createUnmanagedDatasetsItem = ({ onClick }: { onClick: LoadDatasets }) => {
return {
name: uncategorizedLabel,
'data-test-subj': 'unmanagedDatasets',
icon: <EuiIcon type="documents" />,
onClick,
panel: UNMANAGED_STREAMS_PANEL_ID,
@ -103,5 +106,6 @@ export const createIntegrationStatusItem = (props: IntegrationsListStatusProps)
return {
disabled: true,
name: <IntegrationsListStatus {...props} />,
'data-test-subj': 'integrationStatusItem',
};
};

View file

@ -12,6 +12,8 @@ import { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { useControlPanels } from '../hooks/use_control_panels';
import { LogExplorerProfileStateService } from '../state_machines/log_explorer_profile';
const DATASET_FILTERS_CUSTOMIZATION_ID = 'datasetFiltersCustomization';
interface CustomDatasetFiltersProps {
logExplorerProfileStateService: LogExplorerProfileStateService;
data: DataPublicPluginStart;
@ -27,7 +29,7 @@ const CustomDatasetFilters = ({
);
return (
<ControlGroupContainer>
<ControlGroupContainer data-test-subj={DATASET_FILTERS_CUSTOMIZATION_ID}>
<ControlGroupRenderer
ref={setControlGroupAPI}
getCreationOptions={getInitialInput}

View file

@ -0,0 +1,57 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
const defaultLogColumns = ['@timestamp', 'message'];
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'discover']);
describe('Columns selection initialization and update', () => {
before(async () => {
await esArchiver.load(
'x-pack/test/functional/es_archives/discover_log_explorer/data_streams'
);
});
after(async () => {
await esArchiver.unload(
'x-pack/test/functional/es_archives/discover_log_explorer/data_streams'
);
});
describe('when the log explorer profile loads', () => {
it("should initialize the table columns to logs' default selection", async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
await PageObjects.discover.expandTimeRangeAsSuggestedInNoResultsMessage();
await retry.try(async () => {
expect(await PageObjects.discover.getColumnHeaders()).to.eql(defaultLogColumns);
});
});
it('should restore the table columns from the URL state if exists', async () => {
await PageObjects.common.navigateToApp('discover', {
hash: '/p/log-explorer?_a=(columns:!(message,data_stream.namespace))',
});
await PageObjects.discover.expandTimeRangeAsSuggestedInNoResultsMessage();
await retry.try(async () => {
expect(await PageObjects.discover.getColumnHeaders()).to.eql([
...defaultLogColumns,
'data_stream.namespace',
]);
});
});
});
});
}

View file

@ -25,14 +25,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('DatasetSelector should replace the DataViewPicker', async () => {
// Assert does not render on discover app
await PageObjects.common.navigateToApp('discover');
await testSubjects.missingOrFail('dataset-selector-popover');
await testSubjects.missingOrFail('datasetSelectorPopover');
// Assert it renders on log-explorer profile
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
await testSubjects.existOrFail('dataset-selector-popover');
await testSubjects.existOrFail('datasetSelectorPopover');
});
it('the TopNav bar should hide New, Open and Save options', async () => {
it('the TopNav bar should hide then New, Open and Save options', async () => {
// Assert does not render on discover app
await PageObjects.common.navigateToApp('discover');
await testSubjects.existOrFail('discoverNewButton');
@ -59,6 +59,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const results = await PageObjects.navigationalSearch.getDisplayedResults();
expect(results[0].label).to.eql('Discover / Logs Explorer');
});
it('should render a filter controls section as part of the unified search bar', async () => {
// Assert does not render on discover app
await PageObjects.common.navigateToApp('discover');
await testSubjects.missingOrFail('datasetFiltersCustomization');
// Assert it renders on log-explorer profile
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
await testSubjects.existOrFail('datasetFiltersCustomization', { allowHidden: true });
});
});
});
}

View file

@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
describe('when the "index" query param exist', () => {
describe('when the "index" query param exists', () => {
it('should decode and restore the selection from a valid encoded index', async () => {
const azureActivitylogsIndex =
'BQZwpgNmDGAuCWB7AdgLmAEwIay+W6yWAtmKgOQSIDmIAtFgF4CuATmAHRZzwBu8sAJ5VadAFTkANAlhRU3BPyEiQASklFS8lu2kC55AII6wAAgAyNEFN5hWIJGnIBGDgFYOAJgDM5deCgeFAAVQQAHMgdkaihVIA===';
@ -37,7 +37,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(datasetSelectionTitle).to.be('[Azure Logs] activitylogs');
});
it('should fallback to "All log datasets" selection and notify the user for an invalid encoded index', async () => {
it('should fallback to the "All log datasets" selection and notify the user of an invalid encoded index', async () => {
const invalidEncodedIndex = 'invalid-encoded-index';
await PageObjects.common.navigateToApp('discover', {
hash: `/p/log-explorer?_a=(index:${encodeURIComponent(invalidEncodedIndex)})`,

View file

@ -0,0 +1,664 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
const initialPackageMap = {
apache: 'Apache HTTP Server',
aws: 'AWS',
system: 'System',
};
const initialPackagesTexts = Object.values(initialPackageMap);
const expectedUncategorized = ['logs-gaming-*', 'logs-manufacturing-*', 'logs-retail-*'];
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const browser = getService('browser');
const esArchiver = getService('esArchiver');
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'discoverLogExplorer']);
describe('Dataset Selector', () => {
before(async () => {
await PageObjects.discoverLogExplorer.removeInstalledPackages();
});
describe('without installed integrations or uncategorized data streams', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
beforeEach(async () => {
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
});
describe('when open on the first navigation level', () => {
it('should always display the "All log datasets" entry as the first item', async () => {
const allLogDatasetButton =
await PageObjects.discoverLogExplorer.getAllLogDatasetsButton();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
const allLogDatasetTitle = await allLogDatasetButton.getVisibleText();
const firstEntryTitle = await menuEntries[0].getVisibleText();
expect(allLogDatasetTitle).to.be('All log datasets');
expect(allLogDatasetTitle).to.be(firstEntryTitle);
});
it('should always display the unmanaged datasets entry as the second item', async () => {
const unamanagedDatasetButton =
await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
const unmanagedDatasetTitle = await unamanagedDatasetButton.getVisibleText();
const secondEntryTitle = await menuEntries[1].getVisibleText();
expect(unmanagedDatasetTitle).to.be('Uncategorized');
expect(unmanagedDatasetTitle).to.be(secondEntryTitle);
});
it('should display an error prompt if could not retrieve the integrations', async function () {
// Skip the test in case network condition utils are not available
try {
await retry.try(async () => {
await PageObjects.discoverLogExplorer.assertNoIntegrationsPromptExists();
});
await PageObjects.common.sleep(5000);
await browser.setNetworkConditions('OFFLINE');
await PageObjects.discoverLogExplorer.typeSearchFieldWith('a');
await retry.try(async () => {
await PageObjects.discoverLogExplorer.assertNoIntegrationsErrorExists();
});
await browser.restoreNetworkConditions();
} catch (error) {
this.skip();
}
});
it('should display an empty prompt for no integrations', async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations.length).to.be(0);
await PageObjects.discoverLogExplorer.assertNoIntegrationsPromptExists();
});
});
describe('when navigating into Uncategorized data streams', () => {
it('should display a loading skeleton while loading', async function () {
// Skip the test in case network condition utils are not available
try {
await browser.setNetworkConditions('SLOW_3G'); // Almost stuck network conditions
const unamanagedDatasetButton =
await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await unamanagedDatasetButton.click();
await PageObjects.discoverLogExplorer.assertLoadingSkeletonExists();
await browser.restoreNetworkConditions();
} catch (error) {
this.skip();
}
});
it('should display an error prompt if could not retrieve the data streams', async function () {
// Skip the test in case network condition utils are not available
try {
const unamanagedDatasetButton =
await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await unamanagedDatasetButton.click();
await retry.try(async () => {
await PageObjects.discoverLogExplorer.assertNoDataStreamsPromptExists();
});
await browser.setNetworkConditions('OFFLINE');
await PageObjects.discoverLogExplorer.typeSearchFieldWith('a');
await retry.try(async () => {
await PageObjects.discoverLogExplorer.assertNoDataStreamsErrorExists();
});
await browser.restoreNetworkConditions();
} catch (error) {
this.skip();
}
});
it('should display an empty prompt for no data streams', async () => {
const unamanagedDatasetButton =
await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await unamanagedDatasetButton.click();
const unamanagedDatasetEntries =
await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(unamanagedDatasetEntries.length).to.be(0);
await PageObjects.discoverLogExplorer.assertNoDataStreamsPromptExists();
});
});
});
describe('with installed integrations and uncategorized data streams', () => {
let cleanupIntegrationsSetup: () => Promise<void>;
before(async () => {
await esArchiver.load(
'x-pack/test/functional/es_archives/discover_log_explorer/data_streams'
);
cleanupIntegrationsSetup = await PageObjects.discoverLogExplorer.setupInitialIntegrations();
});
after(async () => {
await esArchiver.unload(
'x-pack/test/functional/es_archives/discover_log_explorer/data_streams'
);
await cleanupIntegrationsSetup();
});
describe('when open on the first navigation level', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
beforeEach(async () => {
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
});
it('should always display the "All log datasets" entry as the first item', async () => {
const allLogDatasetButton =
await PageObjects.discoverLogExplorer.getAllLogDatasetsButton();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
const allLogDatasetTitle = await allLogDatasetButton.getVisibleText();
const firstEntryTitle = await menuEntries[0].getVisibleText();
expect(allLogDatasetTitle).to.be('All log datasets');
expect(allLogDatasetTitle).to.be(firstEntryTitle);
});
it('should always display the unmanaged datasets entry as the second item', async () => {
const unamanagedDatasetButton =
await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
const unmanagedDatasetTitle = await unamanagedDatasetButton.getVisibleText();
const secondEntryTitle = await menuEntries[1].getVisibleText();
expect(unmanagedDatasetTitle).to.be('Uncategorized');
expect(unmanagedDatasetTitle).to.be(secondEntryTitle);
});
it('should display a list of installed integrations', async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations.length).to.be(3);
expect(integrations).to.eql(initialPackagesTexts);
});
it('should sort the integrations list by the clicked sorting option', async () => {
// Test ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql(initialPackagesTexts);
});
// Test descending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('desc');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql(initialPackagesTexts.slice().reverse());
});
// Test back ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql(initialPackagesTexts);
});
});
it('should filter the integrations list by the typed integration name', async () => {
await PageObjects.discoverLogExplorer.typeSearchFieldWith('system');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.system]);
});
await PageObjects.discoverLogExplorer.typeSearchFieldWith('a');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.apache, initialPackageMap.aws]);
});
});
it('should display an empty prompt when the search does not match any result', async () => {
await PageObjects.discoverLogExplorer.typeSearchFieldWith('no result search text');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations.length).to.be(0);
});
await PageObjects.discoverLogExplorer.assertNoIntegrationsPromptExists();
});
it('should load more integrations by scrolling to the end of the list', async () => {
// Install more integrations and reload the page
const cleanupAdditionalSetup =
await PageObjects.discoverLogExplorer.setupAdditionalIntegrations();
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
// Initially fetched integrations
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(nodes.length).to.be(15);
await nodes.at(-1)?.scrollIntoViewIfNecessary();
});
// Load more integrations
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(nodes.length).to.be(20);
await nodes.at(-1)?.scrollIntoViewIfNecessary();
});
// No other integrations to load after scrolling to last integration
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(nodes.length).to.be(20);
});
cleanupAdditionalSetup();
});
});
describe('when clicking on integration and moving into the second navigation level', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
beforeEach(async () => {
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
});
it('should display a list of available datasets', async () => {
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
await nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
});
it('should sort the datasets list by the clicked sorting option', async () => {
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
await nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
});
// Test ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
// Test descending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('desc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('error');
expect(await menuEntries[1].getVisibleText()).to.be('access');
});
// Test back ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
});
it('should filter the datasets list by the typed dataset name', async () => {
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
await nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
});
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
await PageObjects.discoverLogExplorer.typeSearchFieldWith('err');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(menuEntries.length).to.be(1);
expect(await menuEntries[0].getVisibleText()).to.be('error');
});
});
it('should update the current selection with the clicked dataset', async () => {
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
await nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
});
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('access');
menuEntries[0].click();
});
await retry.try(async () => {
const selectorButton = await PageObjects.discoverLogExplorer.getDatasetSelectorButton();
expect(await selectorButton.getVisibleText()).to.be('[Apache HTTP Server] access');
});
});
});
describe('when navigating into Uncategorized data streams', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
beforeEach(async () => {
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
});
it('should display a list of available datasets', async () => {
const button = await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await button.click();
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await panelTitleNode.getVisibleText()).to.be('Uncategorized');
expect(await menuEntries[0].getVisibleText()).to.be(expectedUncategorized[0]);
expect(await menuEntries[1].getVisibleText()).to.be(expectedUncategorized[1]);
expect(await menuEntries[2].getVisibleText()).to.be(expectedUncategorized[2]);
});
});
it('should sort the datasets list by the clicked sorting option', async () => {
const button = await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await button.click();
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Uncategorized');
});
// Test ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be(expectedUncategorized[0]);
expect(await menuEntries[1].getVisibleText()).to.be(expectedUncategorized[1]);
expect(await menuEntries[2].getVisibleText()).to.be(expectedUncategorized[2]);
});
// Test descending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('desc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be(expectedUncategorized[2]);
expect(await menuEntries[1].getVisibleText()).to.be(expectedUncategorized[1]);
expect(await menuEntries[2].getVisibleText()).to.be(expectedUncategorized[0]);
});
// Test back ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be(expectedUncategorized[0]);
expect(await menuEntries[1].getVisibleText()).to.be(expectedUncategorized[1]);
expect(await menuEntries[2].getVisibleText()).to.be(expectedUncategorized[2]);
});
});
it('should filter the datasets list by the typed dataset name', async () => {
const button = await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await button.click();
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Uncategorized');
});
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be(expectedUncategorized[0]);
expect(await menuEntries[1].getVisibleText()).to.be(expectedUncategorized[1]);
expect(await menuEntries[2].getVisibleText()).to.be(expectedUncategorized[2]);
});
await PageObjects.discoverLogExplorer.typeSearchFieldWith('retail');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(menuEntries.length).to.be(1);
expect(await menuEntries[0].getVisibleText()).to.be('logs-retail-*');
});
});
it('should update the current selection with the clicked dataset', async () => {
const button = await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await button.click();
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Uncategorized');
});
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('logs-gaming-*');
menuEntries[0].click();
});
await retry.try(async () => {
const selectorButton = await PageObjects.discoverLogExplorer.getDatasetSelectorButton();
expect(await selectorButton.getVisibleText()).to.be('logs-gaming-*');
});
});
});
describe('when open/close the selector', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
beforeEach(async () => {
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
});
it('should restore the latest navigation panel', async () => {
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
await nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
await PageObjects.discoverLogExplorer.closeDatasetSelector();
await PageObjects.discoverLogExplorer.openDatasetSelector();
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
});
it('should restore the latest search results', async () => {
await PageObjects.discoverLogExplorer.typeSearchFieldWith('system');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.system]);
});
await PageObjects.discoverLogExplorer.closeDatasetSelector();
await PageObjects.discoverLogExplorer.openDatasetSelector();
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.system]);
});
});
});
describe('when switching between integration panels', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
it('should remember the latest search and restore its results for each integration', async () => {
await PageObjects.discoverLogExplorer.openDatasetSelector();
await PageObjects.discoverLogExplorer.clearSearchField();
await PageObjects.discoverLogExplorer.typeSearchFieldWith('apache');
await retry.try(async () => {
const { nodes, integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.apache]);
nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
await PageObjects.discoverLogExplorer.typeSearchFieldWith('err');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(menuEntries.length).to.be(1);
expect(await menuEntries[0].getVisibleText()).to.be('error');
});
// Navigate back to integrations
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
panelTitleNode.click();
await retry.try(async () => {
const { nodes, integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.apache]);
const searchValue = await PageObjects.discoverLogExplorer.getSearchFieldValue();
expect(searchValue).to.eql('apache');
nodes[0].click();
});
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
const searchValue = await PageObjects.discoverLogExplorer.getSearchFieldValue();
expect(searchValue).to.eql('err');
expect(menuEntries.length).to.be(1);
expect(await menuEntries[0].getVisibleText()).to.be('error');
});
});
});
});
});
}

View file

@ -9,7 +9,9 @@ import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ loadTestFile }: FtrProviderContext) {
describe('Discover Log-Explorer profile', function () {
loadTestFile(require.resolve('./columns_selection'));
loadTestFile(require.resolve('./customization'));
loadTestFile(require.resolve('./dataset_selection_state'));
loadTestFile(require.resolve('./dataset_selector'));
});
}

View file

@ -0,0 +1,419 @@
{
"type": "data_stream",
"value": {
"data_stream": "logs-gaming-activity",
"template": {
"_meta": {
"description": "Template for my time series data",
"my-custom-meta-field": "More arbitrary metadata"
},
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"index_patterns": [
"logs-gaming-activity"
],
"name": "logs-gaming-activity",
"priority": 500,
"template": {
"mappings": {
"properties": {
"@timestamp": {
"format": "date_optional_time||epoch_millis",
"type": "date"
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
}
}
},
"message": {
"type": "wildcard"
}
}
}
}
}
}
}
{
"type": "data_stream",
"value": {
"data_stream": "logs-gaming-events",
"template": {
"_meta": {
"description": "Template for my time series data",
"my-custom-meta-field": "More arbitrary metadata"
},
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"index_patterns": [
"logs-gaming-events"
],
"name": "logs-gaming-events",
"priority": 500,
"template": {
"mappings": {
"properties": {
"@timestamp": {
"format": "date_optional_time||epoch_millis",
"type": "date"
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
}
}
},
"message": {
"type": "wildcard"
}
}
}
}
}
}
}
{
"type": "data_stream",
"value": {
"data_stream": "logs-gaming-scores",
"template": {
"_meta": {
"description": "Template for my time series data",
"my-custom-meta-field": "More arbitrary metadata"
},
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"index_patterns": [
"logs-gaming-scores"
],
"name": "logs-gaming-scores",
"priority": 500,
"template": {
"mappings": {
"properties": {
"@timestamp": {
"format": "date_optional_time||epoch_millis",
"type": "date"
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
}
}
},
"message": {
"type": "wildcard"
}
}
}
}
}
}
}
{
"type": "data_stream",
"value": {
"data_stream": "logs-manufacturing-downtime",
"template": {
"_meta": {
"description": "Template for my time series data",
"my-custom-meta-field": "More arbitrary metadata"
},
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"index_patterns": [
"logs-manufacturing-downtime"
],
"name": "logs-manufacturing-downtime",
"priority": 500,
"template": {
"mappings": {
"properties": {
"@timestamp": {
"format": "date_optional_time||epoch_millis",
"type": "date"
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
}
}
},
"message": {
"type": "wildcard"
}
}
}
}
}
}
}
{
"type": "data_stream",
"value": {
"data_stream": "logs-manufacturing-output",
"template": {
"_meta": {
"description": "Template for my time series data",
"my-custom-meta-field": "More arbitrary metadata"
},
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"index_patterns": [
"logs-manufacturing-output"
],
"name": "logs-manufacturing-output",
"priority": 500,
"template": {
"mappings": {
"properties": {
"@timestamp": {
"format": "date_optional_time||epoch_millis",
"type": "date"
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
}
}
},
"message": {
"type": "wildcard"
}
}
}
}
}
}
}
{
"type": "data_stream",
"value": {
"data_stream": "logs-manufacturing-quality",
"template": {
"_meta": {
"description": "Template for my time series data",
"my-custom-meta-field": "More arbitrary metadata"
},
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"index_patterns": [
"logs-manufacturing-quality"
],
"name": "logs-manufacturing-quality",
"priority": 500,
"template": {
"mappings": {
"properties": {
"@timestamp": {
"format": "date_optional_time||epoch_millis",
"type": "date"
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
}
}
},
"message": {
"type": "wildcard"
}
}
}
}
}
}
}
{
"type": "data_stream",
"value": {
"data_stream": "logs-retail-customers",
"template": {
"_meta": {
"description": "Template for my time series data",
"my-custom-meta-field": "More arbitrary metadata"
},
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"index_patterns": [
"logs-retail-customers"
],
"name": "logs-retail-customers",
"priority": 500,
"template": {
"mappings": {
"properties": {
"@timestamp": {
"format": "date_optional_time||epoch_millis",
"type": "date"
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
}
}
},
"message": {
"type": "wildcard"
}
}
}
}
}
}
}
{
"type": "data_stream",
"value": {
"data_stream": "logs-retail-inventory",
"template": {
"_meta": {
"description": "Template for my time series data",
"my-custom-meta-field": "More arbitrary metadata"
},
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"index_patterns": [
"logs-retail-inventory"
],
"name": "logs-retail-inventory",
"priority": 500,
"template": {
"mappings": {
"properties": {
"@timestamp": {
"format": "date_optional_time||epoch_millis",
"type": "date"
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
}
}
},
"message": {
"type": "wildcard"
}
}
}
}
}
}
}
{
"type": "data_stream",
"value": {
"data_stream": "logs-retail-promotions",
"template": {
"_meta": {
"description": "Template for my time series data",
"my-custom-meta-field": "More arbitrary metadata"
},
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"index_patterns": [
"logs-retail-promotions"
],
"name": "logs-retail-promotions",
"priority": 500,
"template": {
"mappings": {
"properties": {
"@timestamp": {
"format": "date_optional_time||epoch_millis",
"type": "date"
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
}
}
},
"message": {
"type": "wildcard"
}
}
}
}
}
}
}
{
"type": "data_stream",
"value": {
"data_stream": "logs-retail-sales",
"template": {
"_meta": {
"description": "Template for my time series data",
"my-custom-meta-field": "More arbitrary metadata"
},
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"index_patterns": [
"logs-retail-sales"
],
"name": "logs-retail-sales",
"priority": 500,
"template": {
"mappings": {
"properties": {
"@timestamp": {
"format": "date_optional_time||epoch_millis",
"type": "date"
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
}
}
},
"message": {
"type": "wildcard"
}
}
}
}
}
}
}

View file

@ -7,13 +7,186 @@
import expect from '@kbn/expect';
import { FtrProviderContext } from '../ftr_provider_context';
export interface IntegrationPackage {
name: string;
version: string;
}
const packages: IntegrationPackage[] = [
{
name: 'apache',
version: '1.14.0',
},
{
name: 'aws',
version: '1.51.0',
},
{
name: 'system',
version: '1.38.1',
},
{
name: '1password',
version: '1.18.0',
},
{
name: 'activemq',
version: '0.13.0',
},
{
name: 'akamai',
version: '2.14.0',
},
{
name: 'apache_tomcat',
version: '0.12.1',
},
{
name: 'apm',
version: '8.4.2',
},
{
name: 'atlassian_bitbucket',
version: '1.14.0',
},
{
name: 'atlassian_confluence',
version: '1.15.0',
},
{
name: 'atlassian_jira',
version: '1.15.0',
},
{
name: 'auditd',
version: '3.12.0',
},
{
name: 'auditd_manager',
version: '1.12.0',
},
{
name: 'auth0',
version: '1.10.0',
},
{
name: 'aws_logs',
version: '0.5.0',
},
{
name: 'azure',
version: '1.5.28',
},
{
name: 'azure_app_service',
version: '0.0.1',
},
{
name: 'azure_blob_storage',
version: '0.5.0',
},
{
name: 'azure_frontdoor',
version: '1.1.0',
},
{
name: 'azure_functions',
version: '0.0.1',
},
];
const initialPackages = packages.slice(0, 3);
const additionalPackages = packages.slice(3);
export function DiscoverLogExplorerPageObject({ getService }: FtrProviderContext) {
const log = getService('log');
const supertest = getService('supertest');
const testSubjects = getService('testSubjects');
const toasts = getService('toasts');
return {
async getDatasetSelectorButton() {
return testSubjects.find('dataset-selector-popover-button');
uninstallPackage: ({ name, version }: IntegrationPackage) => {
return supertest.delete(`/api/fleet/epm/packages/${name}/${version}`).set('kbn-xsrf', 'xxxx');
},
installPackage: ({ name, version }: IntegrationPackage) => {
return supertest
.post(`/api/fleet/epm/packages/${name}/${version}`)
.set('kbn-xsrf', 'xxxx')
.send({ force: true });
},
getInstalledPackages: () => {
return supertest
.get(`/api/fleet/epm/packages/installed?dataStreamType=logs&perPage=1000`)
.set('kbn-xsrf', 'xxxx');
},
async removeInstalledPackages(): Promise<IntegrationPackage[]> {
const response = await this.getInstalledPackages();
// Uninstall installed integration
await Promise.all(
response.body.items.map((pkg: IntegrationPackage) => this.uninstallPackage(pkg))
);
return response.body.items;
},
async setupInitialIntegrations() {
log.info(`===== Setup initial integration packages. =====`);
log.info(`===== Uninstall initial integration packages. =====`);
const uninstalled = await this.removeInstalledPackages();
log.info(`===== Install ${initialPackages.length} mock integration packages. =====`);
await Promise.all(initialPackages.map((pkg: IntegrationPackage) => this.installPackage(pkg)));
return async () => {
log.info(`===== Uninstall ${initialPackages.length} mock integration packages. =====`);
await Promise.all(
initialPackages.map((pkg: IntegrationPackage) => this.uninstallPackage(pkg))
);
log.info(`===== Restore pre-existing integration packages. =====`);
await Promise.all(uninstalled.map((pkg: IntegrationPackage) => this.installPackage(pkg)));
};
},
async setupAdditionalIntegrations() {
log.info(`===== Setup additional integration packages. =====`);
log.info(`===== Install ${additionalPackages.length} mock integration packages. =====`);
await Promise.all(
additionalPackages.map((pkg: IntegrationPackage) => this.installPackage(pkg))
);
return async () => {
log.info(`===== Uninstall ${additionalPackages.length} mock integration packages. =====`);
await Promise.all(
additionalPackages.map((pkg: IntegrationPackage) => this.uninstallPackage(pkg))
);
};
},
getDatasetSelector() {
return testSubjects.find('datasetSelectorPopover');
},
getDatasetSelectorButton() {
return testSubjects.find('datasetSelectorPopoverButton');
},
getDatasetSelectorContent() {
return testSubjects.find('datasetSelectorContent');
},
getDatasetSelectorSearchControls() {
return testSubjects.find('datasetSelectorSearchControls');
},
getDatasetSelectorContextMenu() {
return testSubjects.find('datasetSelectorContextMenu');
},
getDatasetSelectorContextMenuPanelTitle() {
return testSubjects.find('contextMenuPanelTitleButton');
},
async getDatasetSelectorButtonText() {
@ -21,11 +194,115 @@ export function DiscoverLogExplorerPageObject({ getService }: FtrProviderContext
return button.getVisibleText();
},
async getCurrentPanelEntries() {
const contextMenu = await this.getDatasetSelectorContextMenu();
return contextMenu.findAllByClassName('euiContextMenuItem', 2000);
},
getAllLogDatasetsButton() {
return testSubjects.find('allLogDatasets');
},
getUnmanagedDatasetsButton() {
return testSubjects.find('unmanagedDatasets');
},
async getIntegrations() {
const content = await this.getDatasetSelectorContent();
const nodes = await content.findAllByCssSelector('[data-test-subj*="integration-"]', 2000);
const integrations = await Promise.all(nodes.map((node) => node.getVisibleText()));
return {
nodes,
integrations,
};
},
async openDatasetSelector() {
const button = await this.getDatasetSelectorButton();
return button.click();
},
async closeDatasetSelector() {
const button = await this.getDatasetSelectorButton();
const isOpen = await testSubjects.exists('datasetSelectorContent');
if (isOpen) return button.click();
},
async clickSortButtonBy(direction: 'asc' | 'desc') {
const titleMap = {
asc: 'Ascending',
desc: 'Descending',
};
const searchControlsContainer = await this.getDatasetSelectorSearchControls();
const sortingButton = await searchControlsContainer.findByCssSelector(
`[title=${titleMap[direction]}]`
);
return sortingButton.click();
},
async getSearchFieldValue() {
const searchControlsContainer = await this.getDatasetSelectorSearchControls();
const searchField = await searchControlsContainer.findByCssSelector('input[type=search]');
return searchField.getAttribute('value');
},
async typeSearchFieldWith(name: string) {
const searchControlsContainer = await this.getDatasetSelectorSearchControls();
const searchField = await searchControlsContainer.findByCssSelector('input[type=search]');
await searchField.clearValueWithKeyboard();
return searchField.type(name);
},
async clearSearchField() {
const searchControlsContainer = await this.getDatasetSelectorSearchControls();
const searchField = await searchControlsContainer.findByCssSelector('input[type=search]');
return searchField.clearValueWithKeyboard();
},
async assertRestoreFailureToastExist() {
const successToast = await toasts.getToastElement(1);
expect(await successToast.getVisibleText()).to.contain(
"We couldn't restore your datasets selection"
);
},
assertLoadingSkeletonExists() {
return testSubjects.existOrFail('datasetSelectorSkeleton');
},
async assertNoIntegrationsPromptExists() {
const integrationStatus = await testSubjects.find('integrationStatusItem');
const promptTitle = await integrationStatus.findByTagName('h2');
expect(await promptTitle.getVisibleText()).to.be('No integrations found');
},
async assertNoIntegrationsErrorExists() {
const integrationStatus = await testSubjects.find('integrationsErrorPrompt');
const promptTitle = await integrationStatus.findByTagName('h2');
expect(await promptTitle.getVisibleText()).to.be('No integrations found');
},
async assertNoDataStreamsPromptExists() {
const integrationStatus = await testSubjects.find('emptyDatasetPrompt');
const promptTitle = await integrationStatus.findByTagName('h2');
expect(await promptTitle.getVisibleText()).to.be('No data streams found');
},
async assertNoDataStreamsErrorExists() {
const integrationStatus = await testSubjects.find('datasetErrorPrompt');
const promptTitle = await integrationStatus.findByTagName('h2');
expect(await promptTitle.getVisibleText()).to.be('No data streams found');
},
};
}

View file

@ -0,0 +1,57 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../ftr_provider_context';
const defaultLogColumns = ['@timestamp', 'message'];
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'discover']);
describe('Columns selection initialization and update', () => {
before(async () => {
await esArchiver.load(
'x-pack/test/functional/es_archives/discover_log_explorer/data_streams'
);
});
after(async () => {
await esArchiver.unload(
'x-pack/test/functional/es_archives/discover_log_explorer/data_streams'
);
});
describe('when the log explorer profile loads', () => {
it("should initialize the table columns to logs' default selection", async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
await PageObjects.discover.expandTimeRangeAsSuggestedInNoResultsMessage();
await retry.try(async () => {
expect(await PageObjects.discover.getColumnHeaders()).to.eql(defaultLogColumns);
});
});
it('should restore the table columns from the URL state if exists', async () => {
await PageObjects.common.navigateToApp('discover', {
hash: '/p/log-explorer?_a=(columns:!(message,data_stream.namespace))',
});
await PageObjects.discover.expandTimeRangeAsSuggestedInNoResultsMessage();
await retry.try(async () => {
expect(await PageObjects.discover.getColumnHeaders()).to.eql([
...defaultLogColumns,
'data_stream.namespace',
]);
});
});
});
});
}

View file

@ -24,11 +24,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('DatasetSelector should replace the DataViewPicker', async () => {
// Assert does not render on discover app
await PageObjects.common.navigateToApp('discover');
await testSubjects.missingOrFail('dataset-selector-popover');
await testSubjects.missingOrFail('datasetSelectorPopover');
// Assert it renders on log-explorer profile
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
await testSubjects.existOrFail('dataset-selector-popover');
await testSubjects.existOrFail('datasetSelectorPopover');
});
it('the TopNav bar should hide New, Open and Save options', async () => {
@ -50,6 +50,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await testSubjects.existOrFail('openInspectorButton');
await testSubjects.missingOrFail('discoverSaveButton');
});
it('should render a filter controls section as part of the unified search bar', async () => {
// Assert does not render on discover app
await PageObjects.common.navigateToApp('discover');
await testSubjects.missingOrFail('datasetFiltersCustomization');
// Assert it renders on log-explorer profile
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
await testSubjects.existOrFail('datasetFiltersCustomization', { allowHidden: true });
});
});
});
}

View file

@ -0,0 +1,664 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../ftr_provider_context';
const initialPackageMap = {
apache: 'Apache HTTP Server',
aws: 'AWS',
system: 'System',
};
const initialPackagesTexts = Object.values(initialPackageMap);
const expectedUncategorized = ['logs-gaming-*', 'logs-manufacturing-*', 'logs-retail-*'];
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const browser = getService('browser');
const esArchiver = getService('esArchiver');
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'discoverLogExplorer']);
describe('Dataset Selector', () => {
before(async () => {
await PageObjects.discoverLogExplorer.removeInstalledPackages();
});
describe('without installed integrations or uncategorized data streams', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
beforeEach(async () => {
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
});
describe('when open on the first navigation level', () => {
it('should always display the "All log datasets" entry as the first item', async () => {
const allLogDatasetButton =
await PageObjects.discoverLogExplorer.getAllLogDatasetsButton();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
const allLogDatasetTitle = await allLogDatasetButton.getVisibleText();
const firstEntryTitle = await menuEntries[0].getVisibleText();
expect(allLogDatasetTitle).to.be('All log datasets');
expect(allLogDatasetTitle).to.be(firstEntryTitle);
});
it('should always display the unmanaged datasets entry as the second item', async () => {
const unamanagedDatasetButton =
await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
const unmanagedDatasetTitle = await unamanagedDatasetButton.getVisibleText();
const secondEntryTitle = await menuEntries[1].getVisibleText();
expect(unmanagedDatasetTitle).to.be('Uncategorized');
expect(unmanagedDatasetTitle).to.be(secondEntryTitle);
});
it('should display an error prompt if could not retrieve the integrations', async function () {
// Skip the test in case network condition utils are not available
try {
await retry.try(async () => {
await PageObjects.discoverLogExplorer.assertNoIntegrationsPromptExists();
});
await PageObjects.common.sleep(5000);
await browser.setNetworkConditions('OFFLINE');
await PageObjects.discoverLogExplorer.typeSearchFieldWith('a');
await retry.try(async () => {
await PageObjects.discoverLogExplorer.assertNoIntegrationsErrorExists();
});
await browser.restoreNetworkConditions();
} catch (error) {
this.skip();
}
});
it('should display an empty prompt for no integrations', async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations.length).to.be(0);
await PageObjects.discoverLogExplorer.assertNoIntegrationsPromptExists();
});
});
describe('when navigating into Uncategorized data streams', () => {
it('should display a loading skeleton while loading', async function () {
// Skip the test in case network condition utils are not available
try {
await browser.setNetworkConditions('SLOW_3G'); // Almost stuck network conditions
const unamanagedDatasetButton =
await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await unamanagedDatasetButton.click();
await PageObjects.discoverLogExplorer.assertLoadingSkeletonExists();
await browser.restoreNetworkConditions();
} catch (error) {
this.skip();
}
});
it('should display an error prompt if could not retrieve the data streams', async function () {
// Skip the test in case network condition utils are not available
try {
const unamanagedDatasetButton =
await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await unamanagedDatasetButton.click();
await retry.try(async () => {
await PageObjects.discoverLogExplorer.assertNoDataStreamsPromptExists();
});
await browser.setNetworkConditions('OFFLINE');
await PageObjects.discoverLogExplorer.typeSearchFieldWith('a');
await retry.try(async () => {
await PageObjects.discoverLogExplorer.assertNoDataStreamsErrorExists();
});
await browser.restoreNetworkConditions();
} catch (error) {
this.skip();
}
});
it('should display an empty prompt for no data streams', async () => {
const unamanagedDatasetButton =
await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await unamanagedDatasetButton.click();
const unamanagedDatasetEntries =
await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(unamanagedDatasetEntries.length).to.be(0);
await PageObjects.discoverLogExplorer.assertNoDataStreamsPromptExists();
});
});
});
describe('with installed integrations and uncategorized data streams', () => {
let cleanupIntegrationsSetup: () => Promise<void>;
before(async () => {
await esArchiver.load(
'x-pack/test/functional/es_archives/discover_log_explorer/data_streams'
);
cleanupIntegrationsSetup = await PageObjects.discoverLogExplorer.setupInitialIntegrations();
});
after(async () => {
await esArchiver.unload(
'x-pack/test/functional/es_archives/discover_log_explorer/data_streams'
);
await cleanupIntegrationsSetup();
});
describe('when open on the first navigation level', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
beforeEach(async () => {
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
});
it('should always display the "All log datasets" entry as the first item', async () => {
const allLogDatasetButton =
await PageObjects.discoverLogExplorer.getAllLogDatasetsButton();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
const allLogDatasetTitle = await allLogDatasetButton.getVisibleText();
const firstEntryTitle = await menuEntries[0].getVisibleText();
expect(allLogDatasetTitle).to.be('All log datasets');
expect(allLogDatasetTitle).to.be(firstEntryTitle);
});
it('should always display the unmanaged datasets entry as the second item', async () => {
const unamanagedDatasetButton =
await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
const unmanagedDatasetTitle = await unamanagedDatasetButton.getVisibleText();
const secondEntryTitle = await menuEntries[1].getVisibleText();
expect(unmanagedDatasetTitle).to.be('Uncategorized');
expect(unmanagedDatasetTitle).to.be(secondEntryTitle);
});
it('should display a list of installed integrations', async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations.length).to.be(3);
expect(integrations).to.eql(initialPackagesTexts);
});
it('should sort the integrations list by the clicked sorting option', async () => {
// Test ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql(initialPackagesTexts);
});
// Test descending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('desc');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql(initialPackagesTexts.slice().reverse());
});
// Test back ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql(initialPackagesTexts);
});
});
it('should filter the integrations list by the typed integration name', async () => {
await PageObjects.discoverLogExplorer.typeSearchFieldWith('system');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.system]);
});
await PageObjects.discoverLogExplorer.typeSearchFieldWith('a');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.apache, initialPackageMap.aws]);
});
});
it('should display an empty prompt when the search does not match any result', async () => {
await PageObjects.discoverLogExplorer.typeSearchFieldWith('no result search text');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations.length).to.be(0);
});
await PageObjects.discoverLogExplorer.assertNoIntegrationsPromptExists();
});
it('should load more integrations by scrolling to the end of the list', async () => {
// Install more integrations and reload the page
const cleanupAdditionalSetup =
await PageObjects.discoverLogExplorer.setupAdditionalIntegrations();
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
// Initially fetched integrations
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(nodes.length).to.be(15);
await nodes.at(-1)?.scrollIntoViewIfNecessary();
});
// Load more integrations
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(nodes.length).to.be(20);
await nodes.at(-1)?.scrollIntoViewIfNecessary();
});
// No other integrations to load after scrolling to last integration
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(nodes.length).to.be(20);
});
cleanupAdditionalSetup();
});
});
describe('when clicking on integration and moving into the second navigation level', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
beforeEach(async () => {
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
});
it('should display a list of available datasets', async () => {
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
await nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
});
it('should sort the datasets list by the clicked sorting option', async () => {
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
await nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
});
// Test ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
// Test descending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('desc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('error');
expect(await menuEntries[1].getVisibleText()).to.be('access');
});
// Test back ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
});
it('should filter the datasets list by the typed dataset name', async () => {
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
await nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
});
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
await PageObjects.discoverLogExplorer.typeSearchFieldWith('err');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(menuEntries.length).to.be(1);
expect(await menuEntries[0].getVisibleText()).to.be('error');
});
});
it('should update the current selection with the clicked dataset', async () => {
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
await nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
});
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('access');
menuEntries[0].click();
});
await retry.try(async () => {
const selectorButton = await PageObjects.discoverLogExplorer.getDatasetSelectorButton();
expect(await selectorButton.getVisibleText()).to.be('[Apache HTTP Server] access');
});
});
});
describe('when navigating into Uncategorized data streams', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
beforeEach(async () => {
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
});
it('should display a list of available datasets', async () => {
const button = await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await button.click();
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await panelTitleNode.getVisibleText()).to.be('Uncategorized');
expect(await menuEntries[0].getVisibleText()).to.be(expectedUncategorized[0]);
expect(await menuEntries[1].getVisibleText()).to.be(expectedUncategorized[1]);
expect(await menuEntries[2].getVisibleText()).to.be(expectedUncategorized[2]);
});
});
it('should sort the datasets list by the clicked sorting option', async () => {
const button = await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await button.click();
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Uncategorized');
});
// Test ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be(expectedUncategorized[0]);
expect(await menuEntries[1].getVisibleText()).to.be(expectedUncategorized[1]);
expect(await menuEntries[2].getVisibleText()).to.be(expectedUncategorized[2]);
});
// Test descending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('desc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be(expectedUncategorized[2]);
expect(await menuEntries[1].getVisibleText()).to.be(expectedUncategorized[1]);
expect(await menuEntries[2].getVisibleText()).to.be(expectedUncategorized[0]);
});
// Test back ascending order
await PageObjects.discoverLogExplorer.clickSortButtonBy('asc');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be(expectedUncategorized[0]);
expect(await menuEntries[1].getVisibleText()).to.be(expectedUncategorized[1]);
expect(await menuEntries[2].getVisibleText()).to.be(expectedUncategorized[2]);
});
});
it('should filter the datasets list by the typed dataset name', async () => {
const button = await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await button.click();
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Uncategorized');
});
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be(expectedUncategorized[0]);
expect(await menuEntries[1].getVisibleText()).to.be(expectedUncategorized[1]);
expect(await menuEntries[2].getVisibleText()).to.be(expectedUncategorized[2]);
});
await PageObjects.discoverLogExplorer.typeSearchFieldWith('retail');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(menuEntries.length).to.be(1);
expect(await menuEntries[0].getVisibleText()).to.be('logs-retail-*');
});
});
it('should update the current selection with the clicked dataset', async () => {
const button = await PageObjects.discoverLogExplorer.getUnmanagedDatasetsButton();
await button.click();
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
expect(await panelTitleNode.getVisibleText()).to.be('Uncategorized');
});
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await menuEntries[0].getVisibleText()).to.be('logs-gaming-*');
menuEntries[0].click();
});
await retry.try(async () => {
const selectorButton = await PageObjects.discoverLogExplorer.getDatasetSelectorButton();
expect(await selectorButton.getVisibleText()).to.be('logs-gaming-*');
});
});
});
describe('when open/close the selector', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
beforeEach(async () => {
await browser.refresh();
await PageObjects.discoverLogExplorer.openDatasetSelector();
});
it('should restore the latest navigation panel', async () => {
await retry.try(async () => {
const { nodes } = await PageObjects.discoverLogExplorer.getIntegrations();
await nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
await PageObjects.discoverLogExplorer.closeDatasetSelector();
await PageObjects.discoverLogExplorer.openDatasetSelector();
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
});
it('should restore the latest search results', async () => {
await PageObjects.discoverLogExplorer.typeSearchFieldWith('system');
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.system]);
});
await PageObjects.discoverLogExplorer.closeDatasetSelector();
await PageObjects.discoverLogExplorer.openDatasetSelector();
await retry.try(async () => {
const { integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.system]);
});
});
});
describe('when switching between integration panels', () => {
before(async () => {
await PageObjects.common.navigateToApp('discover', { hash: '/p/log-explorer' });
});
it('should remember the latest search and restore its results for each integration', async () => {
await PageObjects.discoverLogExplorer.openDatasetSelector();
await PageObjects.discoverLogExplorer.clearSearchField();
await PageObjects.discoverLogExplorer.typeSearchFieldWith('apache');
await retry.try(async () => {
const { nodes, integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.apache]);
nodes[0].click();
});
await retry.try(async () => {
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(await panelTitleNode.getVisibleText()).to.be('Apache HTTP Server');
expect(await menuEntries[0].getVisibleText()).to.be('access');
expect(await menuEntries[1].getVisibleText()).to.be('error');
});
await PageObjects.discoverLogExplorer.typeSearchFieldWith('err');
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
expect(menuEntries.length).to.be(1);
expect(await menuEntries[0].getVisibleText()).to.be('error');
});
// Navigate back to integrations
const panelTitleNode =
await PageObjects.discoverLogExplorer.getDatasetSelectorContextMenuPanelTitle();
panelTitleNode.click();
await retry.try(async () => {
const { nodes, integrations } = await PageObjects.discoverLogExplorer.getIntegrations();
expect(integrations).to.eql([initialPackageMap.apache]);
const searchValue = await PageObjects.discoverLogExplorer.getSearchFieldValue();
expect(searchValue).to.eql('apache');
nodes[0].click();
});
await retry.try(async () => {
const menuEntries = await PageObjects.discoverLogExplorer.getCurrentPanelEntries();
const searchValue = await PageObjects.discoverLogExplorer.getSearchFieldValue();
expect(searchValue).to.eql('err');
expect(menuEntries.length).to.be(1);
expect(await menuEntries[0].getVisibleText()).to.be('error');
});
});
});
});
});
}

View file

@ -9,7 +9,9 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
export default function (loadTestFile: FtrProviderContext['loadTestFile']) {
describe('Discover Log-Explorer profile', function () {
loadTestFile(require.resolve('./columns_selection'));
loadTestFile(require.resolve('./customization'));
loadTestFile(require.resolve('./dataset_selection_state'));
loadTestFile(require.resolve('./dataset_selector'));
});
}