mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
* bulk actions test cases outline * helpers to filter alerts per rule type (reason) * add proper apm indices/privileges to observability functional tests * cleanup * add apm archive data * add correct apm archive data, add helper to select checkbox per solution & cleanup * enable more tests * cleanup * tests for bulk container * more tests for bulk container * fix eslint issues * fix failing unit tests (use ~= for multiple space separated values) * remove unused value * fix typescript error with container.querySelector * remove apm test archive data * use getByTestId in the tests * fix security cypress tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: mgiota <giota85@gmail.com>
This commit is contained in:
parent
acdd56704a
commit
1be554f2e5
8 changed files with 282 additions and 5 deletions
|
@ -12,7 +12,7 @@ export const ALERTS = '[data-test-subj="events-viewer-panel"] [data-test-subj="e
|
|||
export const ALERTS_COUNT =
|
||||
'[data-test-subj="events-viewer-panel"] [data-test-subj="server-side-event-count"]';
|
||||
|
||||
export const ALERT_CHECKBOX = '[data-test-subj="select-event"].euiCheckbox__input';
|
||||
export const ALERT_CHECKBOX = '[data-test-subj~="select-event"].euiCheckbox__input';
|
||||
|
||||
export const ALERT_GRID_CELL = '[data-test-subj="dataGridRowCell"]';
|
||||
|
||||
|
|
|
@ -45,8 +45,8 @@ describe('checkbox control column', () => {
|
|||
const { getByTestId } = render(
|
||||
<RowCheckBox {...defaultProps} onRowSelected={onRowSelected} />
|
||||
);
|
||||
|
||||
fireEvent.click(getByTestId('select-event'));
|
||||
const checkbox = getByTestId(/^select-event/);
|
||||
fireEvent.click(checkbox);
|
||||
|
||||
expect(onRowSelected).toHaveBeenCalled();
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { EuiCheckbox, EuiLoadingSpinner } from '@elastic/eui';
|
||||
import React, { useCallback } from 'react';
|
||||
import { ALERT_RULE_PRODUCER } from '@kbn/rule-data-utils';
|
||||
import { ActionProps, HeaderActionProps } from '../../../../../common';
|
||||
import * as i18n from './translations';
|
||||
|
||||
|
@ -18,7 +19,10 @@ export const RowCheckBox = ({
|
|||
columnValues,
|
||||
disabled,
|
||||
loadingEventIds,
|
||||
data,
|
||||
}: ActionProps) => {
|
||||
const ruleProducers = data.find((d) => d.field === ALERT_RULE_PRODUCER)?.value ?? [];
|
||||
const ruleProducer = ruleProducers[0];
|
||||
const handleSelectEvent = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (!disabled) {
|
||||
|
@ -35,7 +39,7 @@ export const RowCheckBox = ({
|
|||
<EuiLoadingSpinner size="m" data-test-subj="event-loader" />
|
||||
) : (
|
||||
<EuiCheckbox
|
||||
data-test-subj="select-event"
|
||||
data-test-subj={`select-event select-event-rule-producer-${ruleProducer}`}
|
||||
id={eventId}
|
||||
checked={checked && !disabled}
|
||||
disabled={disabled}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
const CHECKBOX_SELECTOR = 'select-event';
|
||||
const CHECKBOX_PRODUCER_SELECTOR = 'select-event-rule-producer';
|
||||
const BULK_ACTIONS_CONTAINER = 'bulk-actions-button-container';
|
||||
const SELECTED_BULK_ACTIONS_BUTTON = 'selectedShowBulkActionsButton';
|
||||
|
||||
export function ObservabilityAlertsBulkActionsProvider({ getService }: FtrProviderContext) {
|
||||
const find = getService('find');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
const getCheckboxSelector = async () => {
|
||||
return await find.allByCssSelector(testSubjects.getCssSelector(`~${CHECKBOX_SELECTOR}`));
|
||||
};
|
||||
|
||||
const missingCheckboxSelectorOrFail = async () => {
|
||||
return await testSubjects.missingOrFail(`~${CHECKBOX_SELECTOR}`);
|
||||
};
|
||||
|
||||
const getCheckboxSelectorPerProducer = async (producer: string) => {
|
||||
return await find.allByCssSelector(
|
||||
testSubjects.getCssSelector(`~${CHECKBOX_PRODUCER_SELECTOR}-${producer}`)
|
||||
);
|
||||
};
|
||||
|
||||
const getBulkActionsContainer = async () => {
|
||||
return await testSubjects.find(BULK_ACTIONS_CONTAINER);
|
||||
};
|
||||
|
||||
const getBulkActionsContainerOrFail = async () => {
|
||||
return await testSubjects.existOrFail(BULK_ACTIONS_CONTAINER);
|
||||
};
|
||||
|
||||
const getBulkActionsButton = async () => {
|
||||
return await testSubjects.find(SELECTED_BULK_ACTIONS_BUTTON);
|
||||
};
|
||||
|
||||
return {
|
||||
getCheckboxSelector,
|
||||
getCheckboxSelectorPerProducer,
|
||||
missingCheckboxSelectorOrFail,
|
||||
getBulkActionsContainer,
|
||||
getBulkActionsContainerOrFail,
|
||||
getBulkActionsButton,
|
||||
};
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
import { ObservabilityAlertsPaginationProvider } from './pagination';
|
||||
import { ObservabilityAlertsCommonProvider } from './common';
|
||||
import { ObservabilityAlertsAddToCaseProvider } from './add_to_case';
|
||||
import { ObservabilityAlertsBulkActionsProvider } from './bulk_actions';
|
||||
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
|
@ -15,9 +16,12 @@ export function ObservabilityAlertsProvider(context: FtrProviderContext) {
|
|||
const common = ObservabilityAlertsCommonProvider(context);
|
||||
const pagination = ObservabilityAlertsPaginationProvider(context);
|
||||
const addToCase = ObservabilityAlertsAddToCaseProvider(context);
|
||||
const bulkActions = ObservabilityAlertsBulkActionsProvider(context);
|
||||
|
||||
return {
|
||||
common,
|
||||
pagination,
|
||||
addToCase,
|
||||
bulkActions,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -72,7 +72,20 @@ const defineBasicObservabilityRole = (
|
|||
...((features.infrastructure?.length ?? 0) > 0
|
||||
? [{ names: ['metricbeat-*', 'metrics-*'], privileges: ['all'] }]
|
||||
: []),
|
||||
...((features.apm?.length ?? 0) > 0 ? [{ names: ['apm-*'], privileges: ['all'] }] : []),
|
||||
...((features.apm?.length ?? 0) > 0
|
||||
? [
|
||||
{
|
||||
names: [
|
||||
'apm-*',
|
||||
'logs-apm*',
|
||||
'metrics-apm*',
|
||||
'traces-apm*',
|
||||
'observability-annotations',
|
||||
],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...((features.uptime?.length ?? 0) > 0
|
||||
? [{ names: ['heartbeat-*,synthetics-*'], privileges: ['all'] }]
|
||||
: []),
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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';
|
||||
|
||||
async function asyncForEach<T>(array: T[], callback: (item: T, index: number) => void) {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index);
|
||||
}
|
||||
}
|
||||
|
||||
export default ({ getService, getPageObjects }: FtrProviderContext) => {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const observability = getService('observability');
|
||||
|
||||
const retry = getService('retry');
|
||||
|
||||
describe('Observability alerts / Bulk actions', function () {
|
||||
this.tags('includeFirefox');
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/observability/alerts');
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs');
|
||||
await esArchiver.load(
|
||||
'x-pack/test/apm_api_integration/common/fixtures/es_archiver/apm_8.0.0'
|
||||
);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs');
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/observability/alerts');
|
||||
await esArchiver.unload(
|
||||
'x-pack/test/apm_api_integration/common/fixtures/es_archiver/apm_8.0.0'
|
||||
);
|
||||
});
|
||||
|
||||
describe('When user has all priviledges for logs app', () => {
|
||||
before(async () => {
|
||||
await observability.users.setTestUserRole(
|
||||
observability.users.defineBasicObservabilityRole({
|
||||
logs: ['all'],
|
||||
})
|
||||
);
|
||||
await observability.alerts.common.navigateToTimeWithData();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await observability.users.restoreDefaultTestUserRole();
|
||||
});
|
||||
|
||||
it('logs checkboxes are enabled', async () => {
|
||||
const logsCheckboxes =
|
||||
await observability.alerts.bulkActions.getCheckboxSelectorPerProducer('logs');
|
||||
|
||||
await asyncForEach(logsCheckboxes, async (checkbox, index) => {
|
||||
expect(await checkbox.isEnabled()).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when checkbox is clicked', async () => {
|
||||
it('shows bulk actions container', async () => {
|
||||
const logsCheckboxes =
|
||||
await observability.alerts.bulkActions.getCheckboxSelectorPerProducer('logs');
|
||||
await logsCheckboxes[0].click();
|
||||
await observability.alerts.bulkActions.getBulkActionsContainerOrFail();
|
||||
});
|
||||
|
||||
describe('when selected bulk action button is clicked', async () => {
|
||||
it('opens overflow menu with workflow status options', async () => {
|
||||
await retry.try(async () => {
|
||||
await (await observability.alerts.bulkActions.getBulkActionsButton()).click();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When user has all priviledges for apm app', () => {
|
||||
before(async () => {
|
||||
await observability.users.setTestUserRole(
|
||||
observability.users.defineBasicObservabilityRole({
|
||||
apm: ['all'],
|
||||
})
|
||||
);
|
||||
await observability.alerts.common.navigateToTimeWithData();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await observability.users.restoreDefaultTestUserRole();
|
||||
});
|
||||
|
||||
it('apm checkboxes are enabled', async () => {
|
||||
const apmCheckboxes = await observability.alerts.bulkActions.getCheckboxSelectorPerProducer(
|
||||
'apm'
|
||||
);
|
||||
|
||||
await asyncForEach(apmCheckboxes, async (checkbox, index) => {
|
||||
expect(await checkbox.isEnabled()).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when checkbox is clicked', async () => {
|
||||
it('shows bulk actions container', async () => {
|
||||
const apmCheckboxes =
|
||||
await observability.alerts.bulkActions.getCheckboxSelectorPerProducer('apm');
|
||||
await apmCheckboxes[0].click();
|
||||
await observability.alerts.bulkActions.getBulkActionsContainerOrFail();
|
||||
});
|
||||
|
||||
describe('when selected bulk action button is clicked', async () => {
|
||||
it('opens overflow menu with workflow status options', async () => {
|
||||
await retry.try(async () => {
|
||||
await (await observability.alerts.bulkActions.getBulkActionsButton()).click();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When user has read permissions for logs', () => {
|
||||
before(async () => {
|
||||
await observability.users.setTestUserRole(
|
||||
observability.users.defineBasicObservabilityRole({
|
||||
logs: ['read'],
|
||||
})
|
||||
);
|
||||
await observability.alerts.common.navigateToTimeWithData();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await observability.users.restoreDefaultTestUserRole();
|
||||
});
|
||||
|
||||
it('checkbox is not visible', async () => {
|
||||
await observability.alerts.bulkActions.missingCheckboxSelectorOrFail();
|
||||
});
|
||||
});
|
||||
|
||||
describe('When user has read permissions for apm', () => {
|
||||
before(async () => {
|
||||
await observability.users.setTestUserRole(
|
||||
observability.users.defineBasicObservabilityRole({
|
||||
apm: ['read'],
|
||||
})
|
||||
);
|
||||
await observability.alerts.common.navigateToTimeWithData();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await observability.users.restoreDefaultTestUserRole();
|
||||
});
|
||||
|
||||
it('checkbox is not displayed', async () => {
|
||||
await observability.alerts.bulkActions.missingCheckboxSelectorOrFail();
|
||||
});
|
||||
});
|
||||
|
||||
describe('When user has mixed permissions for observability apps', () => {
|
||||
before(async () => {
|
||||
await observability.users.setTestUserRole(
|
||||
observability.users.defineBasicObservabilityRole({
|
||||
logs: ['all'],
|
||||
apm: ['read'],
|
||||
observabilityCases: ['read'],
|
||||
})
|
||||
);
|
||||
await observability.alerts.common.navigateToTimeWithData();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await observability.users.restoreDefaultTestUserRole();
|
||||
});
|
||||
|
||||
it('apm checkboxes are disabled', async () => {
|
||||
const apmCheckboxes = await observability.alerts.bulkActions.getCheckboxSelectorPerProducer(
|
||||
'apm'
|
||||
);
|
||||
|
||||
await asyncForEach(apmCheckboxes, async (checkbox, index) => {
|
||||
expect(await checkbox.isEnabled()).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('logs checkboxes are enabled', async () => {
|
||||
const logsCheckboxes =
|
||||
await observability.alerts.bulkActions.getCheckboxSelectorPerProducer('logs');
|
||||
|
||||
await asyncForEach(logsCheckboxes, async (checkbox, index) => {
|
||||
expect(await checkbox.isEnabled()).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
|
@ -18,5 +18,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./alerts/pagination'));
|
||||
loadTestFile(require.resolve('./alerts/add_to_case'));
|
||||
loadTestFile(require.resolve('./alerts/state_synchronization'));
|
||||
loadTestFile(require.resolve('./alerts/bulk_actions'));
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue