Skip to content

Commit 8b944a3

Browse files
authored
Adds cypress e2e tests and github action cypress workflow (opensearch-project#80)
1 parent 18c564c commit 8b944a3

16 files changed

+2916
-1748
lines changed
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
name: E2E Cypress tests
2+
on:
3+
push:
4+
branches:
5+
- master
6+
7+
jobs:
8+
tests:
9+
name: Run Cypress E2E tests
10+
runs-on: ubuntu-latest
11+
env:
12+
# prevents extra Cypress installation progress messages
13+
CI: 1
14+
# avoid warnings like "tput: No value for $TERM and no -T specified"
15+
TERM: xterm
16+
steps:
17+
- name: Set up JDK
18+
uses: actions/setup-java@v1
19+
with:
20+
# TODO: Parse this from index management plugin
21+
java-version: 14
22+
- name: Checkout
23+
uses: actions/checkout@v2
24+
with:
25+
path: index-management
26+
# TODO: Move this after Kibana plugin setup so we can pull down the correct branch to support all opendistro branches
27+
repository: opendistro-for-elasticsearch/index-management
28+
- name: Run elasticsearch with plugin
29+
run: |
30+
cd index-management
31+
./gradlew run &
32+
timeout 300 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:9200)" != "200" ]]; do sleep 5; done'
33+
- name: Checkout Index Management Kibana plugin
34+
uses: actions/checkout@v2
35+
with:
36+
path: index-management-kibana-plugin
37+
- name: Get Kibana version
38+
id: kibana_version
39+
run: |
40+
echo "::set-output name=kibana_version::$(node -p "(require('./index-management-kibana-plugin/package.json').kibana.version).match(/[.0-9]+/)[0]")"
41+
- name: Checkout Kibana
42+
uses: actions/checkout@v2
43+
with:
44+
repository: opendistro-for-elasticsearch/kibana-oss
45+
ref: ${{ steps.kibana_version.outputs.kibana_version }}
46+
token: ${{ secrets.GITHUB_KIBANA_OSS }}
47+
path: kibana
48+
- name: Get node and yarn versions
49+
id: versions
50+
run: |
51+
echo "::set-output name=node_version::$(node -p "(require('./kibana/package.json').engines.node).match(/[.0-9]+/)[0]")"
52+
echo "::set-output name=yarn_version::$(node -p "(require('./kibana/package.json').engines.yarn).match(/[.0-9]+/)[0]")"
53+
- name: Setup node
54+
uses: actions/setup-node@v1
55+
with:
56+
node-version: ${{ steps.versions.outputs.node_version }}
57+
registry-url: 'https://registry.npmjs.org'
58+
- name: Install correct yarn version for Kibana
59+
run: |
60+
npm uninstall -g yarn
61+
echo "Installing yarn ${{ steps.versions_step.outputs.yarn_version }}"
62+
npm i -g yarn@${{ steps.versions.outputs.yarn_version }}
63+
- name: Bootstrap plugin/kibana
64+
run: |
65+
mkdir -p kibana/plugins
66+
mv index-management-kibana-plugin kibana/plugins
67+
cd kibana/plugins/index-management-kibana-plugin
68+
yarn kbn bootstrap
69+
- name: Run kibana server
70+
run: |
71+
cd kibana/plugins/index-management-kibana-plugin
72+
yarn start --no-base-path --no-watch &
73+
timeout 300 bash -c 'while [[ "$(curl -s localhost:5601/api/status | jq -r '.status.overall.state')" != "green" ]]; do sleep 5; done'
74+
# for now just chrome, use matrix to do all browsers later
75+
- name: Cypress tests
76+
uses: cypress-io/github-action@v1
77+
with:
78+
working-directory: kibana/plugins/index-management-kibana-plugin
79+
command: yarn run cypress run
80+
browser: chrome
81+
# Screenshots are only captured on failure, will change this once we do visual regression tests
82+
- uses: actions/upload-artifact@v1
83+
if: failure()
84+
with:
85+
name: cypress-screenshots
86+
path: kibana/plugins/index-management-kibana-plugin/cypress/screenshots
87+
# Test run video was always captured, so this action uses "always()" condition
88+
- uses: actions/upload-artifact@v1
89+
if: always()
90+
with:
91+
name: cypress-videos
92+
path: kibana/plugins/index-management-kibana-plugin/cypress/videos

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ node_modules
66
yarn-error.log
77
/coverage/
88
.DS_Store
9+
/cypress/screenshots/
10+
/cypress/videos/

README.md

+19-2
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,28 @@ Example output: `./build/opendistro_index_management_kibana-1.3.0.0.zip`
4040

4141
- `yarn start`
4242

43-
Starts Kibana and includes this plugin. Kibana will be available on `localhost:5601`.
43+
- Starts Kibana and includes this plugin. Kibana will be available on `localhost:5601`.
44+
- You must have Elasticsearch running with the Index Management plugin
45+
46+
## Test
47+
48+
There are unit/stubbed integration tests and cypress e2e/integration tests.
49+
50+
To run the cypress tests, you must have both Elasticsearch and Kibana running with the Index Management plugin running.
51+
52+
If you are running cypress tests with Kibana development server use the `--no-base-path` option and if you are writing Cypress tests use the `--no-watch` to make sure your server is not restarted.
4453

