Skip to content

Commit

Permalink
[8.x] [Automatic Import] Add Cypress tests for Automatic Import UI fl…
Browse files Browse the repository at this point in the history
…ow (elastic#194948) (elastic#195737)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Automatic Import] Add Cypress tests for Automatic Import UI flow
(elastic#194948)](elastic#194948)

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

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

<!--BACKPORT [{"author":{"name":"Bharat
Pasupula","email":"123897612+bhapas@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-10-10T09:31:30Z","message":"[Automatic
Import] Add Cypress tests for Automatic Import UI flow (elastic#194948)\n\n##
Summary\r\n\r\nAdds Cypress functional UI tests for different flows in
Automatic\r\nImport.\r\n\r\n- Relates
[elastic#192684](https://github.com/elastic/kibana/issues/192684)\r\n\r\n###
RBAC tests\r\n\r\n#### Create Integration Landing Page\r\n- Fleet `read`
Integrations `all` -- No access\r\n- Fleet `read` Integrations `read` --
No access\r\n- Fleet `read` Integrations `read` -- No access\r\n- Fleet
`all` Integrations `all` -- Access\r\n\r\n#### Create Integration
Assistant Page\r\n- Fleet/integrations `all` Actions `read` [ `show`
`execute` ] --\r\nExecute with existing connectors\r\n-
Fleet/integrations `all` Actions `all` [ `show` `execute`
`save`\r\n`delete` ] -- Create new connector / execute existing
ones.\r\n\r\n### Create Integration UI Flow - NDJSON example\r\n- Create
an integration using Automatic Import with NDJSON
samples\r\n\r\n\r\n\r\nhttps://github.com/user-attachments/assets/9ab4cfc2-f058-4491-a280-6b86bcc5c9ce\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"c9200332ffe13e1df7225f023fa493f415ab429f","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["enhancement","release_note:skip","Team:Fleet","v9.0.0","backport:prev-minor","8.16
candidate","Team:Security-Scalability","Feature:AutomaticImport"],"number":194948,"url":"https://github.com/elastic/kibana/pull/194948","mergeCommit":{"message":"[Automatic
Import] Add Cypress tests for Automatic Import UI flow (elastic#194948)\n\n##
Summary\r\n\r\nAdds Cypress functional UI tests for different flows in
Automatic\r\nImport.\r\n\r\n- Relates
[elastic#192684](https://github.com/elastic/kibana/issues/192684)\r\n\r\n###
RBAC tests\r\n\r\n#### Create Integration Landing Page\r\n- Fleet `read`
Integrations `all` -- No access\r\n- Fleet `read` Integrations `read` --
No access\r\n- Fleet `read` Integrations `read` -- No access\r\n- Fleet
`all` Integrations `all` -- Access\r\n\r\n#### Create Integration
Assistant Page\r\n- Fleet/integrations `all` Actions `read` [ `show`
`execute` ] --\r\nExecute with existing connectors\r\n-
Fleet/integrations `all` Actions `all` [ `show` `execute`
`save`\r\n`delete` ] -- Create new connector / execute existing
ones.\r\n\r\n### Create Integration UI Flow - NDJSON example\r\n- Create
an integration using Automatic Import with NDJSON
samples\r\n\r\n\r\n\r\nhttps://github.com/user-attachments/assets/9ab4cfc2-f058-4491-a280-6b86bcc5c9ce\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"c9200332ffe13e1df7225f023fa493f415ab429f"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194948","number":194948,"mergeCommit":{"message":"[Automatic
Import] Add Cypress tests for Automatic Import UI flow (elastic#194948)\n\n##
Summary\r\n\r\nAdds Cypress functional UI tests for different flows in
Automatic\r\nImport.\r\n\r\n- Relates
[elastic#192684](https://github.com/elastic/kibana/issues/192684)\r\n\r\n###
RBAC tests\r\n\r\n#### Create Integration Landing Page\r\n- Fleet `read`
Integrations `all` -- No access\r\n- Fleet `read` Integrations `read` --
No access\r\n- Fleet `read` Integrations `read` -- No access\r\n- Fleet
`all` Integrations `all` -- Access\r\n\r\n#### Create Integration
Assistant Page\r\n- Fleet/integrations `all` Actions `read` [ `show`
`execute` ] --\r\nExecute with existing connectors\r\n-
Fleet/integrations `all` Actions `all` [ `show` `execute`
`save`\r\n`delete` ] -- Create new connector / execute existing
ones.\r\n\r\n### Create Integration UI Flow - NDJSON example\r\n- Create
an integration using Automatic Import with NDJSON
samples\r\n\r\n\r\n\r\nhttps://github.com/user-attachments/assets/9ab4cfc2-f058-4491-a280-6b86bcc5c9ce\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"c9200332ffe13e1df7225f023fa493f415ab429f"}}]}]
BACKPORT-->
  • Loading branch information
bhapas authored Oct 10, 2024
1 parent 8cb2d82 commit d9aeca0
Show file tree
Hide file tree
Showing 17 changed files with 1,168 additions and 39 deletions.
115 changes: 115 additions & 0 deletions x-pack/plugins/fleet/cypress/e2e/integrations_automatic_import.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* 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 { deleteIntegrations } from '../tasks/integrations';
import {
UPLOAD_PACKAGE_LINK,
ASSISTANT_BUTTON,
TECH_PREVIEW_BADGE,
CREATE_INTEGRATION_LANDING_PAGE,
BUTTON_FOOTER_NEXT,
INTEGRATION_TITLE_INPUT,
INTEGRATION_DESCRIPTION_INPUT,
DATASTREAM_TITLE_INPUT,
DATASTREAM_DESCRIPTION_INPUT,
DATASTREAM_NAME_INPUT,
DATA_COLLECTION_METHOD_INPUT,
LOGS_SAMPLE_FILE_PICKER,
EDIT_PIPELINE_BUTTON,
SAVE_PIPELINE_BUTTON,
VIEW_INTEGRATION_BUTTON,
INTEGRATION_SUCCESS_SECTION,
SAVE_ZIP_BUTTON,
} from '../screens/integrations_automatic_import';
import { cleanupAgentPolicies } from '../tasks/cleanup';
import { login, logout } from '../tasks/login';
import { createBedrockConnector, deleteConnectors } from '../tasks/api_calls/connectors';
import {
ecsResultsForJson,
categorizationResultsForJson,
relatedResultsForJson,
} from '../tasks/api_calls/graph_results';

describe('Add Integration - Automatic Import', () => {
beforeEach(() => {
login();

cleanupAgentPolicies();
deleteIntegrations();

// Create a mock connector
deleteConnectors();
createBedrockConnector();
// Mock API Responses
cy.intercept('POST', '/api/integration_assistant/ecs', {
statusCode: 200,
body: {
results: ecsResultsForJson,
},
});
cy.intercept('POST', '/api/integration_assistant/categorization', {
statusCode: 200,
body: {
results: categorizationResultsForJson,
},
});
cy.intercept('POST', '/api/integration_assistant/related', {
statusCode: 200,
body: {
results: relatedResultsForJson,
},
});
});

afterEach(() => {
deleteConnectors();
cleanupAgentPolicies();
deleteIntegrations();
logout();
});

it('should create an integration', () => {
cy.visit(CREATE_INTEGRATION_LANDING_PAGE);

cy.getBySel(ASSISTANT_BUTTON).should('exist');
cy.getBySel(UPLOAD_PACKAGE_LINK).should('exist');
cy.getBySel(TECH_PREVIEW_BADGE).should('exist');

// Create Integration Assistant Page
cy.getBySel(ASSISTANT_BUTTON).click();
cy.getBySel(BUTTON_FOOTER_NEXT).click();

// Integration details Page
cy.getBySel(INTEGRATION_TITLE_INPUT).type('Test Integration');
cy.getBySel(INTEGRATION_DESCRIPTION_INPUT).type('Test Integration Description');
cy.getBySel(BUTTON_FOOTER_NEXT).click();

// Datastream details page
cy.getBySel(DATASTREAM_TITLE_INPUT).type('Audit');
cy.getBySel(DATASTREAM_DESCRIPTION_INPUT).type('Test Datastream Description');
cy.getBySel(DATASTREAM_NAME_INPUT).type('audit');
cy.getBySel(DATA_COLLECTION_METHOD_INPUT).type('file stream');
cy.get('body').click(0, 0);

// Select sample logs file and Analyze logs
cy.fixture('teleport.ndjson', null).as('myFixture');
cy.getBySel(LOGS_SAMPLE_FILE_PICKER).selectFile('@myFixture');
cy.getBySel(BUTTON_FOOTER_NEXT).click();

// Edit Pipeline
cy.getBySel(EDIT_PIPELINE_BUTTON).click();
cy.getBySel(SAVE_PIPELINE_BUTTON).click();

// Deploy
cy.getBySel(BUTTON_FOOTER_NEXT).click();
cy.getBySel(INTEGRATION_SUCCESS_SECTION).should('exist');
cy.getBySel(SAVE_ZIP_BUTTON).should('exist');

// View Integration
cy.getBySel(VIEW_INTEGRATION_BUTTON).click();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* 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 type { User } from '../tasks/privileges';
import {
deleteUsersAndRoles,
getIntegrationsAutoImportRole,
createUsersAndRoles,
AutomaticImportConnectorNoneUser,
AutomaticImportConnectorNoneRole,
AutomaticImportConnectorAllUser,
AutomaticImportConnectorAllRole,
AutomaticImportConnectorReadUser,
AutomaticImportConnectorReadRole,
} from '../tasks/privileges';
import { login, loginWithUserAndWaitForPage, logout } from '../tasks/login';
import {
ASSISTANT_BUTTON,
CONNECTOR_BEDROCK,
CONNECTOR_GEMINI,
CONNECTOR_OPENAI,
CREATE_INTEGRATION_ASSISTANT,
CREATE_INTEGRATION_LANDING_PAGE,
CREATE_INTEGRATION_UPLOAD,
MISSING_PRIVILEGES,
UPLOAD_PACKAGE_LINK,
} from '../screens/integrations_automatic_import';

describe('When the user does not have enough previleges for Integrations', () => {
const runs = [
{ fleetRole: 'read', integrationsRole: 'read' },
{ fleetRole: 'read', integrationsRole: 'all' },
{ fleetRole: 'all', integrationsRole: 'read' },
];

runs.forEach(function (run) {
describe(`When the user has '${run.fleetRole}' role for fleet and '${run.integrationsRole}' role for Integrations`, () => {
const automaticImportIntegrRole = getIntegrationsAutoImportRole({
fleetv2: [run.fleetRole], // fleet
fleet: [run.integrationsRole], // integrations
});
const AutomaticImportIntegrUser: User = {
username: 'automatic_import_integrations_read_user',
password: 'password',
roles: [automaticImportIntegrRole.name],
};

before(() => {
createUsersAndRoles([AutomaticImportIntegrUser], [automaticImportIntegrRole]);
});

beforeEach(() => {
login();
});

afterEach(() => {
logout();
});

after(() => {
deleteUsersAndRoles([AutomaticImportIntegrUser], [automaticImportIntegrRole]);
});

it('Create Assistant is not accessible if user has read role in integrations', () => {
loginWithUserAndWaitForPage(CREATE_INTEGRATION_ASSISTANT, AutomaticImportIntegrUser);
cy.getBySel(MISSING_PRIVILEGES).should('exist');
});

it('Create upload is not accessible if user has read role in integrations', () => {
loginWithUserAndWaitForPage(CREATE_INTEGRATION_UPLOAD, AutomaticImportIntegrUser);
cy.getBySel(MISSING_PRIVILEGES).should('exist');
});
});
});
});

describe('When the user has All permissions for Integrations and No permissions for actions', () => {
before(() => {
createUsersAndRoles([AutomaticImportConnectorNoneUser], [AutomaticImportConnectorNoneRole]);
});

beforeEach(() => {
login();
});

afterEach(() => {
logout();
});

after(() => {
deleteUsersAndRoles([AutomaticImportConnectorNoneUser], [AutomaticImportConnectorNoneRole]);
});

it('Create Assistant is not accessible but upload is accessible', () => {
loginWithUserAndWaitForPage(CREATE_INTEGRATION_LANDING_PAGE, AutomaticImportConnectorNoneUser);
cy.getBySel(ASSISTANT_BUTTON).should('not.exist');
cy.getBySel(UPLOAD_PACKAGE_LINK).should('exist');
});
});

describe('When the user has All permissions for Integrations and read permissions for actions', () => {
before(() => {
createUsersAndRoles([AutomaticImportConnectorReadUser], [AutomaticImportConnectorReadRole]);
});

beforeEach(() => {
login();
});

afterEach(() => {
logout();
});

after(() => {
deleteUsersAndRoles([AutomaticImportConnectorReadUser], [AutomaticImportConnectorReadRole]);
});

it('Create Assistant is not accessible but upload is accessible', () => {
loginWithUserAndWaitForPage(CREATE_INTEGRATION_LANDING_PAGE, AutomaticImportConnectorReadUser);
cy.getBySel(ASSISTANT_BUTTON).should('exist');
cy.getBySel(UPLOAD_PACKAGE_LINK).should('exist');
});

it('Create Assistant is accessible but execute connector is not accessible', () => {
loginWithUserAndWaitForPage(CREATE_INTEGRATION_ASSISTANT, AutomaticImportConnectorReadUser);
cy.getBySel(CONNECTOR_BEDROCK).should('not.exist');
cy.getBySel(CONNECTOR_OPENAI).should('not.exist');
cy.getBySel(CONNECTOR_GEMINI).should('not.exist');
});
});

describe('When the user has All permissions for Integrations and All permissions for actions', () => {
before(() => {
createUsersAndRoles([AutomaticImportConnectorAllUser], [AutomaticImportConnectorAllRole]);
});

beforeEach(() => {
login();
});

afterEach(() => {
logout();
});

after(() => {
deleteUsersAndRoles([AutomaticImportConnectorAllUser], [AutomaticImportConnectorAllRole]);
});

it('Create Assistant is not accessible but upload is accessible', () => {
loginWithUserAndWaitForPage(CREATE_INTEGRATION_ASSISTANT, AutomaticImportConnectorAllUser);
cy.getBySel(CONNECTOR_BEDROCK).should('exist');
cy.getBySel(CONNECTOR_OPENAI).should('exist');
cy.getBySel(CONNECTOR_GEMINI).should('exist');
});
});
1 change: 1 addition & 0 deletions x-pack/plugins/fleet/cypress/fixtures/teleport.ndjson
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"ei":0,"event":"cert.create","uid":"efd326fc-dd13-4df8-acef-3102c2d717d3","code":"TC000I","time":"2024-02-24T06:56:50.648137154Z"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* 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 UPLOAD_PACKAGE_LINK = 'uploadPackageLink';
export const ASSISTANT_BUTTON = 'assistantButton';
export const TECH_PREVIEW_BADGE = 'techPreviewBadge';
export const MISSING_PRIVILEGES = 'missingPrivilegesCallOut';

export const CONNECTOR_BEDROCK = 'actionType-.bedrock';
export const CONNECTOR_OPENAI = 'actionType-.gen-ai';
export const CONNECTOR_GEMINI = 'actionType-.gemini';

export const BUTTON_FOOTER_NEXT = 'buttonsFooter-nextButton';

export const INTEGRATION_TITLE_INPUT = 'integrationTitleInput';
export const INTEGRATION_DESCRIPTION_INPUT = 'integrationDescriptionInput';
export const DATASTREAM_TITLE_INPUT = 'dataStreamTitleInput';
export const DATASTREAM_DESCRIPTION_INPUT = 'dataStreamDescriptionInput';
export const DATASTREAM_NAME_INPUT = 'dataStreamNameInput';
export const DATA_COLLECTION_METHOD_INPUT = 'dataCollectionMethodInput';
export const LOGS_SAMPLE_FILE_PICKER = 'logsSampleFilePicker';

export const EDIT_PIPELINE_BUTTON = 'editPipelineButton';
export const SAVE_PIPELINE_BUTTON = 'savePipelineButton';
export const VIEW_INTEGRATION_BUTTON = 'viewIntegrationButton';
export const INTEGRATION_SUCCESS_SECTION = 'integrationSuccessSection';
export const SAVE_ZIP_BUTTON = 'saveZipButton';

export const CREATE_INTEGRATION_LANDING_PAGE = '/app/integrations/create';
export const CREATE_INTEGRATION_ASSISTANT = '/app/integrations/create/assistant';
export const CREATE_INTEGRATION_UPLOAD = '/app/integrations/create/upload';
Loading

0 comments on commit d9aeca0

Please sign in to comment.