Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cypress cucumber #1

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/dev/ci_setup/setup_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,4 @@ if [[ -d "$ES_DIR" && -f "$ES_JAVA_PROP_PATH" ]]; then
export JAVA_HOME=$HOME/.java/$ES_BUILD_JAVA
fi

export CI_ENV_SETUP=true
export CI_ENV_SETUP=true
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was already merged in upstream, so we will remove the commit that added it

4 changes: 4 additions & 0 deletions x-pack/legacy/plugins/apm/cypress/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cypress/ingest-data/events.json
cypress/screenshots/*

cypress/test-results
17 changes: 9 additions & 8 deletions x-pack/legacy/plugins/apm/cypress/cypress.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
"video": false,
"trashAssetsBeforeRuns": false,
"fileServerFolder": "../",
"fixturesFolder": "./fixtures",
"integrationFolder": "./integration",
"pluginsFile": "./plugins/index.js",
"screenshotsFolder": "./screenshots",
"supportFile": "./support/index.ts",
"videosFolder": "./videos",
"fixturesFolder": "./cypress/fixtures",
"integrationFolder": "./cypress/integration",
"pluginsFile": "./cypress/plugins/index.js",
"screenshotsFolder": "./cypress/screenshots",
"supportFile": "./cypress/support/index.js",
"videosFolder": "./cypress/videos",
"useRelativeSnapshots": true,
"reporter": "junit",
"reporterOptions": {
"mochaFile": "[hash]-e2e-tests.xml",
"mochaFile": "./cypress/test-results/[hash]-e2e-tests.xml",
"toConsole": false
}
},
"testFiles": "**/*.{feature,features}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Feature: APM

Background:
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backgrounds are executed before any scenario within this feature file (like a before test method)

Given a user browses the APM UI application
When the user inspects the opbeans-go service
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The When clause it really important, because it's the one triggering the action we want to verify its behavior.


Scenario: Transaction duration charts
Then should redirect to correct path with correct params
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Then clause is the outcome or the asserts to be done in the scenario. Ideally only one Then should be added per scenario

And should have correct y-axis ticks
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The And clause could be used after a Then or a When. It's indistinguishable from any of them in the sense, but it's important the semantics of And steps: it's like creating another assertion, which ideally must be done just once.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And works with Given, When or Then it makes a scenario easier to read.

Given a thing
And another thing

Reads better than

Given a thing
Given another thing

18 changes: 18 additions & 0 deletions x-pack/legacy/plugins/apm/cypress/cypress/integration/snapshots.js
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;
* you may not use this file except in compliance with the Elastic License.
*/

module.exports = {
'When clicking opbeans-go service': {
'transaction duration charts': {
'should have correct y-axis ticks': {
'1': '3.7 min',
'2': '1.8 min',
'3': '0.0 min'
}
}
},
__version: '3.4.1'
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,10 @@

// eslint-disable-next-line import/no-extraneous-dependencies
const wp = require('@cypress/webpack-preprocessor');
const fs = require('fs');

module.exports = on => {
// add typescript support
const options = {
webpackOptions: {
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
options: { transpileOnly: true }
}
]
}
}
Comment on lines -27 to -40
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to ../webpack.config.js, please check there the configuration for typescript. I'd love hearing your experience in the configuration part, as that is a copy&paste mix of the different examples. 🙏

webpackOptions: require('../webpack.config.js')
};
on('file:preprocessor', wp(options));

// readFileMaybe
on('task', {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what it's the purpose of this function, maybe to read the snapshots.js file? If so, Cucumber + Cypress provides a fixtures dir to store JSON files as data for the tests.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it's for the snapshots IIRC.

readFileMaybe(filename) {
if (fs.existsSync(filename)) {
return fs.readFileSync(filename, 'utf8');
}

return null;
}
});
};
31 changes: 31 additions & 0 deletions x-pack/legacy/plugins/apm/cypress/cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file comes from the scaffolding

* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
/// <reference types="Cypress" />

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

// typically custom commands are added in this support folder
// so it makes sense to put their TypeScript definitions here
// from the JavaScript specs loads this file using
// the triple slash "reference" comment like this:
//
// /// <reference path="../support/index.d.ts" />

