[ML] Transforms: Add functional tests for UI permissions (#106693)

* [ML] Transforms: Add functional tests for UI permissions

* [ML] Fix for edit flyout action

* [ML] Stabilize tests that open the actions menu
This commit is contained in:
Pete Harverson 2021-07-28 09:25:46 +01:00 committed by GitHub
parent 0c4c662ce7
commit f67737d9cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 480 additions and 74 deletions

View file

@ -69,31 +69,33 @@ export const EditTransformFlyoutForm: FC<EditTransformFlyoutFormProps> = ({
)}
paddingSize="s"
>
<EditTransformFlyoutFormTextInput
dataTestSubj="transformEditFlyoutDestinationIndexInput"
errorMessages={formFields.destinationIndex.errorMessages}
label={i18n.translate(
'xpack.transform.transformList.editFlyoutFormDestinationIndexLabel',
{
defaultMessage: 'Destination index',
}
)}
onChange={(value) => dispatch({ field: 'destinationIndex', value })}
value={formFields.destinationIndex.value}
/>
<div data-test-subj="transformEditAccordionDestinationContent">
<EditTransformFlyoutFormTextInput
dataTestSubj="transformEditFlyoutDestinationIndexInput"
errorMessages={formFields.destinationIndex.errorMessages}
label={i18n.translate(
'xpack.transform.transformList.editFlyoutFormDestinationIndexLabel',
{
defaultMessage: 'Destination index',
}
)}
onChange={(value) => dispatch({ field: 'destinationIndex', value })}
value={formFields.destinationIndex.value}
/>
<EditTransformFlyoutFormTextInput
dataTestSubj="transformEditFlyoutDestinationPipelineInput"
errorMessages={formFields.destinationPipeline.errorMessages}
label={i18n.translate(
'xpack.transform.transformList.editFlyoutFormDestinationPipelineLabel',
{
defaultMessage: 'Pipeline',
}
)}
onChange={(value) => dispatch({ field: 'destinationPipeline', value })}
value={formFields.destinationPipeline.value}
/>
<EditTransformFlyoutFormTextInput
dataTestSubj="transformEditFlyoutDestinationPipelineInput"
errorMessages={formFields.destinationPipeline.errorMessages}
label={i18n.translate(
'xpack.transform.transformList.editFlyoutFormDestinationPipelineLabel',
{
defaultMessage: 'Pipeline',
}
)}
onChange={(value) => dispatch({ field: 'destinationPipeline', value })}
value={formFields.destinationPipeline.value}
/>
</div>
</EuiAccordion>
<EuiSpacer size="l" />
@ -109,31 +111,33 @@ export const EditTransformFlyoutForm: FC<EditTransformFlyoutFormProps> = ({
)}
paddingSize="s"
>
<EditTransformFlyoutFormTextInput
dataTestSubj="transformEditFlyoutRetentionPolicyFieldInput"
errorMessages={formFields.retentionPolicyField.errorMessages}
label={i18n.translate(
'xpack.transform.transformList.editFlyoutFormRetentionPolicyFieldLabel',
{
defaultMessage: 'Field',
}
)}
onChange={(value) => dispatch({ field: 'retentionPolicyField', value })}
value={formFields.retentionPolicyField.value}
/>
<EditTransformFlyoutFormTextInput
dataTestSubj="transformEditFlyoutRetentionPolicyMaxAgeInput"
errorMessages={formFields.retentionPolicyMaxAge.errorMessages}
label={i18n.translate(
'xpack.transform.transformList.editFlyoutFormRetentionMaxAgeFieldLabel',
{
defaultMessage: 'Max age',
}
)}
onChange={(value) => dispatch({ field: 'retentionPolicyMaxAge', value })}
value={formFields.retentionPolicyMaxAge.value}
/>
<div data-test-subj="transformEditAccordionRetentionPolicyContent">
{' '}
<EditTransformFlyoutFormTextInput
dataTestSubj="transformEditFlyoutRetentionPolicyFieldInput"
errorMessages={formFields.retentionPolicyField.errorMessages}
label={i18n.translate(
'xpack.transform.transformList.editFlyoutFormRetentionPolicyFieldLabel',
{
defaultMessage: 'Field',
}
)}
onChange={(value) => dispatch({ field: 'retentionPolicyField', value })}
value={formFields.retentionPolicyField.value}
/>
<EditTransformFlyoutFormTextInput
dataTestSubj="transformEditFlyoutRetentionPolicyMaxAgeInput"
errorMessages={formFields.retentionPolicyMaxAge.errorMessages}
label={i18n.translate(
'xpack.transform.transformList.editFlyoutFormRetentionMaxAgeFieldLabel',
{
defaultMessage: 'Max age',
}
)}
onChange={(value) => dispatch({ field: 'retentionPolicyMaxAge', value })}
value={formFields.retentionPolicyMaxAge.value}
/>
</div>
</EuiAccordion>
<EuiSpacer size="l" />

View file

@ -238,7 +238,7 @@ export default function ({ getService }: FtrProviderContext) {
await transform.table.assertTransformRowActions(testData.originalConfig.id, false);
await transform.testExecution.logTestStep('should display the define pivot step');
await transform.table.clickTransformRowAction('Clone');
await transform.table.clickTransformRowAction(testData.originalConfig.id, 'Clone');
await transform.wizard.assertSelectedTransformFunction(testData.type);
await transform.wizard.assertDefineStepActive();
});

