Skip to content

Commit

Permalink
[Logs onboarding] Added Cypress to observability onboarding plugin (#…
Browse files Browse the repository at this point in the history
…157147)

This PR enables cypress testing in observability onboarding plugin.
  • Loading branch information
yngrdyn authored May 11, 2023
1 parent 4808a6d commit 0fc4949
Show file tree
Hide file tree
Showing 17 changed files with 559 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .buildkite/ftr_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ disabled:
- x-pack/test/defend_workflows_cypress/config.ts
- x-pack/test/defend_workflows_cypress/endpoint_config.ts
- x-pack/test/defend_workflows_cypress/visual_config.ts
- x-pack/plugins/observability_onboarding/e2e/ftr_config_open.ts
- x-pack/plugins/observability_onboarding/e2e/ftr_config_runner.ts
- x-pack/plugins/observability_onboarding/e2e/ftr_config.ts
- x-pack/test/osquery_cypress/cli_config.ts
- x-pack/test/osquery_cypress/config.ts
- x-pack/test/osquery_cypress/visual_config.ts
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
steps:
- command: .buildkite/scripts/steps/functional/observability_onboarding_cypress.sh
label: 'Observability onboarding Cypress Tests'
agents:
queue: n2-4-spot
depends_on: build
timeout_in_minutes: 120
parallelism: 2
retry:
automatic:
- exit_status: '-1'
limit: 3
- exit_status: '*'
limit: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

set -euo pipefail

source .buildkite/scripts/common/util.sh

.buildkite/scripts/bootstrap.sh
.buildkite/scripts/download_build_artifacts.sh

export JOB=kibana-observability-onboarding-cypress

echo "--- Observability onboarding Cypress Tests"

cd "$XPACK_DIR"

node plugins/observability_onboarding/scripts/test/e2e.js \
--kibana-install-dir "$KIBANA_BUILD_LOCATION" \
51 changes: 51 additions & 0 deletions x-pack/plugins/observability_onboarding/e2e/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Observability onboarding E2E tests