declare namespace Cypress {
interface Chainable<Subject> {
snapshot: () => {};
Copy link
Author

@mdelapenya mdelapenya Feb 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the function that is nor defined in the tests 🤷‍♀ How could we include it in the tests?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a type def, it's not the actual code. likely we need to include cypress/snapshot somewhere.

Expand Down
26 changes: 26 additions & 0 deletions x-pack/legacy/plugins/apm/cypress/cypress/support/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file comes from the scaffolding

* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands';

mdelapenya marked this conversation as resolved.
Show resolved Hide resolved
// Alternatively you can use CommonJS syntax:
// require('./commands')
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/// <reference types="Cypress" />

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { loginAndWaitForPage } from '../../integration/helpers';

const { Given, When, Then } = require('cypress-cucumber-preprocessor/steps');

Given(`a user browses the APM UI application`, () => {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no difference using Given('foo'), When('foo'), Then('foo')... They technically could be defined in any format. BUT it's important to use the proper word for the sake of semantics! We are providing information to an occasional reader so he/she is able to properly understand the specification/behavior

// open service overview page
loginAndWaitForPage(`/app/apm#/services`);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because a Given represents the pre-conditions for a test, we moved the old before method here.

});

When(`the user inspects the opbeans-go service`, () => {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The When is the action to verify its behavior.

// click opbeans-go service
cy.get(':contains(opbeans-go)')
.last()
.click({ force: true });
});

Then(`should redirect to correct path with correct params`, () => {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The traditional assertions are performed here, in the Then method, which must include the verifications points to mark a behavior as valid.

cy.url().should('contain', `/app/apm#/services/opbeans-go/transactions`);
cy.url().should('contain', `transactionType=request`);
});

Then(`should have correct y-axis ticks`, () => {
const yAxisTick =
'[data-cy=transaction-duration-charts] .rv-xy-plot__axis--vertical .rv-xy-plot__axis__tick__text';

cy.get(yAxisTick)
.eq(2)
.invoke('text')
.snapshot();
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved

cy.get(yAxisTick)
.eq(1)
.invoke('text')
.snapshot();

cy.get(yAxisTick)
.eq(0)
.invoke('text')
.snapshot();
});
41 changes: 41 additions & 0 deletions x-pack/legacy/plugins/apm/cypress/cypress/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

module.exports = {
resolve: {
extensions: ['.ts', '.js']
},
node: { fs: 'empty', child_process: 'empty', readline: 'empty' },
module: {
rules: [
{
test: /\.ts$/,
exclude: [/node_modules/],
use: [
{
loader: 'ts-loader'
}
]
},
{
test: /\.feature$/,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Files representing the features/specifications, in the form of .feature files.

use: [
{
loader: 'cypress-cucumber-preprocessor/loader'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the preloader that does the magic accepting Cucumber feature files

}
]
},
{
test: /\.features$/,
use: [
{
loader: 'cypress-cucumber-preprocessor/lib/featuresLoader'
}
]
}
Comment on lines +31 to +38
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm realising that this could be removed, as hopefully we won't write this kind of files. (TBH, I need to read about the differences)

]
}
};
53 changes: 0 additions & 53 deletions x-pack/legacy/plugins/apm/cypress/integration/apm.spec.ts

This file was deleted.

12 changes: 0 additions & 12 deletions x-pack/legacy/plugins/apm/cypress/integration/snapshots.js

This file was deleted.

12 changes: 10 additions & 2 deletions x-pack/legacy/plugins/apm/cypress/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,25 @@
"license": "MIT",
"scripts": {
"cypress:open": "cypress open",
"cypress:run": "cypress run"
"cypress:run": "cypress run --spec **/*.feature",
"lint": "tslint --project ./tsconfig.json --fix",
"postlint": "npm run tsc",
"tsc": "tsc --pretty --noEmit"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd need help in this part, because maybe it's already provided by kibana build

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can all be removed, typescript should be handled by Kibana scripts, see src/dev/typescript/projects.ts

},
"dependencies": {
"@cypress/snapshot": "^2.1.3",
"@cypress/webpack-preprocessor": "^4.1.0",
"@types/js-yaml": "^3.12.1",
"@types/node": "^10.12.11",
"cypress": "^3.5.0",
"cypress-cucumber-preprocessor": "^2.0.1",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.9.0",
"js-yaml": "^3.13.1",
"p-limit": "^2.2.1",
"ts-loader": "^6.1.0",
"typescript": "3.7.2",
"tslint": "6.0.0",
"typescript": "3.7.5",
"webpack": "^4.40.2"
}
}
1 change: 0 additions & 1 deletion x-pack/legacy/plugins/apm/cypress/screenshots/.gitignore

This file was deleted.

3 changes: 0 additions & 3 deletions x-pack/legacy/plugins/apm/cypress/snapshots.js

This file was deleted.

10 changes: 0 additions & 10 deletions x-pack/legacy/plugins/apm/cypress/support/index.ts

This file was deleted.

Loading