Skip to content

Commit

Permalink
[8.x] [Fleet] Add cypress test against space awareness (#195372) (#19…
Browse files Browse the repository at this point in the history
…5873)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Fleet] Add cypress test against space awareness
(#195372)](#195372)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Nicolas
Chaulet","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-10-11T07:19:21Z","message":"[Fleet]
Add cypress test against space awareness
(#195372)","sha":"5b697499978170937d8c0280b0cf184ee84b57ab","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Fleet","v9.0.0","backport:prev-minor","v8.16.0"],"number":195372,"url":"https://github.com/elastic/kibana/pull/195372","mergeCommit":{"message":"[Fleet]
Add cypress test against space awareness
(#195372)","sha":"5b697499978170937d8c0280b0cf184ee84b57ab"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/195372","number":195372,"mergeCommit":{"message":"[Fleet]
Add cypress test against space awareness
(#195372)","sha":"5b697499978170937d8c0280b0cf184ee84b57ab"}},{"branch":"8.x","label":"v8.16.0","labelRegex":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
nchaulet and elasticmachine authored Oct 15, 2024
1 parent c04b25b commit 89f85ab
Show file tree
Hide file tree
Showing 18 changed files with 303 additions and 14 deletions.
2 changes: 2 additions & 0 deletions .buildkite/ftr_platform_stateful_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ disabled:

# Cypress configs, for now these are still run manually
- x-pack/test/fleet_cypress/cli_config.ts
- x-pack/test/fleet_cypress/cli_config.space_awareness.ts
- x-pack/test/fleet_cypress/config.ts
- x-pack/test/fleet_cypress/config.space_awareness.ts
- x-pack/test/fleet_cypress/visual_config.ts

defaultQueue: 'n2-4-spot'
Expand Down
2 changes: 1 addition & 1 deletion .buildkite/scripts/steps/functional/fleet_cypress.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ echo "--- Fleet Cypress tests (Chrome)"
cd x-pack/plugins/fleet

set +e
yarn cypress:run:reporter; status=$?; yarn junit:merge || :; exit $status
yarn cypress:run:reporter; status=$?; yarn cypress_space_awareness:run:reporter; space_status=$?; yarn junit:merge || :; [ "$status" -ne 0 ] && exit $status || [ "$space_status" -ne 0 ] && exit $space_status || exit 0
49 changes: 49 additions & 0 deletions x-pack/plugins/fleet/cypress.config.space_awareness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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 { defineCypressConfig } from '@kbn/cypress-config';

// eslint-disable-next-line import/no-default-export
export default defineCypressConfig({
defaultCommandTimeout: 60000,
requestTimeout: 60000,
responseTimeout: 60000,
execTimeout: 120000,
pageLoadTimeout: 120000,

retries: {
runMode: 2,
},

env: {
grepFilterSpecs: false,
},

screenshotsFolder: '../../../target/kibana-fleet/cypress/screenshots',
trashAssetsBeforeRuns: false,
video: false,
videosFolder: '../../../target/kibana-fleet/cypress/videos',
viewportHeight: 900,
viewportWidth: 1440,
screenshotOnRunFailure: true,

e2e: {
baseUrl: 'http://localhost:5601',

experimentalRunAllSpecs: true,
experimentalMemoryManagement: true,
numTestsKeptInMemory: 3,

specPattern: './cypress/e2e/space_awareness/**/*.cy.ts',
supportFile: './cypress/support/e2e.ts',

setupNodeEvents(on, config) {
// eslint-disable-next-line @typescript-eslint/no-var-requires, @kbn/imports/no_boundary_crossing
return require('./cypress/plugins')(on, config);
},
},
});
1 change: 1 addition & 0 deletions x-pack/plugins/fleet/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export default defineCypressConfig({

specPattern: './cypress/e2e/**/*.cy.ts',
supportFile: './cypress/support/e2e.ts',
excludeSpecPattern: './cypress/e2e/space_awareness/**/*.cy.ts',

setupNodeEvents(on, config) {
// eslint-disable-next-line @typescript-eslint/no-var-requires, @kbn/imports/no_boundary_crossing
Expand Down
75 changes: 75 additions & 0 deletions x-pack/plugins/fleet/cypress/e2e/space_awareness/policies.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* 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 {
ADD_AGENT_POLICY_BTN,
AGENT_POLICIES_TABLE,
AGENT_POLICY_CREATE_AGENT_POLICY_NAME_FIELD,
AGENT_POLICY_DETAILS_PAGE,
AGENT_POLICY_FLYOUT_CREATE_BUTTON,
AGENT_POLICY_SYSTEM_MONITORING_CHECKBOX,
} from '../../screens/fleet';
import { login } from '../../tasks/login';
import { createSpaces, enableSpaceAwareness } from '../../tasks/spaces';
import { cleanupAgentPolicies } from '../../tasks/cleanup';

describe('Space aware policies creation', { testIsolation: false }, () => {
before(() => {
enableSpaceAwareness();
createSpaces();
cleanupAgentPolicies();
cleanupAgentPolicies('test');
login();
});

beforeEach(() => {
cy.intercept('GET', /\/api\/fleet\/agent_policies/).as('getAgentPolicies');
cy.intercept('GET', /\/internal\/fleet\/agent_policies_spaces/).as('getAgentPoliciesSpaces');
});

const POLICY_NAME = `Policy 1 space test`;
const NO_AGENT_POLICIES = 'No agent policies';
it('should allow to create an agent policy in the test space', () => {
cy.visit('/s/test/app/fleet/policies');

cy.getBySel(ADD_AGENT_POLICY_BTN).click();
cy.getBySel(AGENT_POLICY_CREATE_AGENT_POLICY_NAME_FIELD).type(POLICY_NAME);
cy.getBySel(AGENT_POLICY_SYSTEM_MONITORING_CHECKBOX).uncheck();

cy.getBySel(AGENT_POLICY_FLYOUT_CREATE_BUTTON).click();
cy.getBySel(AGENT_POLICIES_TABLE).contains(POLICY_NAME);
});

it('the created policy should not be visible in the default space', () => {
cy.visit('/app/fleet/policies');
cy.wait('@getAgentPolicies');
cy.getBySel(AGENT_POLICIES_TABLE).contains(NO_AGENT_POLICIES);
});

it('should allow to update that policy to belong to both test and default space', () => {
cy.visit('/s/test/app/fleet/policies');
cy.getBySel(AGENT_POLICIES_TABLE).contains(POLICY_NAME).click();

cy.getBySel(AGENT_POLICY_DETAILS_PAGE.SETTINGS_TAB).click();
cy.wait('@getAgentPoliciesSpaces');
cy.getBySel(AGENT_POLICY_DETAILS_PAGE.SPACE_SELECTOR_COMBOBOX).click().type('default{enter}');

cy.getBySel(AGENT_POLICY_DETAILS_PAGE.SAVE_BUTTON).click();
});

it('the policy should be visible in the test space', () => {
cy.visit('/s/test/app/fleet/policies');
cy.wait('@getAgentPolicies');
cy.getBySel(AGENT_POLICIES_TABLE).contains(POLICY_NAME);
});

it('the policy should be visible in the default space', () => {
cy.visit('/app/fleet/policies');
cy.wait('@getAgentPolicies');
cy.getBySel(AGENT_POLICIES_TABLE).contains(POLICY_NAME);
});
});
5 changes: 5 additions & 0 deletions x-pack/plugins/fleet/cypress/screens/fleet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export const AGENT_POLICY_CREATE_AGENT_POLICY_NAME_FIELD = 'createAgentPolicyNam
export const AGENT_POLICIES_FLYOUT_ADVANCED_DEFAULT_NAMESPACE_HEADER = 'defaultNamespaceHeader';
export const AGENT_POLICY_FLYOUT_CREATE_BUTTON = 'createAgentPolicyFlyoutBtn';

export const AGENT_POLICIES_TABLE = 'agentPoliciesTable';

export const ENROLLMENT_TOKENS = {
CREATE_TOKEN_BUTTON: 'createEnrollmentTokenButton',
CREATE_TOKEN_MODAL_NAME_FIELD: 'createEnrollmentTokenNameField',
Expand Down Expand Up @@ -241,4 +243,7 @@ export const API_KEYS = {

export const AGENT_POLICY_DETAILS_PAGE = {
ADD_AGENT_LINK: 'addAgentLink',
SETTINGS_TAB: 'agentPolicySettingsTab',
SPACE_SELECTOR_COMBOBOX: 'spaceSelectorComboBox',
SAVE_BUTTON: 'agentPolicyDetailsSaveButton',
};
24 changes: 13 additions & 11 deletions x-pack/plugins/fleet/cypress/tasks/cleanup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@

import { request } from './common';

export function cleanupAgentPolicies() {
request({ url: '/api/fleet/agent_policies' }).then((response: any) => {
response.body.items
.filter((policy: any) => policy.agents === 0)
.forEach((policy: any) => {
request({
method: 'POST',
url: '/api/fleet/agent_policies/delete',
body: { agentPolicyId: policy.id },
export function cleanupAgentPolicies(spaceId?: string) {
request({ url: `${spaceId ? `/s/${spaceId}` : ''}/api/fleet/agent_policies` }).then(
(response: any) => {
response.body.items
.filter((policy: any) => policy.agents === 0)
.forEach((policy: any) => {
request({
method: 'POST',
url: `${spaceId ? `/s/${spaceId}` : ''}/api/fleet/agent_policies/delete`,
body: { agentPolicyId: policy.id },
});
});
});
});
}
);
}

export function unenrollAgent() {
Expand Down
17 changes: 17 additions & 0 deletions x-pack/plugins/fleet/cypress/tasks/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ export const COMMON_API_HEADERS = Object.freeze({
'Elastic-Api-Version': API_VERSIONS.public.v1,
});

export const COMMON_INTERNAL_API_HEADERS = Object.freeze({
'kbn-xsrf': 'cypress',
'x-elastic-internal-origin': 'fleet',
'Elastic-Api-Version': API_VERSIONS.internal.v1,
});

// Replaces request - adds baseline authentication + global headers
export const request = <T = unknown>({
headers,
Expand All @@ -40,6 +46,17 @@ export const request = <T = unknown>({
});
};

export const internalRequest = <T = unknown>({
headers,
...options
}: Partial<Cypress.RequestOptions>): Cypress.Chainable<Cypress.Response<T>> => {
return cy.request<T>({
auth: API_AUTH,
headers: { ...COMMON_INTERNAL_API_HEADERS, ...headers },
...options,
});
};

/**
* For all the new features tours we show in the app, this method disables them
* by setting their configs in the local storage. It prevents the tours from appearing
Expand Down
38 changes: 38 additions & 0 deletions x-pack/plugins/fleet/cypress/tasks/spaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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 { request, internalRequest } from './common';

export function enableSpaceAwareness() {
return internalRequest({
url: '/internal/fleet/enable_space_awareness',
failOnStatusCode: false,
method: 'POST',
});
}

export function createSpaces() {
return request({
url: '/api/spaces/space',
failOnStatusCode: false,
method: 'POST',
body: {
id: 'test',
name: 'Test',
description: 'Test space',
color: '#aabbcc',
initials: 'TE',
disabledFeatures: [],
imageUrl:
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABACAYAAABC6cT1AAAGf0lEQVRoQ+3abYydRRUH8N882xYo0IqagEVjokQJKAiKBjXExC9G/aCkGowCIghCkRcrVSSKIu/FEiqgGL6gBIlAYrAqUTH6hZgQFVEMKlQFfItWoQWhZe8z5uzMLdvbfbkLxb13d+fbvfe588x/zpn/+Z9zJpmnI81T3BaAzzfLL1h8weLzZAcWXH2eGHo7zAWLL1h8nuzAjFw9G1N6Kzq8HnuM36MR8iibF3Fv4q+7cv8yDV6K13bYq2furSP8Ag8ncr/vnSnwRViJT2GfCV7yL1yHGxLb+l3EdM9lluNEnIC9xz+f2ZL4Er6Z2DrdXN3fZwp8CU7OfDHxggle8lTLbQ1nJ/7Z7yKmey5zYGZt4h2IzR8/trRc2PDlxJPTzfVcgJ+CC0wMPOa9F6cm7up3EVM9V9386MxliVdM8GwAv6hh/awCz/w7lY25OtF5ruBz4ZLP42NYNrDAFbC3YPWuILnMAfgq3oaRQQYea/stViV+sgssvjKzLvGySeaaNVfP4d7Btokgvxj/bblgpueuF1hmWcyTCmfE3J3M1lTcv0vMswM88zR+jpw4osu6me8kzkpsfLZWzxyRuabO22buxxOJ12FxnXfWgEe83pB5sOE47BsLymzscOoi7nw2JJfZreUjiUsTyzKPZm5NvBDvSuw268AzNzV8H5/Am+qCnsAXgpgSW2Zq9cyKlksbPlTd+te4quWNieMHBfiNDdciYnwsdI/MaOaWhnMTf54J8CqNj8x8JXFIZltYu+HqlmNT8YSBsHgAPw/vxvlVV4du/s0oaxbxg0TbL/jMni0nNcVjQq7+HZfgtpbzBg342TgQ63AkmsymxBW4IjE6A+D7Vzd/fyWxIM/VuCe+HzTgZ2Jpy/kNJ2FJLmLm24mPJ/42A+Bvrxt4SISwlhsaPodH26LZB8rVA3inwwebsrixJCZzX+KMxI/7AV61eVh3DV6Mx3EOvh4kN6jAg8nfUCXm4d1wE66OyxNPTQc+s3/o/MoXizL3JE5O3F3P/uBZPPF4Zr+Wi5uSO48ZPRdyCwn7YB/A35m5KhWNHox4fcNnIs0ddOCRSBxf8+cQG+Huf0l8NJVYP+nI7NXy2ar4QqIGm69JfKPOE2w/mBavCzwM11R2D+ChsUO7hyUfmwx55qDM1xJvqZ7y08TpifuGBfjeURVJnNIVGpkNiXNS0ds7jcySDitDCCWW56LJ10fRo8sNA+3qXUSZD2CtQlZh9T+1rB7h9oliembflnMbzqgSNZKbKGHdPm7OwXb1CvQ1metSETMpszmzvikCJNh/h5E5PHNl4qga/+/cxqrdeWDYgIe7X5L4cGJPJX2940lOX8pD41FnFnc4riluvQKbK0dcHJFi2IBHNTQSlguru4d2/wPOTNzRA3x5y+U1E1uqWDkETOT026XuUJzx6u7ReLhSYenQ7uHua0fKZmwfmcPqsQjxE5WVONcRxn7X89zgn/EKPMRMxOVQXmP18Mx3q3b/Y/0cQE/IhFtHESMsHFlZ1Ml3CH3DZPHImY+pxcKumNmYirtvqMBfhMuU6s3iqOQkTsMPe1tCQwO8Ajs0lxr7W+vnp1MJc9EgCNd/cy6x+9D4veXmprj5wxMw/3C4egW6zzgZOlYZzfwo3F2J7ael0pJamvlPKgWNKFft1AAcKotXoFEbD7kaoSoQPVKB35+5KHF0lai/rJo+up87jWEE/qqqwY+qrL21LWLm95lPJ16ppKw31XC3PXYPJauPEx7B6BHCgrSizRs18qiaRp8tlN3ueCTYPHH9RNaunjI8Z7wLYpT3jZSCYXQ8e9vTsRE/q+no3XMKeObgGtaintbb/AvXj4JDkNw/5hrwYPfIvlZFUbLn7G5q+eQIN09Vnho6cqvnM/Lt99RixH49wO8K0ZL41WTWHoQzvsNVkOheZqKhEGpsp3SzB+BBtZAYve7uOR9tuTaaB6l0XScdYfEQPpkTUyHEGP+XqyDBzu+NBCITUjNWHynkrbWKOuWFn1xKzqsyx0bdvS78odp0+N503Zao0uCsWuSIDku8/7EO60b41vN5+Ses9BKlTdvd8bhp9EBvJjWJAIn/vxwHe6b3tSk6JFPV4nq85oAOrx555v/x/rh3E6Lo+bnuNS4uB4Cuq0ZfvO8X1rM6q/+vnjLVqZq7v83onttc2oYF4HPJmv1gWbB4P7s0l55ZsPhcsmY/WBYs3s8uzaVn5q3F/wf70mRuBCtbjQAAAABJRU5ErkJggg==',
},
}).then((response: any) => {
if (response.status !== 200 && response.status !== 409) {
throw new Error(`Failed to create space test`);
}
});
}
3 changes: 2 additions & 1 deletion x-pack/plugins/fleet/cypress/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"extends": "../../../../tsconfig.base.json",
"include": [
"**/*",
"../cypress.config.ts"
"../cypress.config.ts",
"../cypress.config.space_awareness.ts"
],
"exclude": [
"target/**/*"
Expand Down
4 changes: 4 additions & 0 deletions x-pack/plugins/fleet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
"private": true,
"license": "Elastic License 2.0",
"scripts": {
"cypress_space_awareness": "NODE_OPTIONS=--openssl-legacy-provider node ../security_solution/scripts/start_cypress_parallel --config-file ../fleet/cypress.config.space_awareness.ts --ftr-config-file ../../../x-pack/test/fleet_cypress/cli_config.space_awareness",
"cypress_space_awareness:open": "yarn cypress_space_awareness open",
"cypress_space_awareness:run": "yarn cypress_space_awareness run",
"cypress_space_awareness:run:reporter": "yarn cypress_space_awareness run --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=../fleet/cypress/reporter_config.json",
"cypress": "NODE_OPTIONS=--openssl-legacy-provider node ../security_solution/scripts/start_cypress_parallel --config-file ../fleet/cypress.config.ts --ftr-config-file ../../../x-pack/test/fleet_cypress/cli_config",
"cypress:open": "yarn cypress open",
"cypress:run": "yarn cypress run",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ export const SettingsView = memo<{ agentPolicy: AgentPolicy }>(
Object.keys(validation).length > 0 ||
hasAdvancedSettingsErrors
}
data-test-subj="agentPolicyDetailsSaveButton"
iconType="save"
color="primary"
fill
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export const AgentPolicyDetailsPage: React.FunctionComponent = () => {
name: i18n.translate('xpack.fleet.policyDetails.subTabs.settingsTabText', {
defaultMessage: 'Settings',
}),
'data-test-subj': 'agentPolicySettingsTab',
href: getHref('policy_details', { policyId, tabId: 'settings' }),
isSelected: tabId === 'settings',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ export const AgentPolicyListPage: React.FunctionComponent<{}> = () => {
<EuiSpacer size="m" />
<EuiBasicTable<AgentPolicy>
loading={isLoading}
data-test-subj="agentPoliciesTable"
noItemsMessage={
isLoading ? (
<FormattedMessage
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/fleet/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
},
"exclude": [
"cypress.config.ts",
"cypress.config.space_awareness.ts",
"target/**/*",
],
"include": [
Expand All @@ -17,6 +18,7 @@
"scripts/**/*",
"package.json",
"cypress.config.ts",
"cypress.config.space_awareness.ts",
"../../../typings/**/*"
],
"kbn_references": [
Expand Down
11 changes: 10 additions & 1 deletion x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ ${JSON.stringify(cypressConfigFile, null, 2)}
const specConfig = cypressConfigFile.e2e.specPattern;
const specArg = argv.spec;
const specPattern = specArg ?? specConfig;
const excludeSpecPattern = cypressConfigFile.e2e.excludeSpecPattern;

log.info('Config spec pattern:', specConfig);
log.info('Exclude spec pattern:', excludeSpecPattern);
log.info('Arguments spec pattern:', specArg);
log.info('Resulting spec pattern:', specPattern);

Expand Down Expand Up @@ -121,7 +123,14 @@ ${JSON.stringify(cypressConfigFile, null, 2)}

const concreteFilePaths = isGrepReturnedFilePaths
? grepSpecPattern // use the returned concrete file paths
: globby.sync(specPattern); // convert the glob pattern to concrete file paths
: globby.sync(
specPattern,
excludeSpecPattern
? {
ignore: excludeSpecPattern,
}
: undefined
); // convert the glob pattern to concrete file paths

let files = retrieveIntegrations(concreteFilePaths);

Expand Down
19 changes: 19 additions & 0 deletions x-pack/test/fleet_cypress/cli_config.space_awareness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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 { FtrConfigProviderContext } from '@kbn/test';

import { FleetCypressCliTestRunner } from './runner';

export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const cypressConfig = await readConfigFile(require.resolve('./config.space_awareness.ts'));
return {
...cypressConfig.getAll(),

testRunner: FleetCypressCliTestRunner,
};
}
Loading

0 comments on commit 89f85ab

Please sign in to comment.