diff --git a/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts b/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts index 63e60a0eb19e40..caaf072c934caf 100644 --- a/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts +++ b/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts @@ -98,7 +98,12 @@ const STANDARD_LIST_TYPES = [ 'lens', 'links', 'map', + // cases saved objects 'cases', + 'cases-comments', + 'cases-user-actions', + 'cases-configure', + 'cases-connector-mappings', // synthetics based objects 'synthetics-monitor', 'uptime-dynamic-settings', diff --git a/x-pack/test/functional/services/cases/common.ts b/x-pack/test/functional/services/cases/common.ts index 4fe8523a6bb876..4809fe4278814e 100644 --- a/x-pack/test/functional/services/cases/common.ts +++ b/x-pack/test/functional/services/cases/common.ts @@ -96,7 +96,6 @@ export function CasesCommonServiceProvider({ getService, getPageObject }: FtrPro async expectToasterToContain(content: string) { const toast = await toasts.getToastElement(1); expect(await toast.getVisibleText()).to.contain(content); - await toasts.dismissAllToasts(); }, async assertCaseModalVisible(expectVisible = true) { diff --git a/x-pack/test/functional_with_es_ssl/apps/cases/group1/view_case.ts b/x-pack/test/functional_with_es_ssl/apps/cases/group1/view_case.ts index 9391c9f1e77db3..77ceb4b1a21171 100644 --- a/x-pack/test/functional_with_es_ssl/apps/cases/group1/view_case.ts +++ b/x-pack/test/functional_with_es_ssl/apps/cases/group1/view_case.ts @@ -1154,8 +1154,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/168534 - describe.skip('customFields', () => { + describe('customFields', () => { const customFields = [ { key: 'valid_key_1', @@ -1198,13 +1197,13 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('updates a custom field correctly', async () => { - const summary = await testSubjects.find(`case-text-custom-field-${customFields[0].key}`); - expect(await summary.getVisibleText()).equal('this is a text field value'); + const textField = await testSubjects.find(`case-text-custom-field-${customFields[0].key}`); + expect(await textField.getVisibleText()).equal('this is a text field value'); - const sync = await testSubjects.find( + const toggle = await testSubjects.find( `case-toggle-custom-field-form-field-${customFields[1].key}` ); - expect(await sync.getAttribute('aria-checked')).equal('true'); + expect(await toggle.getAttribute('aria-checked')).equal('true'); await testSubjects.click(`case-text-custom-field-edit-button-${customFields[0].key}`); @@ -1222,19 +1221,23 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await testSubjects.click(`case-text-custom-field-submit-button-${customFields[0].key}`); + await header.waitUntilLoadingHasFinished(); + await retry.waitFor('update toast exist', async () => { return await testSubjects.exists('toastCloseButton'); }); await testSubjects.click('toastCloseButton'); - await sync.click(); + await header.waitUntilLoadingHasFinished(); + + await toggle.click(); await header.waitUntilLoadingHasFinished(); - expect(await summary.getVisibleText()).equal('this is a text field value edited!!'); + expect(await textField.getVisibleText()).equal('this is a text field value edited!!'); - expect(await sync.getAttribute('aria-checked')).equal('false'); + expect(await toggle.getAttribute('aria-checked')).equal('false'); // validate user action const userActions = await find.allByCssSelector( diff --git a/x-pack/test/functional_with_es_ssl/apps/cases/group2/attachment_framework.ts b/x-pack/test/functional_with_es_ssl/apps/cases/group2/attachment_framework.ts index ca9c4ad3af49a0..5ac08acfbc6ed3 100644 --- a/x-pack/test/functional_with_es_ssl/apps/cases/group2/attachment_framework.ts +++ b/x-pack/test/functional_with_es_ssl/apps/cases/group2/attachment_framework.ts @@ -61,6 +61,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const dashboard = getPageObject('dashboard'); const lens = getPageObject('lens'); const listingTable = getService('listingTable'); + const toasts = getService('toasts'); const createAttachmentAndNavigate = async (attachment: AttachmentRequest) => { const caseData = await cases.api.createCase({ @@ -249,6 +250,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { */ await cases.create.createCase({ owner }); await cases.common.expectToasterToContain('has been updated'); + await toasts.dismissAllToastsWithChecks(); } const casesCreatedFromFlyout = await findCases({ supertest }); @@ -325,6 +327,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await testSubjects.click(`cases-table-row-select-${currentCaseId}`); await cases.common.expectToasterToContain('has been updated'); + await toasts.dismissAllToastsWithChecks(); await ensureFirstCommentOwner(currentCaseId, owner); } }); @@ -387,6 +390,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await cases.common.expectToasterToContain(`${caseTitle} has been updated`); await testSubjects.click('toaster-content-case-view-link'); + await toasts.dismissAllToastsWithChecks(); const title = await find.byCssSelector('[data-test-subj="editable-title-header-value"]'); expect(await title.getVisibleText()).toEqual(caseTitle); @@ -414,6 +418,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await cases.common.expectToasterToContain(`${theCaseTitle} has been updated`); await testSubjects.click('toaster-content-case-view-link'); + await toasts.dismissAllToastsWithChecks(); const title = await find.byCssSelector('[data-test-subj="editable-title-header-value"]'); expect(await title.getVisibleText()).toEqual(theCaseTitle); diff --git a/x-pack/test_serverless/api_integration/services/svl_cases/api.ts b/x-pack/test_serverless/api_integration/services/svl_cases/api.ts index a504b71240dd56..8f23eba1ea9814 100644 --- a/x-pack/test_serverless/api_integration/services/svl_cases/api.ts +++ b/x-pack/test_serverless/api_integration/services/svl_cases/api.ts @@ -79,7 +79,7 @@ export function SvlCasesApiServiceProvider({ getService }: FtrProviderContext) { async deleteAllCaseItems() { await Promise.all([ - this.deleteCasesByESQuery(), + this.deleteCases(), this.deleteCasesUserActions(), this.deleteComments(), this.deleteConfiguration(), @@ -91,7 +91,7 @@ export function SvlCasesApiServiceProvider({ getService }: FtrProviderContext) { await kbnServer.savedObjects.clean({ types: ['cases-user-actions'] }); }, - async deleteCasesByESQuery(): Promise { + async deleteCases(): Promise { await kbnServer.savedObjects.clean({ types: ['cases'] }); }, diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts index d1f601f709af26..30fbe518085cb3 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts @@ -14,7 +14,7 @@ export default ({ getService }: FtrProviderContext): void => { describe('get_case', () => { afterEach(async () => { - await svlCases.api.deleteCasesByESQuery(); + await svlCases.api.deleteCases(); }); it('should return a case', async () => { diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts index 01cf60d424f902..79f180a5092ff9 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts @@ -15,7 +15,7 @@ export default ({ getService }: FtrProviderContext): void => { describe('post_case', () => { afterEach(async () => { - await svlCases.api.deleteCasesByESQuery(); + await svlCases.api.deleteCases(); }); it('should create a case', async () => { diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts index 719841ff28ab50..fe3c02a7342a9d 100644 --- a/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts +++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts @@ -13,7 +13,7 @@ export default ({ getService }: FtrProviderContext): void => { describe('get_case', () => { afterEach(async () => { - await svlCases.api.deleteCasesByESQuery(); + await svlCases.api.deleteCases(); }); it('should return a case', async () => { diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts index 77917915d4bcc1..db5967654de854 100644 --- a/x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts +++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts @@ -15,7 +15,7 @@ export default ({ getService }: FtrProviderContext): void => { describe('post_case', () => { afterEach(async () => { - await svlCases.api.deleteCasesByESQuery(); + await svlCases.api.deleteCases(); }); it('should create a case', async () => { diff --git a/x-pack/test_serverless/functional/test_suites/observability/cases/attachment_framework.ts b/x-pack/test_serverless/functional/test_suites/observability/cases/attachment_framework.ts index cd0647a1a35d75..e1a13b456c0f34 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/cases/attachment_framework.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/cases/attachment_framework.ts @@ -18,39 +18,37 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const cases = getService('cases'); + const svlCases = getService('svlCases'); const find = getService('find'); + const toasts = getService('toasts'); - // failing test https://github.com/elastic/kibana/issues/166592 - describe.skip('Cases persistable attachments', function () { - // security_exception: action [indices:data/write/delete/byquery] is unauthorized for user [elastic] with effective roles [superuser] on restricted indices [.kibana_alerting_cases], this action is granted by the index privileges [delete,write,all] - this.tags(['failsOnMKI']); + describe('Cases persistable attachments', function () { describe('lens visualization', () => { before(async () => { await svlCommonPage.login(); + await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); await kibanaServer.importExport.load( 'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json' ); await svlObltNavigation.navigateToLandingPage(); - await svlCommonNavigation.sidenav.clickLink({ deepLinkId: 'dashboards' }); await dashboard.clickNewDashboard(); - await lens.createAndAddLensFromDashboard({}); - await dashboard.waitForRenderComplete(); }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await esArchiver.unload('x-pack/test/functional/es_archives/logstash_functional'); await kibanaServer.importExport.unload( 'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json' ); + await kibanaServer.savedObjects.cleanStandardList(); await svlCommonPage.forceLogout(); }); @@ -73,8 +71,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await testSubjects.click('create-case-submit'); await cases.common.expectToasterToContain(`${caseTitle} has been updated`); - await testSubjects.click('toaster-content-case-view-link'); + await toasts.dismissAllToastsWithChecks(); if (await testSubjects.exists('appLeaveConfirmModal')) { await testSubjects.exists('confirmModalConfirmButton'); @@ -108,6 +106,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await cases.common.expectToasterToContain(`${theCaseTitle} has been updated`); await testSubjects.click('toaster-content-case-view-link'); + await toasts.dismissAllToastsWithChecks(); if (await testSubjects.exists('appLeaveConfirmModal')) { await testSubjects.exists('confirmModalConfirmButton'); diff --git a/x-pack/test_serverless/functional/test_suites/observability/cases/configure.ts b/x-pack/test_serverless/functional/test_suites/observability/cases/configure.ts index f63ce94ead3fe1..79339d0dc345ba 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/cases/configure.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/cases/configure.ts @@ -16,13 +16,12 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const svlObltNavigation = getService('svlObltNavigation'); const testSubjects = getService('testSubjects'); const cases = getService('cases'); + const svlCases = getService('svlCases'); const toasts = getService('toasts'); const retry = getService('retry'); const find = getService('find'); describe('Configure Case', function () { - // security_exception: action [indices:data/write/delete/byquery] is unauthorized for user [elastic] with effective roles [superuser] on restricted indices [.kibana_alerting_cases], this action is granted by the index privileges [delete,write,all] - this.tags(['failsOnMKI']); before(async () => { await svlCommonPage.login(); await svlObltNavigation.navigateToLandingPage(); @@ -42,7 +41,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await svlCommonPage.forceLogout(); }); diff --git a/x-pack/test_serverless/functional/test_suites/observability/cases/create_case_form.ts b/x-pack/test_serverless/functional/test_suites/observability/cases/create_case_form.ts index 58fb83ce2c8775..9bc03b8e232b80 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/cases/create_case_form.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/cases/create_case_form.ts @@ -16,10 +16,9 @@ const owner = OBSERVABILITY_OWNER; export default ({ getService, getPageObject }: FtrProviderContext) => { describe('Create Case', function () { - // security_exception: action [indices:data/write/delete/byquery] is unauthorized for user [elastic] with effective roles [superuser] on restricted indices [.kibana_alerting_cases], this action is granted by the index privileges [delete,write,all] - this.tags(['failsOnMKI']); const find = getService('find'); const cases = getService('cases'); + const svlCases = getService('svlCases'); const testSubjects = getService('testSubjects'); const svlCommonPage = getPageObject('svlCommonPage'); const config = getService('config'); @@ -35,7 +34,7 @@ export default ({ getService, getPageObject }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await svlCommonPage.forceLogout(); }); diff --git a/x-pack/test_serverless/functional/test_suites/observability/cases/index.ts b/x-pack/test_serverless/functional/test_suites/observability/cases/index.ts new file mode 100644 index 00000000000000..801166c562b456 --- /dev/null +++ b/x-pack/test_serverless/functional/test_suites/observability/cases/index.ts @@ -0,0 +1,18 @@ +/* + * 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('Serverless Observability Cases', function () { + loadTestFile(require.resolve('./attachment_framework')); + loadTestFile(require.resolve('./view_case')); + loadTestFile(require.resolve('./configure')); + loadTestFile(require.resolve('./create_case_form')); + loadTestFile(require.resolve('./list_view')); + }); +} diff --git a/x-pack/test_serverless/functional/test_suites/observability/cases/list_view.ts b/x-pack/test_serverless/functional/test_suites/observability/cases/list_view.ts index 30fd021e5c6f50..b001adb306a44d 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/cases/list_view.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/cases/list_view.ts @@ -14,13 +14,12 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const header = getPageObject('header'); const testSubjects = getService('testSubjects'); const cases = getService('cases'); + const svlCases = getService('svlCases'); const svlCommonNavigation = getPageObject('svlCommonNavigation'); const svlCommonPage = getPageObject('svlCommonPage'); const svlObltNavigation = getService('svlObltNavigation'); describe('Cases list', function () { - // multiple errors in after hook due to delete permission - this.tags(['failsOnMKI']); before(async () => { await svlCommonPage.login(); await svlObltNavigation.navigateToLandingPage(); @@ -28,7 +27,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await cases.casesTable.waitForCasesToBeDeleted(); await svlCommonPage.forceLogout(); }); @@ -107,7 +106,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); afterEach(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await cases.casesTable.waitForCasesToBeDeleted(); }); @@ -170,7 +169,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await cases.casesTable.waitForCasesToBeDeleted(); }); @@ -274,6 +273,7 @@ const createNCasesBeforeDeleteAllAfter = ( getService: FtrProviderContext['getService'] ) => { const cases = getService('cases'); + const svlCases = getService('svlCases'); const header = getPageObject('header'); before(async () => { @@ -283,7 +283,7 @@ const createNCasesBeforeDeleteAllAfter = ( }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await cases.casesTable.waitForCasesToBeDeleted(); }); }; diff --git a/x-pack/test_serverless/functional/test_suites/observability/cases/view_case.ts b/x-pack/test_serverless/functional/test_suites/observability/cases/view_case.ts index a0fbd090ea97a2..c60b7a8ed103c7 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/cases/view_case.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/cases/view_case.ts @@ -26,6 +26,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const header = getPageObject('header'); const testSubjects = getService('testSubjects'); const cases = getService('cases'); + const svlCases = getService('svlCases'); const find = getService('find'); const retry = getService('retry'); @@ -34,14 +35,12 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const svlCommonPage = getPageObject('svlCommonPage'); describe('Case View', function () { - // security_exception: action [indices:data/write/delete/byquery] is unauthorized for user [elastic] with effective roles [superuser] on restricted indices [.kibana_alerting_cases], this action is granted by the index privileges [delete,write,all] - this.tags(['failsOnMKI']); before(async () => { await svlCommonPage.login(); }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await svlCommonPage.forceLogout(); }); @@ -280,7 +279,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { after(async () => { await cases.testResources.removeKibanaSampleData('logs'); - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); }); it('adds lens visualization in description', async () => { @@ -325,7 +324,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); }); it('initially renders user actions list correctly', async () => { @@ -437,7 +436,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); }); it('should set the cases title', async () => { @@ -498,17 +497,17 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); afterEach(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); }); it('updates a custom field correctly', async () => { - const summary = await testSubjects.find(`case-text-custom-field-${customFields[0].key}`); - expect(await summary.getVisibleText()).equal('this is a text field value'); + const textField = await testSubjects.find(`case-text-custom-field-${customFields[0].key}`); + expect(await textField.getVisibleText()).equal('this is a text field value'); - const sync = await testSubjects.find( + const toggle = await testSubjects.find( `case-toggle-custom-field-form-field-${customFields[1].key}` ); - expect(await sync.getAttribute('aria-checked')).equal('true'); + expect(await toggle.getAttribute('aria-checked')).equal('true'); await testSubjects.click(`case-text-custom-field-edit-button-${customFields[0].key}`); @@ -526,19 +525,23 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await testSubjects.click(`case-text-custom-field-submit-button-${customFields[0].key}`); + await header.waitUntilLoadingHasFinished(); + await retry.waitFor('update toast exist', async () => { return await testSubjects.exists('toastCloseButton'); }); await testSubjects.click('toastCloseButton'); - await sync.click(); + await header.waitUntilLoadingHasFinished(); + + await toggle.click(); await header.waitUntilLoadingHasFinished(); - expect(await summary.getVisibleText()).equal('this is a text field value edited!!'); + expect(await textField.getVisibleText()).equal('this is a text field value edited!!'); - expect(await sync.getAttribute('aria-checked')).equal('false'); + expect(await toggle.getAttribute('aria-checked')).equal('false'); // validate user action const userActions = await find.allByCssSelector( diff --git a/x-pack/test_serverless/functional/test_suites/observability/index.ts b/x-pack/test_serverless/functional/test_suites/observability/index.ts index 8611ba5c3abbc6..3de929288c253c 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/index.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/index.ts @@ -12,12 +12,8 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./landing_page')); loadTestFile(require.resolve('./navigation')); loadTestFile(require.resolve('./observability_log_explorer')); - loadTestFile(require.resolve('./cases/attachment_framework')); loadTestFile(require.resolve('./rules/rules_list')); - loadTestFile(require.resolve('./cases/view_case')); - loadTestFile(require.resolve('./cases/configure')); - loadTestFile(require.resolve('./cases/create_case_form')); - loadTestFile(require.resolve('./cases/list_view')); + loadTestFile(require.resolve('./cases')); loadTestFile(require.resolve('./advanced_settings')); loadTestFile(require.resolve('./infra')); loadTestFile(require.resolve('./ml')); diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/attachment_framework.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/attachment_framework.ts index 6fb8c2ae94e442..24da4464e9fb3d 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/attachment_framework.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/attachment_framework.ts @@ -12,40 +12,38 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const dashboard = getPageObject('dashboard'); const lens = getPageObject('lens'); const svlSecNavigation = getService('svlSecNavigation'); + const svlCommonPage = getPageObject('svlCommonPage'); const testSubjects = getService('testSubjects'); - const esArchiver = getService('esArchiver'); - const kibanaServer = getService('kibanaServer'); const cases = getService('cases'); + const svlCases = getService('svlCases'); const find = getService('find'); + const retry = getService('retry'); + const header = getPageObject('header'); + const toasts = getService('toasts'); - // Failing - // Issue: https://github.com/elastic/kibana/issues/165135 - describe.skip('Cases persistable attachments', () => { + describe('Cases persistable attachments', () => { describe('lens visualization', () => { before(async () => { - await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); - await kibanaServer.importExport.load( - 'x-pack/test/functional/fixtures/kbn_archiver/dashboard/feature_controls/security/security.json' - ); - + await svlCommonPage.login(); await svlSecNavigation.navigateToLandingPage(); await testSubjects.click('solutionSideNavItemLink-dashboards'); + await header.waitUntilLoadingHasFinished(); + + await retry.waitFor('createDashboardButton', async () => { + return await testSubjects.exists('createDashboardButton'); + }); await testSubjects.click('createDashboardButton'); + await header.waitUntilLoadingHasFinished(); await lens.createAndAddLensFromDashboard({}); - await dashboard.waitForRenderComplete(); }); after(async () => { - await cases.api.deleteAllCases(); - - await esArchiver.unload('x-pack/test/functional/es_archives/logstash_functional'); - await kibanaServer.importExport.unload( - 'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json' - ); + await svlCases.api.deleteAllCaseItems(); + await svlCommonPage.forceLogout(); }); it('adds lens visualization to a new case', async () => { @@ -68,8 +66,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await testSubjects.click('create-case-submit'); await cases.common.expectToasterToContain(`${caseTitle} has been updated`); - await testSubjects.click('toaster-content-case-view-link'); + await toasts.dismissAllToastsWithChecks(); if (await testSubjects.exists('appLeaveConfirmModal')) { await testSubjects.exists('confirmModalConfirmButton'); @@ -107,6 +105,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await cases.common.expectToasterToContain(`${theCaseTitle} has been updated`); await testSubjects.click('toaster-content-case-view-link'); + await toasts.dismissAllToastsWithChecks(); if (await testSubjects.exists('appLeaveConfirmModal')) { await testSubjects.exists('confirmModalConfirmButton'); diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/configure.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/configure.ts index 19cd7a3ccdce06..320f83790d301e 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/configure.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/configure.ts @@ -15,13 +15,12 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const svlSecNavigation = getService('svlSecNavigation'); const testSubjects = getService('testSubjects'); const cases = getService('cases'); + const svlCases = getService('svlCases'); const toasts = getService('toasts'); const retry = getService('retry'); const find = getService('find'); describe('Configure Case', function () { - // security_exception: action [indices:data/write/delete/byquery] is unauthorized for user [elastic] with effective roles [superuser] on restricted indices [.kibana_alerting_cases], this action is granted by the index privileges [delete,write,all] - this.tags(['failsOnMKI']); before(async () => { await svlCommonPage.login(); await svlSecNavigation.navigateToLandingPage(); @@ -41,7 +40,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await svlCommonPage.forceLogout(); }); diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/create_case_form.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/create_case_form.ts index 9acc6378b620e1..b5ef129b467dc3 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/create_case_form.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/create_case_form.ts @@ -16,9 +16,9 @@ const owner = SECURITY_SOLUTION_OWNER; export default ({ getService, getPageObject }: FtrProviderContext) => { describe('Create Case', function () { - this.tags(['failsOnMKI']); const find = getService('find'); const cases = getService('cases'); + const svlCases = getService('svlCases'); const testSubjects = getService('testSubjects'); const config = getService('config'); const svlCommonPage = getPageObject('svlCommonPage'); @@ -34,7 +34,7 @@ export default ({ getService, getPageObject }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await svlCommonPage.forceLogout(); }); diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/index.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/index.ts new file mode 100644 index 00000000000000..998c74e23f1212 --- /dev/null +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/index.ts @@ -0,0 +1,18 @@ +/* + * 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('Serverless Security Cases', function () { + loadTestFile(require.resolve('./attachment_framework')); + loadTestFile(require.resolve('./view_case')); + loadTestFile(require.resolve('./create_case_form')); + loadTestFile(require.resolve('./configure')); + loadTestFile(require.resolve('./list_view')); + }); +} diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/list_view.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/list_view.ts index 045d56b9c5dd8a..8a753e5d4829ab 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/list_view.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/list_view.ts @@ -14,12 +14,11 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const header = getPageObject('header'); const testSubjects = getService('testSubjects'); const cases = getService('cases'); + const svlCases = getService('svlCases'); const svlSecNavigation = getService('svlSecNavigation'); const svlCommonPage = getPageObject('svlCommonPage'); describe('Cases List', function () { - // multiple errors in after hook due to delete permission - this.tags(['failsOnMKI']); before(async () => { await svlCommonPage.login(); @@ -29,7 +28,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await cases.casesTable.waitForCasesToBeDeleted(); await svlCommonPage.forceLogout(); }); @@ -49,8 +48,6 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); describe('bulk actions', () => { - // security_exception: action [indices:data/write/delete/byquery] is unauthorized for user [elastic] with effective roles [superuser] on restricted indices [.kibana_alerting_cases], this action is granted by the index privileges [delete,write,all] - // action [indices:data/write/delete/byquery] is unauthorized for user [elastic] with effective roles [superuser] on restricted indices [.kibana_alerting_cases], this action is granted by the index privileges [delete,write,all] describe('delete', () => { createNCasesBeforeDeleteAllAfter(8, getPageObject, getService); @@ -110,7 +107,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); afterEach(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await cases.casesTable.waitForCasesToBeDeleted(); }); @@ -174,7 +171,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await cases.casesTable.waitForCasesToBeDeleted(); }); @@ -279,6 +276,7 @@ const createNCasesBeforeDeleteAllAfter = ( getService: FtrProviderContext['getService'] ) => { const cases = getService('cases'); + const svlCases = getService('svlCases'); const header = getPageObject('header'); before(async () => { @@ -288,7 +286,7 @@ const createNCasesBeforeDeleteAllAfter = ( }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await cases.casesTable.waitForCasesToBeDeleted(); }); }; diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/view_case.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/view_case.ts index 85ed51c191ba50..c3d82858576347 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cases/view_case.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cases/view_case.ts @@ -26,6 +26,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const header = getPageObject('header'); const testSubjects = getService('testSubjects'); const cases = getService('cases'); + const svlCases = getService('svlCases'); const find = getService('find'); const retry = getService('retry'); @@ -34,14 +35,12 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const svlCommonPage = getPageObject('svlCommonPage'); describe('Case View', function () { - // security_exception: action [indices:data/write/delete/byquery] is unauthorized for user [elastic] with effective roles [superuser] on restricted indices [.kibana_alerting_cases], this action is granted by the index privileges [delete,write,all] - this.tags(['failsOnMKI']); before(async () => { await svlCommonPage.login(); }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); await svlCommonPage.forceLogout(); }); @@ -279,7 +278,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { after(async () => { await cases.testResources.removeKibanaSampleData('logs'); - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); }); it('adds lens visualization in description', async () => { @@ -324,7 +323,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); }); it('initially renders user actions list correctly', async () => { @@ -436,7 +435,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); }); it('should set the cases title', async () => { @@ -498,17 +497,17 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); afterEach(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); }); it('updates a custom field correctly', async () => { - const summary = await testSubjects.find(`case-text-custom-field-${customFields[0].key}`); - expect(await summary.getVisibleText()).equal('this is a text field value'); + const textField = await testSubjects.find(`case-text-custom-field-${customFields[0].key}`); + expect(await textField.getVisibleText()).equal('this is a text field value'); - const sync = await testSubjects.find( + const toggle = await testSubjects.find( `case-toggle-custom-field-form-field-${customFields[1].key}` ); - expect(await sync.getAttribute('aria-checked')).equal('true'); + expect(await toggle.getAttribute('aria-checked')).equal('true'); await testSubjects.click(`case-text-custom-field-edit-button-${customFields[0].key}`); @@ -526,19 +525,23 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await testSubjects.click(`case-text-custom-field-submit-button-${customFields[0].key}`); + await header.waitUntilLoadingHasFinished(); + await retry.waitFor('update toast exist', async () => { return await testSubjects.exists('toastCloseButton'); }); await testSubjects.click('toastCloseButton'); - await sync.click(); + await header.waitUntilLoadingHasFinished(); + + await toggle.click(); await header.waitUntilLoadingHasFinished(); - expect(await summary.getVisibleText()).equal('this is a text field value edited!!'); + expect(await textField.getVisibleText()).equal('this is a text field value edited!!'); - expect(await sync.getAttribute('aria-checked')).equal('false'); + expect(await toggle.getAttribute('aria-checked')).equal('false'); // validate user action const userActions = await find.allByCssSelector( diff --git a/x-pack/test_serverless/functional/test_suites/security/index.ts b/x-pack/test_serverless/functional/test_suites/security/index.ts index cadf61fdf5eda4..fabe48960b1115 100644 --- a/x-pack/test_serverless/functional/test_suites/security/index.ts +++ b/x-pack/test_serverless/functional/test_suites/security/index.ts @@ -11,11 +11,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { describe('serverless security UI', function () { loadTestFile(require.resolve('./ftr/landing_page')); loadTestFile(require.resolve('./ftr/navigation')); - loadTestFile(require.resolve('./ftr/cases/attachment_framework')); - loadTestFile(require.resolve('./ftr/cases/view_case')); - loadTestFile(require.resolve('./ftr/cases/create_case_form')); - loadTestFile(require.resolve('./ftr/cases/configure')); - loadTestFile(require.resolve('./ftr/cases/list_view')); + loadTestFile(require.resolve('./ftr/cases')); loadTestFile(require.resolve('./advanced_settings')); loadTestFile(require.resolve('./ml')); }); diff --git a/x-pack/test_serverless/shared/lib/cases/helpers.ts b/x-pack/test_serverless/shared/lib/cases/helpers.ts index 98dcfb6d31ebc8..5cc4aa637ec43e 100644 --- a/x-pack/test_serverless/shared/lib/cases/helpers.ts +++ b/x-pack/test_serverless/shared/lib/cases/helpers.ts @@ -13,14 +13,14 @@ export const createOneCaseBeforeDeleteAllAfter = ( getService: FtrProviderContext['getService'], owner: string ) => { - const cases = getService('cases'); + const svlCases = getService('svlCases'); before(async () => { await createAndNavigateToCase(getPageObject, getService, owner); }); after(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); }); }; @@ -29,14 +29,14 @@ export const createOneCaseBeforeEachDeleteAllAfterEach = ( getService: FtrProviderContext['getService'], owner: string ) => { - const cases = getService('cases'); + const svlCases = getService('svlCases'); beforeEach(async () => { await createAndNavigateToCase(getPageObject, getService, owner); }); afterEach(async () => { - await cases.api.deleteAllCases(); + await svlCases.api.deleteAllCaseItems(); }); };