View file

@ -589,7 +589,7 @@ export default function ({ getService }: FtrProviderContext) {
await transform.table.assertTransformRowActions(testData.transformId, false);
await transform.testExecution.logTestStep('should navigate to discover');
await transform.table.clickTransformRowAction('Discover');
await transform.table.clickTransformRowAction(testData.transformId, 'Discover');
if (testData.discoverAdjustSuperDatePicker) {
await transform.discover.assertNoResults(testData.destinationIndex);

View file

@ -99,7 +99,7 @@ export default function ({ getService }: FtrProviderContext) {
);
await transform.testExecution.logTestStep('should stop the transform');
await transform.table.clickTransformRowAction('Stop');
await transform.table.clickTransformRowAction(testData.originalConfig.id, 'Stop');
}
await transform.testExecution.logTestStep('should display the stopped transform');
@ -117,7 +117,7 @@ export default function ({ getService }: FtrProviderContext) {
'Delete',
true
);
await transform.table.clickTransformRowAction('Delete');
await transform.table.clickTransformRowAction(testData.originalConfig.id, 'Delete');
await transform.table.assertTransformDeleteModalExists();
await transform.testExecution.logTestStep('should delete the transform');

View file

@ -112,7 +112,7 @@ export default function ({ getService }: FtrProviderContext) {
await transform.table.assertTransformRowActions(testData.originalConfig.id, false);
await transform.testExecution.logTestStep('should show the edit flyout');
await transform.table.clickTransformRowAction('Edit');
await transform.table.clickTransformRowAction(testData.originalConfig.id, 'Edit');
await transform.editFlyout.assertTransformEditFlyoutExists();
});

View file

@ -39,6 +39,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
await transform.securityUI.logout();
});
loadTestFile(require.resolve('./permissions'));
loadTestFile(require.resolve('./creation_index_pattern'));
loadTestFile(require.resolve('./creation_saved_search'));
loadTestFile(require.resolve('./creation_runtime_mappings'));

View file