4554
- `yarn test:jest`
4655

47-
Runs the plugin tests.
56+
- Runs the plugin tests.
57+
58+
- `yarn run cypress open`
59+
60+
- Opens the Cypress test runner
61+
62+
- `yarn run cypress run`
63+
64+
- Runs the Cypress test runner
4865

4966
## Contributing to Open Distro for Elasticsearch Index Management Kibana
5067

cypress.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"viewportHeight": 900,
3+
"viewportWidth": 1440,
4+
"defaultCommandTimeout": 10000,
5+
"env": {
6+
"elasticsearch": "localhost:9200",
7+
"kibana": "localhost:5601"
8+
}
9+
}

cypress/.eslintrc.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": ["plugin:cypress/recommended"],
3+
"rules": {
4+
"quotes": ["error", "double", { "allowTemplateLiterals": true }]
5+
}
6+
}

cypress/fixtures/sample_policy.json

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"policy": {
3+
"description": "A simple description",
4+
"default_state": "hot",
5+
"states": [
6+
{
7+
"name": "hot",
8+
"actions": [
9+
{
10+
"replica_count": {
11+
"number_of_replicas": 5
12+
}
13+
}
14+
],
15+
"transitions": [
16+
{
17+
"state_name": "cold",
18+
"conditions": {
19+
"min_index_age": "30d"
20+
}
21+
}
22+
]
23+
},
24+
{
25+
"name": "cold",
26+
"actions": [
27+
{
28+
"replica_count": {
29+
"number_of_replicas": 2
30+
}
31+
}
32+
],
33+
"transitions": []
34+
}
35+
]
36+
}
37+
}

cypress/integration/indices_spec.js

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
import { PLUGIN_NAME } from "../support/constants";
17+
import samplePolicy from "../fixtures/sample_policy";
18+
19+
const POLICY_ID = "test_policy_id";
20+
const SAMPLE_INDEX = "sample_index";
21+
22+
describe("Indices", () => {
23+
beforeEach(() => {
24+
// Set welcome screen tracking to false
25+
localStorage.setItem("home:welcome:show", "false");
26+
27+
// Visit ISM Kibana
28+
cy.visit(`${Cypress.env("kibana")}/app/${PLUGIN_NAME}#/indices`);
29+
30+
// Common text to wait for to confirm page loaded, give up to 60 seconds for initial load
31+
cy.contains("Rows per page", { timeout: 60000 });
32+
});
33+
34+
describe("can be searched", () => {
35+
before(() => {
36+
cy.deleteAllIndices();
37+
// Create 20+ indices that can be sorted alphabetically by using letters a-z
38+
for (let i = 97; i < 123; i++) {
39+
const char = String.fromCharCode(i);
40+
cy.createIndex(`index_${char}`);
41+
}
42+
});
43+
44+
it("successfully", () => {
45+
// Get the index table header and click it to sort
46+
cy.get("thead > tr > th").contains("Index").click({ force: true });
47+
48+
// Confirm we have index_a in view and not index_z
49+
cy.contains("index_a");
50+
cy.contains("index_z").should("not.exist");
51+
52+
// Type in index_z in search input
53+
cy.get(`input[type="search"]`).focus().type("index_z");
54+
55+
// Confirm we only see index_z in table
56+
cy.get("tbody > tr").should(($tr) => {
57+
expect($tr, "1 row").to.have.length(1);
58+
expect($tr, "item").to.contain("index_z");
59+
});
60+
});
61+
});
62+
63+
describe("can have policies applied", () => {
64+
before(() => {
65+
cy.deleteAllIndices();
66+
cy.createPolicy(POLICY_ID, samplePolicy);
67+
cy.createIndex(SAMPLE_INDEX);
68+
});
69+
70+
it("successfully", () => {
71+
// Confirm we have our initial index
72+
cy.contains(SAMPLE_INDEX);
73+
74+
// Confirm our initial index is not currently managed
75+
cy.get(`tbody > tr:contains("${SAMPLE_INDEX}") > td`).filter(`:nth-child(4)`).contains("No");
76+
77+
// Select checkbox for our index
78+
cy.get(`[data-test-subj="checkboxSelectRow-${SAMPLE_INDEX}"]`).check({ force: true });
79+
80+
// Click apply policy button
81+
cy.get(`[data-test-subj="Apply policyButton"]`).click({ force: true });
82+
83+
cy.get(`input[data-test-subj="comboBoxSearchInput"]`).focus().type(POLICY_ID, { parseSpecialCharSequences: false, delay: 1 });
84+
85+
// Click the policy option
86+
cy.get(`button[role="option"]`).first().click({ force: true });
87+
88+
cy.contains("A simple description");
89+
90+
cy.get(`[data-test-subj="applyPolicyModalEditButton"]`).click({ force: true });
91+
92+
cy.reload();
93+
94+
cy.contains(SAMPLE_INDEX, { timeout: 20000 });
95+
96+
// Confirm our index is now being managed
97+
cy.get(`tbody > tr:contains("${SAMPLE_INDEX}") > td`).filter(`:nth-child(4)`).contains("Yes");
98+
});
99+
});
100+
});

0 commit comments

Comments
 (0)