diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/document_migrator.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/document_migrator.ts index 8ca15093d58276..540f8e39b46715 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/document_migrator.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/document_migrator.ts @@ -31,11 +31,16 @@ export interface DocumentMigrateOptions { * Defaults to `false`. */ allowDowngrade?: boolean; + /** + * If specified, will migrate to the given version instead of the latest known version. + */ + targetTypeVersion?: string; } interface TransformOptions { convertNamespaceTypes?: boolean; allowDowngrade?: boolean; + targetTypeVersion?: string; } interface DocumentMigratorOptions { @@ -149,10 +154,11 @@ export class DocumentMigrator implements VersionedTransformer { */ public migrate( doc: SavedObjectUnsanitizedDoc, - { allowDowngrade = false }: DocumentMigrateOptions = {} + { allowDowngrade = false, targetTypeVersion }: DocumentMigrateOptions = {} ): SavedObjectUnsanitizedDoc { const { document } = this.transform(doc, { allowDowngrade, + targetTypeVersion, }); return document; } @@ -171,15 +177,20 @@ export class DocumentMigrator implements VersionedTransformer { private transform( doc: SavedObjectUnsanitizedDoc, - { convertNamespaceTypes = false, allowDowngrade = false }: TransformOptions = {} + { + convertNamespaceTypes = false, + allowDowngrade = false, + targetTypeVersion, + }: TransformOptions = {} ) { if (!this.migrations) { throw new Error('Migrations are not ready. Make sure prepareMigrations is called first.'); } const typeMigrations = this.migrations[doc.type]; - if (downgradeRequired(doc, typeMigrations?.latestVersion ?? {})) { + if (downgradeRequired(doc, typeMigrations?.latestVersion ?? {}, targetTypeVersion)) { const currentVersion = doc.typeMigrationVersion ?? doc.migrationVersion?.[doc.type]; - const latestVersion = this.migrations[doc.type].latestVersion[TransformType.Migrate]; + const latestVersion = + targetTypeVersion ?? this.migrations[doc.type].latestVersion[TransformType.Migrate]; if (!allowDowngrade) { throw Boom.badData( `Document "${doc.id}" belongs to a more recent version of Kibana [${currentVersion}] when the last known version is [${latestVersion}].` @@ -187,13 +198,16 @@ export class DocumentMigrator implements VersionedTransformer { } return this.transformDown(doc, { targetTypeVersion: latestVersion! }); } else { - return this.transformUp(doc, { convertNamespaceTypes }); + return this.transformUp(doc, { convertNamespaceTypes, targetTypeVersion }); } } private transformUp( doc: SavedObjectUnsanitizedDoc, - { convertNamespaceTypes }: { convertNamespaceTypes: boolean } + { + convertNamespaceTypes, + targetTypeVersion, + }: { convertNamespaceTypes: boolean; targetTypeVersion?: string } ) { if (!this.migrations) { throw new Error('Migrations are not ready. Make sure prepareMigrations is called first.'); @@ -201,6 +215,7 @@ export class DocumentMigrator implements VersionedTransformer { const pipeline = new DocumentUpgradePipeline({ document: doc, + targetTypeVersion, migrations: this.migrations, kibanaVersion: this.options.kibanaVersion, convertNamespaceTypes, diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/utils.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/utils.test.ts index 6734def19d5ce4..b66e1ea7c2d717 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/utils.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/utils.test.ts @@ -154,4 +154,40 @@ describe('downgradeRequired', () => { expect(downgradeRequired(doc, latestVersions)).toEqual(false); }); + + it('returns true when targetTypeVersion is specified and lower than the document version', () => { + const doc = createDoc({ + typeMigrationVersion: '8.0.0', + }); + const latestVersions = { + [TransformType.Migrate]: '8.5.0', + } as Record; + const targetTypeVersion = '7.9.0'; + + expect(downgradeRequired(doc, latestVersions, targetTypeVersion)).toEqual(true); + }); + + it('returns false when targetTypeVersion is specified and higher than the document version', () => { + const doc = createDoc({ + typeMigrationVersion: '8.0.0', + }); + const latestVersions = { + [TransformType.Migrate]: '7.9.0', + } as Record; + const targetTypeVersion = '8.5.0'; + + expect(downgradeRequired(doc, latestVersions, targetTypeVersion)).toEqual(false); + }); + + it('returns false when targetTypeVersion is specified and the same as the document version', () => { + const doc = createDoc({ + typeMigrationVersion: '8.0.0', + }); + const latestVersions = { + [TransformType.Migrate]: '7.9.0', + } as Record; + const targetTypeVersion = '8.0.0'; + + expect(downgradeRequired(doc, latestVersions, targetTypeVersion)).toEqual(false); + }); }); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/utils.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/utils.ts index 2082a0361336c2..a111fc663e5dac 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/utils.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/utils.ts @@ -92,13 +92,14 @@ export function transformComparator(a: Transform, b: Transform) { */ export function downgradeRequired( doc: SavedObjectUnsanitizedDoc, - latestVersions: Record + latestVersions: Record, + targetTypeVersion?: string ): boolean { const docTypeVersion = doc.typeMigrationVersion ?? doc.migrationVersion?.[doc.type]; - const latestMigrationVersion = maxVersion( - latestVersions[TransformType.Migrate], - latestVersions[TransformType.Convert] - ); + const latestMigrationVersion = + targetTypeVersion ?? + maxVersion(latestVersions[TransformType.Migrate], latestVersions[TransformType.Convert]); + if (!docTypeVersion || !latestMigrationVersion) { return false; } diff --git a/packages/core/test-helpers/core-test-helpers-model-versions/README.md b/packages/core/test-helpers/core-test-helpers-model-versions/README.md index 71aca755a14b69..e9e8ca52d76419 100644 --- a/packages/core/test-helpers/core-test-helpers-model-versions/README.md +++ b/packages/core/test-helpers/core-test-helpers-model-versions/README.md @@ -1,12 +1,44 @@ # @kbn/core-test-helpers-model-versions -Package exposing utilities for model version integration testing. +Package exposing utilities for model version testing: +- unit testing +- integration testing + +## Unit testing + +### Model version test migrator + +The `createModelVersionTestMigrator` helper allows to create a test migrator that +can be used to test model version changes between versions. + +```ts +const mySoType = someSoType(); +const migrator = createModelVersionTestMigrator({ type: mySoType }); + +const obj = createSomeSavedObject(); + +const migrated = migrator.migrate({ + document: obj, + fromVersion: 1, + toVersion: 2, +}); + +expect(migrated.properties).toEqual(myExpectedProperties); +``` + +Please refer to the code documentation for more detailed examples. + +## Integration testing + +### Model version test bed This package exposes a `createModelVersionTestBed` utility which allow simulating a testbed environment where we're in the cohabitation period between two versions, to test the interactions between two model versions of a set of SO types. -### Limitations: +Please refer to the code documentation for more detailed examples. + +*Limitations:* Because the test bed is only creating the parts of Core required to create the two SO repositories, and because we're not loading all plugins (for proper isolation), the integration diff --git a/packages/core/test-helpers/core-test-helpers-model-versions/index.ts b/packages/core/test-helpers/core-test-helpers-model-versions/index.ts index e8a5565f1dd795..9bd91d4e7d592e 100644 --- a/packages/core/test-helpers/core-test-helpers-model-versions/index.ts +++ b/packages/core/test-helpers/core-test-helpers-model-versions/index.ts @@ -6,11 +6,14 @@ * Side Public License, v 1. */ -export { createModelVersionTestBed } from './src/test_bed'; - -export type { - ModelVersionTestBed, - ModelVersionTestKit, - ModelVersionTestkitOptions, - SavedObjectTestkitDefinition, -} from './src/types'; +export { + createModelVersionTestBed, + type ModelVersionTestBed, + type ModelVersionTestKit, + type ModelVersionTestkitOptions, + type SavedObjectTestkitDefinition, +} from './src/test_bed'; +export { + createModelVersionTestMigrator, + type ModelVersionTestMigrator, +} from './src/model_version_tester'; diff --git a/packages/core/test-helpers/core-test-helpers-model-versions/src/model_version_tester.test.ts b/packages/core/test-helpers/core-test-helpers-model-versions/src/model_version_tester.test.ts new file mode 100644 index 00000000000000..6f0aa75e2ad747 --- /dev/null +++ b/packages/core/test-helpers/core-test-helpers-model-versions/src/model_version_tester.test.ts @@ -0,0 +1,192 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { schema } from '@kbn/config-schema'; +import type { SavedObjectsType, SavedObject } from '@kbn/core-saved-objects-server'; +import { createModelVersionTestMigrator } from './model_version_tester'; + +const createObject = (parts: Partial): SavedObject => { + return { + type: 'test-type', + id: 'test-id', + attributes: {}, + references: [], + ...parts, + }; +}; + +describe('modelVersionTester', () => { + const testType: SavedObjectsType = { + name: 'test-type', + hidden: false, + namespaceType: 'single', + mappings: { properties: {} }, + modelVersions: { + 1: { + changes: [], + schemas: { + forwardCompatibility: schema.object( + { + fieldV1: schema.string(), + }, + { unknowns: 'ignore' } + ), + }, + }, + 2: { + changes: [ + { + type: 'data_backfill', + backfillFn: (document) => { + return { + attributes: { + fieldAddedInV2: '2', + }, + }; + }, + }, + ], + schemas: { + forwardCompatibility: schema.object( + { + fieldV1: schema.string(), + fieldAddedInV2: schema.string(), + }, + { unknowns: 'ignore' } + ), + }, + }, + 3: { + changes: [ + { + type: 'data_backfill', + backfillFn: (doc) => { + return { + attributes: { + fieldAddedInV3: '3', + }, + }; + }, + }, + ], + schemas: { + forwardCompatibility: schema.object( + { + fieldV1: schema.string(), + fieldAddedInV2: schema.string(), + fieldAddedInV3: schema.string(), + }, + { unknowns: 'ignore' } + ), + }, + }, + 4: { + changes: [ + { + type: 'unsafe_transform', + transformFn: (doc) => { + doc.attributes = { + ...doc.attributes, + fieldUnsafelyAddedInV4: '4', + }; + + return { document: doc }; + }, + }, + ], + schemas: { + forwardCompatibility: schema.object( + { + fieldV1: schema.string(), + fieldAddedInV2: schema.string(), + fieldAddedInV3: schema.string(), + fieldUnsafelyAddedInV4: schema.string(), + }, + { unknowns: 'ignore' } + ), + }, + }, + }, + }; + + it('upward migrate one version', () => { + const migrator = createModelVersionTestMigrator({ type: testType }); + + const obj = createObject({ + attributes: { + fieldV1: 'v1', + }, + }); + + const migrated = migrator.migrate({ document: obj, fromVersion: 1, toVersion: 2 }); + + expect(migrated.attributes).toEqual({ + fieldV1: 'v1', + fieldAddedInV2: '2', + }); + }); + + it('upward migrate multiple version', () => { + const migrator = createModelVersionTestMigrator({ type: testType }); + + const obj = createObject({ + attributes: { + fieldV1: 'v1', + }, + }); + + const migrated = migrator.migrate({ document: obj, fromVersion: 1, toVersion: 4 }); + + expect(migrated.attributes).toEqual({ + fieldV1: 'v1', + fieldAddedInV2: '2', + fieldAddedInV3: '3', + fieldUnsafelyAddedInV4: '4', + }); + }); + + it('downward migrate one version', () => { + const migrator = createModelVersionTestMigrator({ type: testType }); + + const obj = createObject({ + attributes: { + fieldV1: 'v1', + fieldAddedInV2: '2', + fieldAddedInV3: '3', + fieldUnsafelyAddedInV4: '4', + }, + }); + + const migrated = migrator.migrate({ document: obj, fromVersion: 4, toVersion: 3 }); + + expect(migrated.attributes).toEqual({ + fieldV1: 'v1', + fieldAddedInV2: '2', + fieldAddedInV3: '3', + }); + }); + + it('downward migrate multiple versions', () => { + const migrator = createModelVersionTestMigrator({ type: testType }); + + const obj = createObject({ + attributes: { + fieldV1: 'v1', + fieldAddedInV2: '2', + fieldAddedInV3: '3', + fieldUnsafelyAddedInV4: '4', + }, + }); + + const migrated = migrator.migrate({ document: obj, fromVersion: 4, toVersion: 1 }); + + expect(migrated.attributes).toEqual({ + fieldV1: 'v1', + }); + }); +}); diff --git a/packages/core/test-helpers/core-test-helpers-model-versions/src/model_version_tester.ts b/packages/core/test-helpers/core-test-helpers-model-versions/src/model_version_tester.ts new file mode 100644 index 00000000000000..9aaa2fcde38479 --- /dev/null +++ b/packages/core/test-helpers/core-test-helpers-model-versions/src/model_version_tester.ts @@ -0,0 +1,113 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { loggerMock } from '@kbn/logging-mocks'; +import { getEnvOptions } from '@kbn/config-mocks'; +import { Env } from '@kbn/config'; +import { REPO_ROOT } from '@kbn/repo-info'; +import type { SavedObjectsType, SavedObject } from '@kbn/core-saved-objects-server'; +import { + modelVersionToVirtualVersion, + SavedObjectTypeRegistry, + globalSwitchToModelVersionAt, +} from '@kbn/core-saved-objects-base-server-internal'; +import { DocumentMigrator } from '@kbn/core-saved-objects-migration-server-internal'; + +const env = Env.createDefault(REPO_ROOT, getEnvOptions()); +const currentVersion = env.packageInfo.version; +const lastCoreVersion = '8.8.0'; + +/** + * Options for {@link ModelVersionTestMigrator.migrate} + */ +interface ModelVersionTestMigrateOptions { + /** + * The document to migrate. + */ + document: SavedObject; + /** + * The model version the input document should be considered in. + */ + fromVersion: number; + /** + * The model version the document should be migrated to. + */ + toVersion: number; +} + +/** + * Test utility allowing to test model version changes between versions. + */ +export interface ModelVersionTestMigrator { + /** + * Migrate the document from the provided source to destination model version. + * + * @see {@link ModelVersionTestMigrateOptions} + */ + migrate( + options: ModelVersionTestMigrateOptions + ): SavedObject; +} + +/** + * Create a {@link ModelVersionTestMigrator | test migrator} that can be used + * to test model version changes between versions. + * + * @example + * ```ts + * const mySoType = someSoType(); + * const migrator = createModelVersionTestMigrator({ type: mySoType }); + * + * const obj = createSomeSavedObject(); + * + * const migrated = migrator.migrate({ + * document: obj, + * fromVersion: 1, + * toVersion: 2, + * }); + * + * expect(migrated.properties).toEqual(myExpectedProperties); + * ``` + */ +export const createModelVersionTestMigrator = ({ + type, +}: { + type: SavedObjectsType; +}): ModelVersionTestMigrator => { + const typeRegistry = new SavedObjectTypeRegistry(); + typeRegistry.registerType({ + switchToModelVersionAt: globalSwitchToModelVersionAt, + ...type, + }); + + const logger = loggerMock.create(); + + const migrator = new DocumentMigrator({ + typeRegistry, + log: logger, + kibanaVersion: currentVersion, + }); + migrator.prepareMigrations(); + + return { + migrate: ({ document, fromVersion, toVersion }) => { + const docCopy: SavedObject = { + ...document, + coreMigrationVersion: lastCoreVersion, + typeMigrationVersion: modelVersionToVirtualVersion(fromVersion), + }; + + const migratedDoc = migrator.migrate(docCopy, { + allowDowngrade: true, + targetTypeVersion: modelVersionToVirtualVersion(toVersion), + }); + + return migratedDoc as SavedObject; + }, + }; +}; diff --git a/packages/core/test-helpers/core-test-helpers-model-versions/src/elasticsearch.ts b/packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/elasticsearch.ts similarity index 100% rename from packages/core/test-helpers/core-test-helpers-model-versions/src/elasticsearch.ts rename to packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/elasticsearch.ts diff --git a/packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/index.ts b/packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/index.ts new file mode 100644 index 00000000000000..b38390e7c38f8c --- /dev/null +++ b/packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/index.ts @@ -0,0 +1,16 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { createModelVersionTestBed } from './test_bed'; + +export type { + ModelVersionTestBed, + ModelVersionTestKit, + ModelVersionTestkitOptions, + SavedObjectTestkitDefinition, +} from './types'; diff --git a/packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed.ts b/packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/test_bed.ts similarity index 100% rename from packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed.ts rename to packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/test_bed.ts diff --git a/packages/core/test-helpers/core-test-helpers-model-versions/src/test_kit.ts b/packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/test_kit.ts similarity index 100% rename from packages/core/test-helpers/core-test-helpers-model-versions/src/test_kit.ts rename to packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/test_kit.ts diff --git a/packages/core/test-helpers/core-test-helpers-model-versions/src/type_registry.ts b/packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/type_registry.ts similarity index 100% rename from packages/core/test-helpers/core-test-helpers-model-versions/src/type_registry.ts rename to packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/type_registry.ts diff --git a/packages/core/test-helpers/core-test-helpers-model-versions/src/types.ts b/packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/types.ts similarity index 100% rename from packages/core/test-helpers/core-test-helpers-model-versions/src/types.ts rename to packages/core/test-helpers/core-test-helpers-model-versions/src/test_bed/types.ts diff --git a/packages/core/test-helpers/core-test-helpers-model-versions/tsconfig.json b/packages/core/test-helpers/core-test-helpers-model-versions/tsconfig.json index fe08f1cce0cea3..89bf3a0c97d1b7 100644 --- a/packages/core/test-helpers/core-test-helpers-model-versions/tsconfig.json +++ b/packages/core/test-helpers/core-test-helpers-model-versions/tsconfig.json @@ -33,5 +33,7 @@ "@kbn/doc-links", "@kbn/core-doc-links-server", "@kbn/core-node-server", + "@kbn/config-schema", + "@kbn/logging-mocks", ] } diff --git a/src/plugins/telemetry/server/routes/telemetry_config.ts b/src/plugins/telemetry/server/routes/telemetry_config.ts index d62566bdc3563a..7c056b0cfd5195 100644 --- a/src/plugins/telemetry/server/routes/telemetry_config.ts +++ b/src/plugins/telemetry/server/routes/telemetry_config.ts @@ -85,7 +85,8 @@ export function registerTelemetryConfigRoutes({ optIn: schema.oneOf([schema.boolean(), schema.literal(null)]), sendUsageFrom: schema.oneOf([schema.literal('server'), schema.literal('browser')]), telemetryNotifyUserAboutOptInDefault: schema.boolean(), - labels: labelsSchema, + // Declare the `serverless` label as optional in both offerings while we fix https://github.com/elastic/kibana/issues/167862 + labels: labelsSchema.extends({ serverless: schema.maybe(schema.string()) }), }), }, }, diff --git a/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.test.tsx b/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.test.tsx index 909e3029db48df..edcff40f4763a1 100644 --- a/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.test.tsx +++ b/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.test.tsx @@ -224,6 +224,49 @@ describe('getTopNavConfig', () => { ] `); }); + + test('navigates to origin app and path on cancel', async () => { + const vis = { + savedVis: { + id: 'test', + sharingSavedObjectProps: { + outcome: 'conflict', + aliasTargetId: 'alias_id', + }, + }, + vis: { + type: { + title: 'TSVB', + }, + }, + } as VisualizeEditorVisInstance; + const mockNavigateToApp = jest.fn(); + const topNavLinks = getTopNavConfig( + { + hasUnsavedChanges: false, + setHasUnsavedChanges: jest.fn(), + hasUnappliedChanges: false, + onOpenInspector: jest.fn(), + originatingApp: 'testApp', + originatingPath: '/testPath', + setOriginatingApp: jest.fn(), + visInstance: vis, + stateContainer, + visualizationIdFromUrl: undefined, + stateTransfer: createEmbeddableStateTransferMock(), + } as unknown as TopNavConfigParams, + { + ...services, + application: { navigateToApp: mockNavigateToApp }, + } as unknown as VisualizeServices + ); + + const executionFunction = topNavLinks.find(({ id }) => id === 'cancel')?.run; + const mockAnchorElement = document.createElement('div'); + await executionFunction?.(mockAnchorElement); + expect(mockNavigateToApp).toHaveBeenCalledWith('testApp', { path: '/testPath' }); + }); + test('returns correct links for by reference visualization', () => { const vis = { savedVis: { diff --git a/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx b/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx index 49ebc45833376a..064e281f8c2698 100644 --- a/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx +++ b/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx @@ -258,7 +258,7 @@ export const getTopNavConfig = ( const navigateToOriginatingApp = () => { if (originatingApp) { - application.navigateToApp(originatingApp); + application.navigateToApp(originatingApp, { path: originatingPath }); } }; diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx index 75dadbc2f65585..c13682800707a6 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/nodes_page.tsx @@ -186,15 +186,17 @@ export const ElasticsearchNodesPage: React.FC = ({ clusters }) = ); }; -function sortNodeRoles(roles: string[] | undefined): string[] | undefined { +function sortNodeRoles(roles: string[] | string | undefined): string[] | undefined { if (!roles) { return undefined; } - if (roles.length === 0) { + const rolesList = Array.isArray(roles) ? roles : [roles]; + + if (rolesList.length === 0) { return []; } - const rolesAsSet = new Set(roles); + const rolesAsSet = new Set(rolesList); return rolesByImportance.filter((role) => rolesAsSet.has(role)); } diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts index dba23548e5d206..7916458c29ba04 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts @@ -25,7 +25,7 @@ import { } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; - +import { openRuleManagementPageViaBreadcrumbs } from '../../../tasks/rules_management'; import { CREATE_RULE_URL } from '../../../urls/navigation'; // TODO: https://github.com/elastic/kibana/issues/161539 @@ -60,6 +60,7 @@ describe( fillScheduleRuleAndContinue(rule); fillRuleAction(actions); createAndEnableRule(); + openRuleManagementPageViaBreadcrumbs(); goToRuleDetailsOf(rule.name); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/common_flows.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/common_flows.cy.ts index aa9ef9cd975bd3..dffb50ab6dae64 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/common_flows.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/common_flows.cy.ts @@ -21,7 +21,7 @@ import { RULE_NAME_HEADER } from '../../../screens/rule_details'; import { createTimeline } from '../../../tasks/api_calls/timelines'; import { deleteAlertsAndRules } from '../../../tasks/common'; import { - createAndEnableRuleOnly, + createAndEnableRule, expandAdvancedSettings, fillCustomInvestigationFields, fillDescription, @@ -93,8 +93,9 @@ describe('Common rule creation flows', { tags: ['@ess', '@serverless'] }, () => cy.get(ABOUT_CONTINUE_BTN).should('exist').click(); cy.get(SCHEDULE_CONTINUE_BUTTON).click(); - createAndEnableRuleOnly(); + createAndEnableRule(); + // UI redirects to rule creation page of a created rule cy.get(RULE_NAME_HEADER).should('contain', ruleFields.ruleName); }); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts index 07f0b8535d8353..e4bb4b2bfba830 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts @@ -10,10 +10,10 @@ import { RULE_NAME_HEADER } from '../../../screens/rule_details'; import { deleteAlertsAndRules } from '../../../tasks/common'; import { - createAndEnableRuleOnly, fillScheduleRuleAndContinue, fillAboutRuleMinimumAndContinue, fillDefineCustomRuleAndContinue, + createRuleWithoutEnabling, } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; @@ -37,7 +37,7 @@ describe('Create custom query rule', { tags: ['@ess', '@serverless'] }, () => { fillDefineCustomRuleAndContinue(rule); fillAboutRuleMinimumAndContinue(rule); fillScheduleRuleAndContinue(rule); - createAndEnableRuleOnly(); + createRuleWithoutEnabling(); cy.log('Asserting we have a new rule created'); cy.get(RULE_NAME_HEADER).should('contain', rule.name); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts index 5c23d4dab1b3a5..32eb50ef25d532 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts @@ -64,6 +64,7 @@ import { import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; +import { openRuleManagementPageViaBreadcrumbs } from '../../../tasks/rules_management'; import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details'; import { CREATE_RULE_URL } from '../../../urls/navigation'; @@ -97,6 +98,7 @@ describe('Custom query rules', { tags: ['@ess', '@serverless', '@brokenInServerl fillAboutRuleAndContinue(rule); fillScheduleRuleAndContinue(rule); createAndEnableRule(); + openRuleManagementPageViaBreadcrumbs(); cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); @@ -161,6 +163,7 @@ describe('Custom query rules', { tags: ['@ess', '@serverless', '@brokenInServerl fillScheduleRuleAndContinue(rule); createRuleWithoutEnabling(); + openRuleManagementPageViaBreadcrumbs(); goToRuleDetailsOf(rule.name); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts index a2abf05ecab40c..c0498bdfcbcb11 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts @@ -43,9 +43,9 @@ import { visitRuleDetailsPage, } from '../../../tasks/rule_details'; import { createRule } from '../../../tasks/api_calls/rules'; - import { CREATE_RULE_URL } from '../../../urls/navigation'; import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management'; +import { openRuleManagementPageViaBreadcrumbs } from '../../../tasks/rules_management'; const savedQueryName = 'custom saved query'; const savedQueryQuery = 'process.name: test'; @@ -87,6 +87,7 @@ describe('Saved query rules', { tags: ['@ess', '@serverless', '@brokenInServerle fillScheduleRuleAndContinue(rule); cy.intercept('POST', '/api/detection_engine/rules').as('savedQueryRule'); createAndEnableRule(); + openRuleManagementPageViaBreadcrumbs(); cy.wait('@savedQueryRule').then(({ response }) => { // created rule should have saved_query type diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/esql_rule_create.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/esql_rule_create.cy.ts index 857043cd0a84d1..386b6c919a5e6c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/esql_rule_create.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/esql_rule_create.cy.ts @@ -31,8 +31,8 @@ import { selectEsqlRuleType, getDefineContinueButton, fillEsqlQueryBar, - pressRuleCreateBtn, fillAboutSpecificEsqlRuleAndContinue, + createRuleWithoutEnabling, } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; @@ -68,7 +68,7 @@ describe.skip('Detection ES|QL rules, creation', { tags: ['@ess'] }, () => { fillDefineEsqlRuleAndContinue(rule); fillAboutRuleAndContinue(rule); fillScheduleRuleAndContinue(rule); - pressRuleCreateBtn(); + createRuleWithoutEnabling(); // ensures after rule save ES|QL rule is displayed cy.get(RULE_NAME_HEADER).should('contain', `${rule.name}`); @@ -91,7 +91,7 @@ describe.skip('Detection ES|QL rules, creation', { tags: ['@ess'] }, () => { fillDefineEsqlRuleAndContinue(rule); fillAboutSpecificEsqlRuleAndContinue({ ...rule, rule_name_override: 'test_id' }); fillScheduleRuleAndContinue(rule); - pressRuleCreateBtn(); + createRuleWithoutEnabling(); // ensure rule name override is displayed on details page getDetails(RULE_NAME_OVERRIDE_DETAILS).should('have.text', 'test_id'); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts index 1984ef5a5eda4a..d169d44f197611 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts @@ -54,7 +54,7 @@ import { } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; - +import { openRuleManagementPageViaBreadcrumbs } from '../../../tasks/rules_management'; import { CREATE_RULE_URL } from '../../../urls/navigation'; // TODO: https://github.com/elastic/kibana/issues/161539 @@ -85,6 +85,7 @@ describe('EQL rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, fillAboutRuleAndContinue(rule); fillScheduleRuleAndContinue(rule); createAndEnableRule(); + openRuleManagementPageViaBreadcrumbs(); cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); @@ -162,6 +163,7 @@ describe('EQL rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, fillAboutRuleAndContinue(rule); fillScheduleRuleAndContinue(rule); createAndEnableRule(); + openRuleManagementPageViaBreadcrumbs(); goToRuleDetailsOf(rule.name); waitForTheRuleToBeExecuted(); waitForAlertsToPopulate(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts index 8d581d69edb950..0d1466a7551852 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts @@ -109,9 +109,9 @@ import { waitForTheRuleToBeExecuted, visitRuleDetailsPage, } from '../../../tasks/rule_details'; - import { CREATE_RULE_URL } from '../../../urls/navigation'; import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management'; +import { openRuleManagementPageViaBreadcrumbs } from '../../../tasks/rules_management'; const DEFAULT_THREAT_MATCH_QUERY = '@timestamp >= "now-30d/d"'; @@ -435,6 +435,7 @@ describe('indicator match', { tags: ['@ess', '@serverless', '@brokenInServerless fillAboutRuleAndContinue(rule); fillScheduleRuleAndContinue(rule); createAndEnableRule(); + openRuleManagementPageViaBreadcrumbs(); cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/machine_learning_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/machine_learning_rule.cy.ts index 38f977f6c309f0..7e73310433df1f 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/machine_learning_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/machine_learning_rule.cy.ts @@ -51,7 +51,7 @@ import { } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; - +import { openRuleManagementPageViaBreadcrumbs } from '../../../tasks/rules_management'; import { CREATE_RULE_URL } from '../../../urls/navigation'; // TODO: https://github.com/elastic/kibana/issues/161539 @@ -78,6 +78,7 @@ describe('Machine Learning rules', { tags: ['@ess', '@serverless', '@brokenInSer fillAboutRuleAndContinue(mlRule); fillScheduleRuleAndContinue(mlRule); createAndEnableRule(); + openRuleManagementPageViaBreadcrumbs(); cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts index 91a815823ad419..53334bdc80541c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts @@ -56,8 +56,8 @@ import { } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; - import { CREATE_RULE_URL } from '../../../urls/navigation'; +import { openRuleManagementPageViaBreadcrumbs } from '../../../tasks/rules_management'; // TODO: https://github.com/elastic/kibana/issues/161539 describe('New Terms rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { @@ -86,6 +86,7 @@ describe('New Terms rules', { tags: ['@ess', '@serverless', '@brokenInServerless fillAboutRuleAndContinue(rule); fillScheduleRuleAndContinue(rule); createAndEnableRule(); + openRuleManagementPageViaBreadcrumbs(); cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts index b438d43a256363..6290583e82d827 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts @@ -59,8 +59,8 @@ import { import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details'; - import { CREATE_RULE_URL } from '../../../urls/navigation'; +import { openRuleManagementPageViaBreadcrumbs } from '../../../tasks/rules_management'; // TODO: https://github.com/elastic/kibana/issues/161539 describe('Rules override', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { @@ -82,6 +82,7 @@ describe('Rules override', { tags: ['@ess', '@serverless', '@brokenInServerless' fillAboutRuleWithOverrideAndContinue(rule); fillScheduleRuleAndContinue(rule); createAndEnableRule(); + openRuleManagementPageViaBreadcrumbs(); cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts index 1b4122606c1027..1928fd8098f916 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts @@ -56,11 +56,10 @@ import { } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; - +import { openRuleManagementPageViaBreadcrumbs } from '../../../tasks/rules_management'; import { CREATE_RULE_URL } from '../../../urls/navigation'; -// TODO: https://github.com/elastic/kibana/issues/161539 -describe('Threshold rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { +describe('Threshold rules', { tags: ['@ess', '@serverless'] }, () => { const rule = getNewThresholdRule(); const expectedUrls = rule.references?.join(''); const expectedFalsePositives = rule.false_positives?.join(''); @@ -84,6 +83,7 @@ describe('Threshold rules', { tags: ['@ess', '@serverless', '@brokenInServerless fillAboutRuleAndContinue(rule); fillScheduleRuleAndContinue(rule); createAndEnableRule(); + openRuleManagementPageViaBreadcrumbs(); cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)'); diff --git a/x-pack/test/security_solution_cypress/cypress/screens/breadcrumbs.ts b/x-pack/test/security_solution_cypress/cypress/screens/breadcrumbs.ts new file mode 100644 index 00000000000000..52910ec9b5f299 --- /dev/null +++ b/x-pack/test/security_solution_cypress/cypress/screens/breadcrumbs.ts @@ -0,0 +1,11 @@ +/* + * 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. + */ + +export const RULE_MANAGEMENT_PAGE_BREADCRUMB = + '[data-test-subj~="breadcrumb"][title="Detection rules (SIEM)"]'; + +export const LAST_BREADCRUMB = `[data-test-subj~="breadcrumb"][data-test-subj~="last"]`; diff --git a/x-pack/test/security_solution_cypress/cypress/screens/rule_details.ts b/x-pack/test/security_solution_cypress/cypress/screens/rule_details.ts index 4759c3cd2b08c9..fd98e38f9cc329 100644 --- a/x-pack/test/security_solution_cypress/cypress/screens/rule_details.ts +++ b/x-pack/test/security_solution_cypress/cypress/screens/rule_details.ts @@ -146,8 +146,5 @@ export const THREAT_TECHNIQUE = '[data-test-subj="threatTechniqueLink"]'; export const THREAT_SUBTECHNIQUE = '[data-test-subj="threatSubtechniqueLink"]'; -export const BACK_TO_RULES_TABLE = - '[data-test-subj="breadcrumbs"] a[title="Detection rules (SIEM)"]'; - export const HIGHLIGHTED_ROWS_IN_TABLE = '[data-test-subj="euiDataGridBody"] .alertsTableHighlightedRow'; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/create_new_rule.ts b/x-pack/test/security_solution_cypress/cypress/tasks/create_new_rule.ts index a6eb63fe6318be..9faf5fa81ec004 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/create_new_rule.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/create_new_rule.ts @@ -127,33 +127,20 @@ import { ALERTS_TABLE_COUNT } from '../screens/timeline'; import { TIMELINE } from '../screens/timelines'; import { EUI_FILTER_SELECT_ITEM, COMBO_BOX_INPUT } from '../screens/common/controls'; import { ruleFields } from '../data/detection_engine'; -import { BACK_TO_RULES_TABLE } from '../screens/rule_details'; import { waitForAlerts } from './alerts'; import { refreshPage } from './security_header'; import { EMPTY_ALERT_TABLE } from '../screens/alerts'; -export const createAndEnableRuleOnly = () => { - cy.get(CREATE_AND_ENABLE_BTN).click({ force: true }); - cy.get(CREATE_AND_ENABLE_BTN).should('not.exist'); -}; - export const createAndEnableRule = () => { - cy.get(CREATE_AND_ENABLE_BTN).click({ force: true }); + cy.get(CREATE_AND_ENABLE_BTN).click(); cy.get(CREATE_AND_ENABLE_BTN).should('not.exist'); - cy.get(BACK_TO_RULES_TABLE).click({ force: true }); }; -export const pressRuleCreateBtn = () => { +export const createRuleWithoutEnabling = () => { cy.get(CREATE_WITHOUT_ENABLING_BTN).click(); cy.get(CREATE_WITHOUT_ENABLING_BTN).should('not.exist'); }; -export const createRuleWithoutEnabling = () => { - pressRuleCreateBtn(); - cy.get(BACK_TO_RULES_TABLE).click({ force: true }); - cy.get(BACK_TO_RULES_TABLE).should('not.exist'); -}; - export const fillAboutRule = (rule: RuleCreateProps) => { cy.get(RULE_NAME_INPUT).clear({ force: true }); cy.get(RULE_NAME_INPUT).type(rule.name, { force: true }); diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/prebuilt_rules.ts b/x-pack/test/security_solution_cypress/cypress/tasks/prebuilt_rules.ts index e6945c551c9655..7b58dda17015fb 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/prebuilt_rules.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/prebuilt_rules.ts @@ -22,7 +22,7 @@ import { UPGRADE_ALL_RULES_BUTTON, UPGRADE_SELECTED_RULES_BUTTON, } from '../screens/alerts_detection_rules'; -import { BACK_TO_RULES_TABLE } from '../screens/rule_details'; +import { RULE_MANAGEMENT_PAGE_BREADCRUMB } from '../screens/breadcrumbs'; import type { SAMPLE_PREBUILT_RULE } from './api_calls/prebuilt_rules'; export const addElasticRulesButtonClick = () => { @@ -108,7 +108,7 @@ const assertInstallationSuccessOrFailure = ( cy.get(ADD_ELASTIC_RULES_TABLE).contains(rule['security-rule'].name); } } else { - cy.get(BACK_TO_RULES_TABLE).click(); + cy.get(RULE_MANAGEMENT_PAGE_BREADCRUMB).click(); for (const rule of rules) { cy.get(RULES_MANAGEMENT_TABLE).contains(rule['security-rule'].name); } diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/rule_details.ts b/x-pack/test/security_solution_cypress/cypress/tasks/rule_details.ts index 9264b17fec0812..a81be48d229e90 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/rule_details.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/rule_details.ts @@ -7,6 +7,7 @@ import { ROLES } from '@kbn/security-solution-plugin/common/test'; import type { Exception } from '../objects/exception'; +import { RULE_MANAGEMENT_PAGE_BREADCRUMB } from '../screens/breadcrumbs'; import { PAGE_CONTENT_SPINNER } from '../screens/common/page'; import { RULE_STATUS } from '../screens/create_new_rule'; import { @@ -30,7 +31,6 @@ import { EDIT_EXCEPTION_BTN, ENDPOINT_EXCEPTIONS_TAB, EDIT_RULE_SETTINGS_LINK, - BACK_TO_RULES_TABLE, EXCEPTIONS_TAB_EXPIRED_FILTER, EXCEPTIONS_TAB_ACTIVE_FILTER, RULE_NAME_HEADER, @@ -152,7 +152,7 @@ export const waitForTheRuleToBeExecuted = () => { }; export const goBackToRulesTable = () => { - cy.get(BACK_TO_RULES_TABLE).click(); + cy.get(RULE_MANAGEMENT_PAGE_BREADCRUMB).click(); }; export const getDetails = (title: string | RegExp) => diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/rules_management.ts b/x-pack/test/security_solution_cypress/cypress/tasks/rules_management.ts index 6c6bbfb1564e2b..5f795ce97d524d 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/rules_management.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/rules_management.ts @@ -6,6 +6,7 @@ */ import type { ROLES } from '@kbn/security-solution-plugin/common/test'; +import { LAST_BREADCRUMB, RULE_MANAGEMENT_PAGE_BREADCRUMB } from '../screens/breadcrumbs'; import { RULES_MANAGEMENT_URL } from '../urls/rules_management'; import { resetRulesTableState } from './common'; import { visit } from './navigation'; @@ -14,3 +15,9 @@ export function visitRulesManagementTable(role?: ROLES): void { resetRulesTableState(); // Clear persistent rules filter data before page loading visit(RULES_MANAGEMENT_URL, { role }); } + +export function openRuleManagementPageViaBreadcrumbs(): void { + cy.log('Navigate back to rules table via breadcrumbs'); + cy.get(RULE_MANAGEMENT_PAGE_BREADCRUMB).not(LAST_BREADCRUMB).click(); + cy.get(RULE_MANAGEMENT_PAGE_BREADCRUMB).filter(LAST_BREADCRUMB).should('exist'); +} diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/telemetry_config.ts b/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/telemetry_config.ts index 6ef34b9a0966c7..d803cf06b4c521 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/telemetry_config.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/telemetry_config.ts @@ -25,7 +25,7 @@ export default function telemetryConfigTest({ getService }: FtrProviderContext) it('GET should get the default config', async () => { await supertest .get('/api/telemetry/v2/config') - .set(svlCommonApi.getInternalRequestHeader()) + .set(svlCommonApi.getCommonRequestHeader()) .expect(200, baseConfig); }); @@ -39,7 +39,7 @@ export default function telemetryConfigTest({ getService }: FtrProviderContext) await supertest .get('/api/telemetry/v2/config') - .set(svlCommonApi.getInternalRequestHeader()) + .set(svlCommonApi.getCommonRequestHeader()) .expect(200, { ...baseConfig, labels: { diff --git a/x-pack/test_serverless/api_integration/test_suites/security/telemetry/telemetry_config.ts b/x-pack/test_serverless/api_integration/test_suites/security/telemetry/telemetry_config.ts index 5df1da84a8dbfb..2be964bc579bae 100644 --- a/x-pack/test_serverless/api_integration/test_suites/security/telemetry/telemetry_config.ts +++ b/x-pack/test_serverless/api_integration/test_suites/security/telemetry/telemetry_config.ts @@ -25,7 +25,7 @@ export default function telemetryConfigTest({ getService }: FtrProviderContext) it('GET should get the default config', async () => { await supertest .get('/api/telemetry/v2/config') - .set(svlCommonApi.getInternalRequestHeader()) + .set(svlCommonApi.getCommonRequestHeader()) .expect(200, baseConfig); }); @@ -39,7 +39,7 @@ export default function telemetryConfigTest({ getService }: FtrProviderContext) await supertest .get('/api/telemetry/v2/config') - .set(svlCommonApi.getInternalRequestHeader()) + .set(svlCommonApi.getCommonRequestHeader()) .expect(200, { ...baseConfig, labels: { diff --git a/yarn.lock b/yarn.lock index 67674a57416eff..800c37edf20c46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27223,14 +27223,7 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semve resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.0, semver@^7.5.2, semver@^7.5.3: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== - dependencies: - lru-cache "^6.0.0" - -semver@^7.5.4: +semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.0, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==