@ -0,0 +1,187 @@
/*
* 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 { getPivotTransformConfig } from '../index';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const transform = getService('transform');
describe('for user with full transform access', function () {
describe('with no data loaded', function () {
before(async () => {
await transform.securityUI.loginAsTransformPowerUser();
});
after(async () => {
await transform.securityUI.logout();
});
it('should display elements in the Transform list page correctly', async () => {
await transform.testExecution.logTestStep('should load the Transform list page');
await transform.navigation.navigateTo();
await transform.management.assertTransformListPageExists();
await transform.testExecution.logTestStep('should display the stats bar');
await transform.management.assertTransformStatsBarExists();
await transform.testExecution.logTestStep(
'should display the "No transforms found" message'
);
await transform.management.assertNoTransformsFoundMessageExists();
await transform.testExecution.logTestStep(
'should display an enabled "Create first transform" button'
);
await transform.management.assertCreateFirstTransformButtonExists();
await transform.management.assertCreateFirstTransformButtonEnabled(true);
});
});
describe('with data loaded', function () {
const PREFIX = 'permissions_full_access';
const transformConfigWithPivot = getPivotTransformConfig(PREFIX, false);
before(async () => {
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce');
await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date');
await transform.api.createAndRunTransform(
transformConfigWithPivot.id,
transformConfigWithPivot
);
await transform.testResources.setKibanaTimeZoneToUTC();
await transform.securityUI.loginAsTransformPowerUser();
});
after(async () => {
await transform.testResources.deleteIndexPatternByTitle(
transformConfigWithPivot.dest.index
);
await transform.api.deleteIndices(transformConfigWithPivot.dest.index);
await transform.api.cleanTransformIndices();
});
it('should display elements in the Transform list page correctly', async () => {
await transform.testExecution.logTestStep('should load the Transform list page');
await transform.navigation.navigateTo();
await transform.management.assertTransformListPageExists();
await transform.testExecution.logTestStep('should display the stats bar');
await transform.management.assertTransformStatsBarExists();
await transform.testExecution.logTestStep('should display the transforms table');
await transform.management.assertTransformsTableExists();
await transform.testExecution.logTestStep(
'should display an enabled "Create a transform" button'
);
await transform.management.assertCreateNewTransformButtonExists();
await transform.management.assertCreateNewTransformButtonEnabled(true);
await transform.testExecution.logTestStep(
'should display the expected transform in the transform list'
);
await transform.table.refreshTransformList();
await transform.table.filterWithSearchString(transformConfigWithPivot.id, 1);
await transform.testExecution.logTestStep('should show the actions popover');
await transform.table.assertTransformRowActionsButtonEnabled(
transformConfigWithPivot.id,
true
);
await transform.table.assertTransformRowActions(transformConfigWithPivot.id, false);
await transform.testExecution.logTestStep('should have the edit action enabled');
await transform.table.assertTransformRowActionEnabled(
transformConfigWithPivot.id,
'Edit',
true
);
await transform.testExecution.logTestStep('should have the clone action enabled');
await transform.table.assertTransformRowActionEnabled(
transformConfigWithPivot.id,
'Clone',
true
);
await transform.testExecution.logTestStep('should have the delete action enabled');
await transform.table.assertTransformRowActionEnabled(
transformConfigWithPivot.id,
'Delete',
true
);
await transform.testExecution.logTestStep('should have the Discover action disabled');
await transform.table.assertTransformRowActionEnabled(
transformConfigWithPivot.id,
'Discover',
false
);
await transform.testExecution.logTestStep('should have the start action disabled');
await transform.table.assertTransformRowActionEnabled(
transformConfigWithPivot.id,
'Start',
false
);
await transform.testExecution.logTestStep('should show content in the expanded table row');
await transform.table.assertTransformExpandedRow();
});
it('should display controls in the edit flyout correctly', async () => {
await transform.testExecution.logTestStep('should show the edit flyout');
await transform.table.clickTransformRowAction(transformConfigWithPivot.id, 'Edit');
await transform.editFlyout.assertTransformEditFlyoutExists();
await transform.testExecution.logTestStep('should have the description input enabled');
await transform.editFlyout.assertTransformEditFlyoutInputEnabled('Description', true);
await transform.testExecution.logTestStep('should have the frequency input enabled');
await transform.editFlyout.assertTransformEditFlyoutInputEnabled('Frequency', true);
await transform.testExecution.logTestStep('should have the destination inputs enabled');
await transform.editFlyout.openTransformEditAccordionDestinationSettings();
await transform.editFlyout.assertTransformEditFlyoutInputEnabled('DestinationIndex', true);
await transform.editFlyout.assertTransformEditFlyoutInputEnabled(
'DestinationPipeline',
true
);
await transform.testExecution.logTestStep(
'should have the retention policy inputs enabled'
);
await transform.editFlyout.openTransformEditAccordionRetentionPolicySettings();
await transform.editFlyout.assertTransformEditFlyoutInputEnabled(
'RetentionPolicyField',
true
);
await transform.editFlyout.assertTransformEditFlyoutInputEnabled(
'RetentionPolicyMaxAge',
true
);
await transform.testExecution.logTestStep(
'should have the advanced settings inputs enabled'
);
await transform.editFlyout.openTransformEditAccordionAdvancedSettings();
await transform.editFlyout.assertTransformEditFlyoutInputEnabled('DocsPerSecond', true);
await transform.editFlyout.assertTransformEditFlyoutInputEnabled('MaxPageSearchSize', true);
await transform.testExecution.logTestStep(
'should have the update button enabled after making an edit'
);
await transform.editFlyout.assertTransformEditFlyoutInputExists('Frequency');
await transform.editFlyout.setTransformEditFlyoutInputValue('Frequency', '10m');
await transform.editFlyout.assertUpdateTransformButtonExists();
await transform.editFlyout.assertUpdateTransformButtonEnabled(true);
});
});
});
}

View file

@ -0,0 +1,15 @@
/*
* 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';
export default function ({ loadTestFile }: FtrProviderContext) {
describe('permissions', function () {
loadTestFile(require.resolve('./full_transform_access'));
loadTestFile(require.resolve('./read_transform_access'));
});
}

View file

@ -0,0 +1,106 @@
/*
* 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 { getPivotTransformConfig } from '../index';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const transform = getService('transform');
describe('for user with full transform access', function () {
describe('with no data loaded', function () {
before(async () => {
await transform.securityUI.loginAsTransformViewer();
});
after(async () => {
await transform.securityUI.logout();
});
it('should display elements in the Transform list page correctly', async () => {
await transform.testExecution.logTestStep('should load the Transform list page');
await transform.navigation.navigateTo();
await transform.management.assertTransformListPageExists();
await transform.testExecution.logTestStep('should display the stats bar');
await transform.management.assertTransformStatsBarExists();
await transform.testExecution.logTestStep(
'should display the "No transforms found" message'
);
await transform.management.assertNoTransformsFoundMessageExists();
await transform.testExecution.logTestStep(
'should display a disabled "Create first transform" button'
);
await transform.management.assertCreateFirstTransformButtonExists();
await transform.management.assertCreateFirstTransformButtonEnabled(false);
});
});
describe('with data loaded', function () {
const PREFIX = 'permissions_read_access';
const transformConfigWithPivot = getPivotTransformConfig(PREFIX, false);
before(async () => {
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce');
await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date');
await transform.api.createAndRunTransform(
transformConfigWithPivot.id,
transformConfigWithPivot
);
await transform.testResources.setKibanaTimeZoneToUTC();
await transform.securityUI.loginAsTransformViewer();
});
after(async () => {
await transform.testResources.deleteIndexPatternByTitle(
transformConfigWithPivot.dest.index
);
await transform.api.deleteIndices(transformConfigWithPivot.dest.index);
await transform.api.cleanTransformIndices();
});
it('should display elements in the Transform list page correctly', async () => {
await transform.testExecution.logTestStep('should load the Transform list page');
await transform.navigation.navigateTo();
await transform.management.assertTransformListPageExists();
await transform.testExecution.logTestStep('should display the stats bar');
await transform.management.assertTransformStatsBarExists();
await transform.testExecution.logTestStep('should display the transforms table');
await transform.management.assertTransformsTableExists();
await transform.testExecution.logTestStep(
'should display a disabled "Create a transform" button'
);
await transform.management.assertCreateNewTransformButtonExists();
await transform.management.assertCreateNewTransformButtonEnabled(false);
await transform.testExecution.logTestStep(
'should display the expected transform in the transform list'
);
await transform.table.refreshTransformList();
await transform.table.filterWithSearchString(transformConfigWithPivot.id, 1);
await transform.testExecution.logTestStep('should display a disabled actions popover');
await transform.table.assertTransformRowActionsButtonEnabled(
transformConfigWithPivot.id,
false
);
await transform.testExecution.logTestStep('should show content in the expanded table row');
await transform.table.assertTransformExpandedRow();
});
});
});
}

View file

@ -77,7 +77,7 @@ export default function ({ getService }: FtrProviderContext) {
await transform.testExecution.logTestStep('should start the transform');
await transform.table.assertTransformRowActionEnabled(transformId, 'Start', true);
await transform.table.clickTransformRowAction('Start');
await transform.table.clickTransformRowAction(transformId, 'Start');
await transform.table.confirmStartTransform();
await transform.table.clearSearchString(testDataList.length);

View file

@ -37,7 +37,28 @@ export function TransformEditFlyoutProvider({ getService }: FtrProviderContext)
);
},
// for now we expect this to be used only for opening the accordion
async assertTransformEditFlyoutInputEnabled(input: string, expectedValue: boolean) {
await testSubjects.existOrFail(`transformEditFlyout${input}Input`, { timeout: 1000 });
const isEnabled = await testSubjects.isEnabled(`transformEditFlyout${input}Input`);
expect(isEnabled).to.eql(
expectedValue,
`Expected '${input}' input to be '${expectedValue ? 'enabled' : 'disabled'}' (got '${
isEnabled ? 'enabled' : 'disabled'
}')`
);
},
// for now we expect these to be used only for opening the accordion
async openTransformEditAccordionDestinationSettings() {
await testSubjects.click('transformEditAccordionDestination');
await testSubjects.existOrFail('transformEditAccordionDestinationContent');
},
async openTransformEditAccordionRetentionPolicySettings() {
await testSubjects.click('transformEditAccordionRetentionPolicy');
await testSubjects.existOrFail('transformEditAccordionRetentionPolicyContent');
},
async openTransformEditAccordionAdvancedSettings() {
await testSubjects.click('transformEditAccordionAdvancedSettings');
await testSubjects.existOrFail('transformEditAccordionAdvancedSettingsContent');
@ -50,6 +71,20 @@ export function TransformEditFlyoutProvider({ getService }: FtrProviderContext)
await this.assertTransformEditFlyoutInputValue(input, value);
},
async assertUpdateTransformButtonExists() {
await testSubjects.existOrFail('transformEditFlyoutUpdateButton');
},
async assertUpdateTransformButtonEnabled(expectedValue: boolean) {
const isEnabled = await testSubjects.isEnabled('transformEditFlyoutUpdateButton');
expect(isEnabled).to.eql(
expectedValue,
`Expected "Update" button to be '${expectedValue ? 'enabled' : 'disabled'}' (got '${
isEnabled ? 'enabled' : 'disabled'
}')`
);
},
async updateTransform() {
await testSubjects.click('transformEditFlyoutUpdateButton');
await retry.tryForTime(5000, async () => {

View file

@ -5,6 +5,8 @@
* 2.0.
*/
import expect from '@kbn/expect';
import { ProvidedType } from '@kbn/test';
import { FtrProviderContext } from '../../ftr_provider_context';
@ -26,10 +28,34 @@ export function TransformManagementProvider({ getService }: FtrProviderContext)
await testSubjects.existOrFail('~transformListTable');
},
async assertCreateFirstTransformButtonExists() {
await testSubjects.existOrFail('transformCreateFirstButton');
},
async assertCreateFirstTransformButtonEnabled(expectedValue: boolean) {
const isEnabled = await testSubjects.isEnabled('transformCreateFirstButton');
expect(isEnabled).to.eql(
expectedValue,
`Expected "Create first transform" button to be '${
expectedValue ? 'enabled' : 'disabled'
}' (got '${isEnabled ? 'enabled' : 'disabled'}')`
);
},
async assertCreateNewTransformButtonExists() {
await testSubjects.existOrFail('transformButtonCreate');
},
async assertCreateNewTransformButtonEnabled(expectedValue: boolean) {
const isEnabled = await testSubjects.isEnabled('transformButtonCreate');
expect(isEnabled).to.eql(
expectedValue,
`Expected "Create a transform" button to be '${
expectedValue ? 'enabled' : 'disabled'
}' (got '${isEnabled ? 'enabled' : 'disabled'}')`
);
},
async assertTransformStatsBarExists() {
await testSubjects.existOrFail('transformStatsBar');
},