Observability onboarding uses [FTR](../../../../packages/kbn-test/README.mdx) (functional test runner) and [Cypress](https://www.cypress.io/) to run the e2e tests. The tests are located at `kibana/x-pack/plugins/observability_onboarding/e2e/cypress/e2e`.

## E2E Tests (Cypress)

The E2E tests are located in [`x-pack/plugins/observability_onboarding/e2e`](./cypress/e2e).

Tests run on buildkite PR pipeline are parallelized (2 parallel jobs) and are orchestrated by the Cypress dashboard service. It can be configured in [.buildkite/pipelines/pull_request/observability_onboarding_cypress.yml](https://github.com/elastic/kibana/blob/main/.buildkite/pipelines/pull_request/observability_onboarding_cypress.yml) with the property `parallelism`.

```yml
...
depends_on: build
parallelism: 2
...
```

## Running it locally

### Start test server

```
node x-pack/plugins/observability_onboarding/scripts/test/e2e --server
```

### Run tests
Runs all tests in the terminal

```
node x-pack/plugins/observability_onboarding/scripts/test/e2e --runner
```

### Open cypress dashboard
Opens cypress dashboard, there it's possible to select what test you want to run.

```
node x-pack/plugins/observability_onboarding/scripts/test/e2e --open
```
### Arguments

| Option | Description |
| ------------ | ----------------------------------------------- |
| --server | Only start ES and Kibana |
| --runner | Only run tests |
| --spec | Specify the specs to run |
| --times | Repeat the test n number of times |
| --bail | stop tests after the first failure |

```
node x-pack/plugins/observability_onboarding/scripts/test/e2e.js --runner --spec cypress/e2e/home.cy.ts --times 2
```
33 changes: 33 additions & 0 deletions x-pack/plugins/observability_onboarding/e2e/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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';

export default defineCypressConfig({
fileServerFolder: './cypress',
fixturesFolder: './cypress/fixtures',
screenshotsFolder: './cypress/screenshots',
videosFolder: './cypress/videos',
requestTimeout: 10000,
responseTimeout: 40000,
defaultCommandTimeout: 30000,
execTimeout: 120000,
pageLoadTimeout: 120000,
viewportHeight: 1800,
viewportWidth: 1440,
video: false,
videoUploadOnPasses: false,
screenshotOnRunFailure: false,
retries: {
runMode: 1,
},
e2e: {
baseUrl: 'http://localhost:5601',
supportFile: './cypress/support/e2e.ts',
specPattern: './cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
},
});
17 changes: 17 additions & 0 deletions x-pack/plugins/observability_onboarding/e2e/cypress/e2e/home.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* 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.
*/

describe('[Observability onboarding] Landing page', () => {
beforeEach(() => {
cy.loginAsElastic();
});

it('shows landing page', () => {
cy.visitKibana('/app/observabilityOnboarding');
cy.contains('Get started with Observability');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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 URL from 'url';

Cypress.Commands.add(
'loginAs',
({ username, password }: { username: string; password: string }) => {
const kibanaUrl = Cypress.env('KIBANA_URL');
cy.log(`Logging in as ${username} on ${kibanaUrl}`);
cy.visit('/');
cy.request({
log: true,
method: 'POST',
url: `${kibanaUrl}/internal/security/login`,
body: {
providerType: 'basic',
providerName: 'basic',
currentURL: `${kibanaUrl}/login`,
params: { username, password },
},
headers: {
'kbn-xsrf': 'e2e_test',
},
});
cy.visit('/');
}
);

Cypress.Commands.add('loginAsElastic', () => {
return cy.loginAs({
username: 'elastic',
password: 'changeme',
});
});

Cypress.Commands.add('getByTestSubj', (selector: string) => {
return cy.get(`[data-test-subj="${selector}"]`);
});

Cypress.Commands.add(
'visitKibana',
(url: string, rangeFrom?: string, rangeTo?: string) => {
const urlPath = URL.format({
pathname: url,
query: { rangeFrom, rangeTo },
});

cy.visit(urlPath);
cy.getByTestSubj('kbnLoadingMessage').should('exist');
cy.getByTestSubj('kbnLoadingMessage').should('not.exist', {
timeout: 50000,
});
}
);
12 changes: 12 additions & 0 deletions x-pack/plugins/observability_onboarding/e2e/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* 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.
*/

Cypress.on('uncaught:exception', (err, runnable) => {
return false;
});

import './commands';
Original file line number Diff line number Diff line change
@@ -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.
*/

declare namespace Cypress {
interface Chainable {
loginAs(params: {
username: string;
password: string;
}): Cypress.Chainable<Cypress.Response<any>>;
loginAsElastic(): Cypress.Chainable<Cypress.Response<any>>;
getByTestSubj(selector: string): Chainable<JQuery<Element>>;
visitKibana(url: string, rangeFrom?: string, rangeTo?: string): void;
}
}
78 changes: 78 additions & 0 deletions x-pack/plugins/observability_onboarding/e2e/cypress_test_runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* 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 cypress from 'cypress';
import path from 'path';
import Url from 'url';
import { FtrProviderContext } from './ftr_provider_context';

export async function cypressTestRunner({
ftrProviderContext: { getService },
cypressExecution,
}: {
ftrProviderContext: FtrProviderContext;
cypressExecution: typeof cypress.run | typeof cypress.open;
}) {
const config = getService('config');

const username = config.get('servers.elasticsearch.username');
const password = config.get('servers.elasticsearch.password');

const esNode = Url.format({
protocol: config.get('servers.elasticsearch.protocol'),
port: config.get('servers.elasticsearch.port'),
hostname: config.get('servers.elasticsearch.hostname'),
auth: `${username}:${password}`,
});

const esRequestTimeout = config.get('timeouts.esRequestTimeout');

const kibanaUrlWithoutAuth = Url.format({
protocol: config.get('servers.kibana.protocol'),
hostname: config.get('servers.kibana.hostname'),
port: config.get('servers.kibana.port'),
});

const cypressProjectPath = path.join(__dirname);
const { open, ...cypressCliArgs } = getCypressCliArgs();

const res = await cypressExecution({
...cypressCliArgs,
project: cypressProjectPath,
config: {
e2e: {
baseUrl: kibanaUrlWithoutAuth,
},
},
env: {
KIBANA_URL: kibanaUrlWithoutAuth,
ES_NODE: esNode,
ES_REQUEST_TIMEOUT: esRequestTimeout,
TEST_CLOUD: process.env.TEST_CLOUD,
},
});

return res;
}

function getCypressCliArgs(): Record<string, unknown> {
if (!process.env.CYPRESS_CLI_ARGS) {
return {};
}

const { $0, _, ...cypressCliArgs } = JSON.parse(
process.env.CYPRESS_CLI_ARGS
) as Record<string, unknown>;

const spec =
typeof cypressCliArgs.spec === 'string' &&
!cypressCliArgs.spec.includes('**')
? `**/${cypressCliArgs.spec}*`
: cypressCliArgs.spec;

return { ...cypressCliArgs, spec };
}
51 changes: 51 additions & 0 deletions x-pack/plugins/observability_onboarding/e2e/ftr_config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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 { CA_CERT_PATH } from '@kbn/dev-utils';
import path from 'path';

const kibanaYamlFilePath = path.join(__dirname, './ftr_kibana.yml');

async function ftrConfig({ readConfigFile }: FtrConfigProviderContext) {
const kibanaCommonTestsConfig = await readConfigFile(
require.resolve('../../../../test/common/config.js')
);
const xpackFunctionalTestsConfig = await readConfigFile(
require.resolve('../../../test/functional/config.base.js')
);

return {
...kibanaCommonTestsConfig.getAll(),

esTestCluster: {
...xpackFunctionalTestsConfig.get('esTestCluster'),
serverArgs: [
...xpackFunctionalTestsConfig.get('esTestCluster.serverArgs'),
// define custom es server here
// API Keys is enabled at the top level
'xpack.security.enabled=true',
],
},

kbnTestServer: {
...xpackFunctionalTestsConfig.get('kbnTestServer'),
serverArgs: [
...xpackFunctionalTestsConfig.get('kbnTestServer.serverArgs'),
'--home.disableWelcomeScreen=true',
'--csp.strict=false',
'--csp.warnLegacyBrowsers=false',
// define custom kibana server args here
`--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`,
`--config=${kibanaYamlFilePath}`,
],
},
};
}

// eslint-disable-next-line import/no-default-export
export default ftrConfig;
Loading

0 comments on commit 0fc4949

Please sign in to comment.