View file

@ -12,6 +12,7 @@ import { FtrProviderContext } from '../../ftr_provider_context';
type TransformRowActionName = 'Clone' | 'Delete' | 'Edit' | 'Start' | 'Stop' | 'Discover';
export function TransformTableProvider({ getService }: FtrProviderContext) {
const find = getService('find');
const retry = getService('retry');
const testSubjects = getService('testSubjects');
const browser = getService('browser');
@ -235,8 +236,47 @@ export function TransformTableProvider({ getService }: FtrProviderContext) {
return !subSelector ? row : `${row} > ${subSelector}`;
}
public async ensureTransformActionsMenuOpen(transformId: string) {
await retry.tryForTime(30 * 1000, async () => {
await this.ensureTransformActionsMenuClosed();
if (!(await find.existsByCssSelector('.euiContextMenuPanel', 1000))) {
await testSubjects.click(this.rowSelector(transformId, 'euiCollapsedItemActionsButton'));
expect(await find.existsByCssSelector('.euiContextMenuPanel', 1000)).to.eql(
true,
'Actions popover should exist'
);
}
});
}
public async ensureTransformActionsMenuClosed() {
await retry.tryForTime(30 * 1000, async () => {
await browser.pressKeys(browser.keys.ESCAPE);
expect(await find.existsByCssSelector('.euiContextMenuPanel', 1000)).to.eql(
false,
'Actions popover should not exist'
);
});
}
public async assertTransformRowActionsButtonEnabled(
transformId: string,
expectedValue: boolean
) {
const isEnabled = await testSubjects.isEnabled(
this.rowSelector(transformId, 'euiCollapsedItemActionsButton')
);
expect(isEnabled).to.eql(
expectedValue,
`Expected transform row actions button to be '${
expectedValue ? 'enabled' : 'disabled'
}' (got '${isEnabled ? 'enabled' : 'disabled'}')`
);
}
public async assertTransformRowActions(transformId: string, isTransformRunning = false) {
await testSubjects.click(this.rowSelector(transformId, 'euiCollapsedItemActionsButton'));
await this.ensureTransformActionsMenuOpen(transformId);
await testSubjects.existOrFail('transformActionClone');
await testSubjects.existOrFail('transformActionDelete');
@ -250,6 +290,8 @@ export function TransformTableProvider({ getService }: FtrProviderContext) {
await testSubjects.existOrFail('transformActionStart');
await testSubjects.missingOrFail('transformActionStop');
}
await this.ensureTransformActionsMenuClosed();
}
public async assertTransformRowActionEnabled(
@ -261,10 +303,9 @@ export function TransformTableProvider({ getService }: FtrProviderContext) {
await retry.tryForTime(60 * 1000, async () => {
await this.refreshTransformList();
await browser.pressKeys(browser.keys.ESCAPE);
await testSubjects.click(this.rowSelector(transformId, 'euiCollapsedItemActionsButton'));
await this.ensureTransformActionsMenuOpen(transformId);
await testSubjects.existOrFail(selector);
await testSubjects.existOrFail(selector, { timeout: 1000 });
const isEnabled = await testSubjects.isEnabled(selector);
expect(isEnabled).to.eql(
expectedValue,
@ -272,24 +313,15 @@ export function TransformTableProvider({ getService }: FtrProviderContext) {
isEnabled ? 'enabled' : 'disabled'
}')`
);
await this.ensureTransformActionsMenuClosed();
});
}
public async clickTransformRowActionWithRetry(
transformId: string,
action: TransformRowActionName
) {
await retry.tryForTime(30 * 1000, async () => {
await browser.pressKeys(browser.keys.ESCAPE);
await testSubjects.click(this.rowSelector(transformId, 'euiCollapsedItemActionsButton'));
await testSubjects.existOrFail(`transformAction${action}`);
await testSubjects.click(`transformAction${action}`);
await testSubjects.missingOrFail(`transformAction${action}`);
});
}
public async clickTransformRowAction(action: TransformRowActionName) {
public async clickTransformRowAction(transformId: string, action: TransformRowActionName) {
await this.ensureTransformActionsMenuOpen(transformId);
await testSubjects.click(`transformAction${action}`);
await testSubjects.missingOrFail(`transformAction${action}`);
}
public async waitForTransformsExpandedRowPreviewTabToLoad() {