summaryrefslogtreecommitdiffstats
path: root/cucumber-js-test-apis-ci/cucumber-common
diff options
context:
space:
mode:
Diffstat (limited to 'cucumber-js-test-apis-ci/cucumber-common')
-rw-r--r--cucumber-js-test-apis-ci/cucumber-common/package.json37
-rw-r--r--cucumber-js-test-apis-ci/cucumber-common/plugins/README.md30
-rw-r--r--cucumber-js-test-apis-ci/cucumber-common/plugins/jsdoc_config.json16
-rw-r--r--cucumber-js-test-apis-ci/cucumber-common/plugins/reporter.js31
-rw-r--r--cucumber-js-test-apis-ci/cucumber-common/plugins/steps.js65
-rw-r--r--cucumber-js-test-apis-ci/cucumber-common/stepDefinitions/world.js107
-rw-r--r--cucumber-js-test-apis-ci/cucumber-common/utils/UpdateTestConfig.js81
-rw-r--r--cucumber-js-test-apis-ci/cucumber-common/utils/Utils.js223
8 files changed, 590 insertions, 0 deletions
diff --git a/cucumber-js-test-apis-ci/cucumber-common/package.json b/cucumber-js-test-apis-ci/cucumber-common/package.json
new file mode 100644
index 0000000000..1efc8f12ad
--- /dev/null
+++ b/cucumber-js-test-apis-ci/cucumber-common/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "cucumber-common",
+ "version": "1.0.14",
+ "description": "Cucumber common methods and utilities",
+ "repository": "",
+ "main": "index.js",
+ "directories": {
+ "doc": "docs"
+ },
+ "scripts": {
+ "test": "cucumber-js",
+ "test-and-report": "npm-run-all -c -s test cucumber-html-report",
+ "cucumber-html-report": "node plugins/reporter.js",
+ "cucumber-docs": "jsdoc ./stepDefinitions -c plugins/jsdoc_config.json --readme plugins/README.md"
+ },
+ "author": "",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "assert": "^1.4.1",
+ "btoa": "^1.2.1",
+ "cucumber": "^5.1.0",
+ "cucumber-html-reporter": "^4.0.4",
+ "docdash": "^1.0.2",
+ "find-up": "^4.1.0",
+ "jsdoc": "^3.5.5",
+ "jsdoc-one-page": "0.0.5",
+ "lodash": "^4.17.11",
+ "md5": "^2.2.1",
+ "needle": "^2.4.0",
+ "node-zip": "^1.1.1",
+ "normalize-newline": "^3.0.0",
+ "npm-run-all": "^4.1.2",
+ "request": "^2.83.0",
+ "yamljs": "^0.3.0"
+ },
+ "devDependencies": {}
+}
diff --git a/cucumber-js-test-apis-ci/cucumber-common/plugins/README.md b/cucumber-js-test-apis-ci/cucumber-common/plugins/README.md
new file mode 100644
index 0000000000..9eaeb8f3a6
--- /dev/null
+++ b/cucumber-js-test-apis-ci/cucumber-common/plugins/README.md
@@ -0,0 +1,30 @@
+<br>
+<h1>Welcome!</h1>
+This is the documentation for using the BDD testing framework for SDC.<br>
+The Modules on the left contains all steps for particalar aress and/or explanations of what they do.<br>
+<br><br>
+<h3>How to set the server configuration</h3>
+<li> Copy the config.json to devConfig.json
+<li> Replace the server and user values with the correct values
+<h3>How to run with Maven</h3>
+<li>"mvn clean install" will install npm if needed, download all modules
+<li> run "mvn install -DskipTests=true -P dev" to create the documentation under the "docs" folder
+<li>"mvn test -P dev" will run all tests in the features folder and create an HTML report under the "reports" folder
+<h3>How to develop tests</h3>
+You can open the project in IntelliJ and Webstorm to run and develop scenarios.<br>
+<li><b>You will need to install the Cucumber.Js plugin</b> In order to install, go to "Settings/Plugins". If cucumber.js in not on the list, go to "Browse repositories.." and install .
+<li>First time only: Right click on feature file and try to run. Now go to "Run/edit configurations" and set the "executable path" to the "node_modules\.bin\cucumber-js.cmd" under your current project.
+<li>Now you can run the feature files by right clicking on the file and selecting "Run" from IDEA.<br>
+<li>Add to existing scenarios or create new files under the "features" directory for additional tests
+<br>
+<li>You can also run a specific test from the command line by running "npm run test -- [features/path to file]
+<h3>More Information</h3>
+<li> More on <a href="https://cucumber.io/docs/reference">Cucumber</a>
+<li> More on <a herf="https://github.com/cucumber/cucumber/wiki/Gherkin">Gherkin</a>
+<li> More on <a href="https://github.com/cucumber/cucumber-js">Cucumber-js</a>
+<br>
+<h3>How to run the docker</h3>
+<li>"mvn clean install -P docker" will create the docker images
+<li>the "docker_run.sh" script will start all ONAP images and run the cucumber docker against them
+<li> environment variables that can be set to change the server/version: IMAGES_TAG (default 1.4-STAGING-latest), TEST_CI_BE_HOST (deafult - machine IP), TEST_CI_CATALOG_PORT (default 8080)
+
diff --git a/cucumber-js-test-apis-ci/cucumber-common/plugins/jsdoc_config.json b/cucumber-js-test-apis-ci/cucumber-common/plugins/jsdoc_config.json
new file mode 100644
index 0000000000..2757000472
--- /dev/null
+++ b/cucumber-js-test-apis-ci/cucumber-common/plugins/jsdoc_config.json
@@ -0,0 +1,16 @@
+{
+ "tags": {
+ "allowUnknownTags": true
+ },
+ "templates": {
+ "default": {
+ "outputSourceFiles": false
+ }
+ },
+
+ "plugins": ["./steps"],
+ "opts": {
+ "template": "node_modules/jsdoc-one-page",
+ "destination": "docs/"
+ }
+} \ No newline at end of file
diff --git a/cucumber-js-test-apis-ci/cucumber-common/plugins/reporter.js b/cucumber-js-test-apis-ci/cucumber-common/plugins/reporter.js
new file mode 100644
index 0000000000..8913789c95
--- /dev/null
+++ b/cucumber-js-test-apis-ci/cucumber-common/plugins/reporter.js
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var reporter = require('cucumber-html-reporter');
+
+var options = {
+ theme: 'bootstrap',
+ jsonFile: 'report/report.json',
+ output: 'report/report.html',
+ reportSuiteAsScenarios: true,
+ launchReport: false,
+ metadata: {
+ "ONAP" : "Some build",
+ "Executed": "Local"
+ }
+};
+
+reporter.generate(options);
+
diff --git a/cucumber-js-test-apis-ci/cucumber-common/plugins/steps.js b/cucumber-js-test-apis-ci/cucumber-common/plugins/steps.js
new file mode 100644
index 0000000000..2faa7efbd8
--- /dev/null
+++ b/cucumber-js-test-apis-ci/cucumber-common/plugins/steps.js
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @module plugins/steptag
+ */
+'use strict';
+
+
+exports.handlers = {
+ /**
+ * Support @step tag.
+ *
+ * @step description
+ */
+ newDoclet: function(e) {
+ var tags = e.doclet.tags;
+ var tag;
+ var value;
+
+ // any user-defined tags in this doclet?
+ if (typeof tags !== 'undefined') {
+
+ tags = tags.filter(function($) {
+ return $.title === 'step' || $.title === 'examplefile';
+ });
+
+ if (tags.length) {
+ // take the first one
+ tag = tags[0];
+ let step = null;
+ let exampleFile = null;
+ for (tag in tags) {
+ if (tags[tag].title === "step") {
+ step = "<b>" + tags[tag].value + "</b><br>";
+ }
+ if (tags[tag].title === "examplefile") {
+ exampleFile = "<i> Example Features File: " + tags[tag].value + "</i><br>";
+ }
+ }
+ if (exampleFile !== null) {
+ step += exampleFile;
+ }
+ e.doclet.meta = e.doclet.meta || {};
+ if (e.doclet.description !== undefined) {
+ e.doclet.description = step + e.doclet.description;
+ } else {
+ e.doclet.description = step;
+ }
+ }
+ }
+ }
+}; \ No newline at end of file
diff --git a/cucumber-js-test-apis-ci/cucumber-common/stepDefinitions/world.js b/cucumber-js-test-apis-ci/cucumber-common/stepDefinitions/world.js
new file mode 100644
index 0000000000..7811aba886
--- /dev/null
+++ b/cucumber-js-test-apis-ci/cucumber-common/stepDefinitions/world.js
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+const { setWorldConstructor } = require('cucumber');
+const _ = require('lodash');
+const findUp = require('find-up');
+
+
+
+let configPath = findUp.sync('config.json');
+configPath = configPath.replace(/\\/g, '/');
+
+let config = require(configPath);
+let localConfig = {};
+try {
+ let devConfigPath = findUp.sync('devConfig.json');
+ devConfigPath = devConfigPath.replace(/\\/g, '/');
+ localConfig = require(devConfigPath);
+} catch (e) {
+ try {
+ let envdir = findUp.sync('environments', {type: 'directory'});
+ envdir = envdir.replace(/\\/g, '/');
+ localConfig = require(envdir + '/dockerConfig.json');
+ } catch (e) {
+ console.error("no env configuration was found!");
+ }
+}
+
+config = _.merge(config, localConfig);
+var {setDefaultTimeout} = require('cucumber');
+
+
+/**
+ * @module Context
+ * @description Context that is used per feature file and can be accessed as 'this.context' in all steps.<Br>
+ * This class can be extended in order to add additional configurations.
+ *<Br>
+ * Contains the following items:<br>
+ * <li>this.context.server <ul>REST server and onboarding prefix including version. set either in configuration file or from the command line or SERVER environment variable</ul>
+ * <li>this.context.item <ul>When a VLM or VSP has been created, this has the an id and versionId set to the correct IDs.</ul>
+ * <li>this.context <ul>Object with properties that were saved in the steps.</ul>
+ * <li>this.context.inputdata <ul><b>Automatically updated with the last responseData from the Rest call</b><br>Object with properties that were prepares in the steps.</ul>
+ * <li>this.context.responseData <ul>Response from the last REST call.</ul>
+ **/
+class CustomWorld {
+ constructor(options) {
+ this.context = {};
+ this.context.headers = {};
+ let typeName;
+
+ this.context.defaultServerType = 'main';
+ for (typeName in config) {
+ this.context.headers[typeName] = {};
+ if (config[typeName].user) {
+ this.context.headers[typeName]['USER_ID'] = config[typeName].user;
+ }
+ // adding additional headers
+ if (config[typeName].additionalHeaders) {
+ _.assign(this.context.headers[typeName] , config[typeName].additionalHeaders);
+ }
+ if (config[typeName].isDefault !== undefined && config[typeName].isDefault) {
+ this.context.defaultServerType = typeName;
+ }
+ }
+ this.context.item = {id: null, versionId: null, componentId: null};
+ // adding the default items that should also be initialized
+ if (config.initData) {
+ _.assign(this.context, config.initData);
+ }
+
+ this.context.shouldFail = false;
+ this.context.errorCode = null;
+ this.context.inputData = null;
+ this.context.responseData = null;
+
+
+ this.config = config;
+
+ let context = this.context;
+ this.context.getUrlForType = (function(type) {
+ var _server = context.server;
+ var _config = config;
+ return function(type) {
+ let typeData = _config[type];
+ let _url = typeData.protocol + '://' +
+ typeData.server + ':' +
+ typeData.port + '/' +
+ typeData.prefix;
+ return _url;
+ }
+ })();
+ setDefaultTimeout(60 * 1000);
+ }
+}
+setWorldConstructor(CustomWorld);
diff --git a/cucumber-js-test-apis-ci/cucumber-common/utils/UpdateTestConfig.js b/cucumber-js-test-apis-ci/cucumber-common/utils/UpdateTestConfig.js
new file mode 100644
index 0000000000..a2c1dae2f7
--- /dev/null
+++ b/cucumber-js-test-apis-ci/cucumber-common/utils/UpdateTestConfig.js
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+'use strict'
+
+const fs = require('fs');
+
+var pathToRoot = process.env.TESTS_BASE;
+if (!pathToRoot.endsWith("/")) {
+ pathToRoot += "/";
+}
+var envConfig = require(pathToRoot + 'config.json');
+var protocol = (process.env.PROTOCOL !== undefined) ? process.env.PROTOCOL : 'https';
+
+try {
+ envConfig = require(pathToRoot + 'environments/dockerConfig.json');
+} catch (e) {
+}
+
+function run() {
+ var inputArgs = process.argv.slice(2);
+ let changeConfig = false;
+ if (process.env.K8S_CONF_PATH !== undefined) {
+ console.log('updating with kubernetes services');
+ let k8sConfig = require(pathToRoot + process.env.K8S_CONF_PATH);
+ mapK8sPod2Docker(k8sConfig, inputArgs[0], inputArgs[1]);
+ changeConfig = true;
+ } else {
+ console.log('not updating at all');
+ }
+ if (changeConfig) {
+ let data = JSON.stringify(envConfig, null, 2);
+ console.log('writing config file: ' + pathToRoot+'environments/dockerConfig.json');
+ console.log(data);
+ fs.writeFileSync(pathToRoot+'environments/dockerConfig.json', data);
+ }
+}
+
+function mapK8sPod2Docker(k8sConfig, id, k8sid) {
+ let item = k8sConfig.items.find(item => {
+ if (item.spec !== undefined && item.spec.ports !== undefined) {
+ let spec = item.spec.ports.find(port => {
+ if (port.name === k8sid) {
+ return true;
+ }
+ });
+ return (spec !== undefined);
+ } else {
+ return false;
+ }
+ });
+
+ item.spec.ports.forEach(port => {
+ if (port.name === k8sid) {
+ envConfig[id].port = port.nodePort;
+ let rancherData = JSON.parse(item.metadata.annotations["field.cattle.io/publicEndpoints"]);
+ let address = rancherData.find(address => {
+ return address.port === port.nodePort;
+ });
+ envConfig[id].port = address.port;
+ envConfig[id].server = address.addresses[0];
+ envConfig[id].protocol = protocol;
+ envConfig[id].user = process.env.SDC_USER_ID;
+ }
+ });
+
+}
+
+run();
diff --git a/cucumber-js-test-apis-ci/cucumber-common/utils/Utils.js b/cucumber-js-test-apis-ci/cucumber-common/utils/Utils.js
new file mode 100644
index 0000000000..22ee775080
--- /dev/null
+++ b/cucumber-js-test-apis-ci/cucumber-common/utils/Utils.js
@@ -0,0 +1,223 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+const needle = require('needle');
+const fs = require('fs');
+require('node-zip');
+var btoa = require('btoa');
+const md5 = require('md5');
+const _ = require('lodash');
+
+function getOptionsForRequest(context, method, path, type) {
+ if (type == undefined || type == null) {
+ type = context.defaultServerType
+ }
+ let server = context.getUrlForType(type);
+ let options = {
+ method: method,
+ url: server + path,
+ headers: _.clone(context.headers[type])
+ };
+// options.headers["Content-Type"] = "application/json";
+// options.headers["accept"] = "application/json";
+ return options;
+}
+
+function _requestBinaryFormData(context, method, path, fileName, formInputName, type) {
+ let options = getOptionsForRequest(context, method, path, type);
+ let formData = {};
+ if (method === 'POST' || method === 'PUT') {
+ //formData[formInputName] = fs.createReadStream(fileName);
+ //options.formData = formData;
+ let fileData = {
+ file: fileName
+ };
+ fileData['content_type'] = 'multipart/form-data';
+ options.formData = {};
+ options.formData[formInputName] = fileData;
+ }
+ return _request(context, method, path, options);
+}
+function _requestBinaryBody(context, method, path, fileName, type) {
+ let options = getOptionsForRequest(context, method, path, type);
+ if (method === 'POST' || method === 'PUT') {
+ options.body = fs.createReadStream(fileName);
+ options.headers['Content-Type'] = 'application/octet-stream';
+
+ }
+ return _request(context, method, path, options);
+}
+
+
+function _requestPayload(context, method, path, filePath, type) {
+ let options = getOptionsForRequest(context, method, path, type);
+ options.json = _createPayload(filePath);
+ options.headers['Content-MD5'] = addCheckSum(options.json);
+ return _request(context, method, path, options);
+}
+
+function _requestRest(context, method, path, data, type) {
+ let options = getOptionsForRequest(context, method, path, type);
+ if (method === 'POST' || method === 'PUT') {
+ options.json = data;
+ }
+ return _request(context, method, path, options);
+}
+
+function _request(context, method, path, options) {
+ console.log('--> Calling REST ' + options.method +' url: ' + options.url);
+ let inputData = options.json;
+ let needleOptions = {headers: options.headers, rejectUnauthorized: false};
+ if (inputData == undefined) {
+ if (options.formData != undefined) {
+ inputData = options.formData;
+ needleOptions.multipart = true;
+ }
+ if (inputData && inputData.body != undefined) {
+ inputData = options.body;
+ }
+ } else {
+ needleOptions.json = true;
+ }
+ return needle(method, options.url, inputData, needleOptions)
+ .then(function(result) {
+ context.inputData = null;
+ let isExpected = (context.shouldFail) ? (result.statusCode != 200 && result.statusCode != 201) : (result.statusCode == 200 || result.statusCode == 201);
+ data = result.body;
+ if (!isExpected) {
+ console.log('Did not get expected response code');
+ throw 'Status Code was ' + result.statusCode ;
+ }
+ if (context.shouldFail && context.errorCode) {
+ if (typeof data === 'string' && data) {
+ data = JSON.parse(data);
+ }
+ let errorCode = data.errorCode;
+ let contextErrorCode = context.errorCode;
+ context.errorCode = null;
+ if (errorCode !== contextErrorCode) {
+ throw 'Error Code was ' + errorCode + ' instead of ' + contextErrorCode;
+ }
+ }
+ if (context.shouldFail && context.errorMessage) {
+ if (typeof data === 'string' && data) {
+ data = JSON.parse(data);
+ }
+ let errorMessage = data.message;
+ let contextErrorMessage = context.errorMessage;
+ context.errorMessage = null;
+ if (errorMessage !== contextErrorMessage) {
+ throw 'Error Message was ' + errorMessage + ' instead of ' + contextErrorMessage;
+ }
+ }
+ if (context.shouldFail) {
+ context.shouldFail = false;
+ return({statusCode: result.statusCode, data: {}});
+ }
+
+ if (typeof data === 'string' && data) {
+ if (data.startsWith('[') || data.startsWith('{')) {
+ data = JSON.parse(data);
+ }
+ }
+ context.responseData = data;
+ context.inputData = data;
+ return({statusCode: result.statusCode, data: data});
+
+ })
+ .catch(function(err) {
+ console.error('Request URL: ' + options.url);
+ console.error('Request Method: ' + options.method);
+ console.log(err);
+ throw err;
+ })
+}
+
+function download(context, path, filePath, type) {
+ if (type == undefined || type == null) {
+ type = context.defaultServerType
+ }
+ let server = context.getUrlForType(type);
+ let options = {
+ method: 'GET',
+ url: server + path,
+ headers: context.headers[type]
+ };
+
+ console.log('--> Calling REST download url: ' + options.url);
+ return needle('GET', options.url, {}, {
+ headers: options.headers,
+ rejectUnauthorized: false,
+ output: filePath
+ })
+ .then(function (result) {
+ let zipFile = fs.readFileSync(filePath, 'binary');
+ let zip = new JSZip(zipFile, {base64: false, checkCRC32: true});
+ if (zip.files['MANIFEST.json']) {
+ let manifestData = zip.files['MANIFEST.json']._data;
+ manifestData = manifestData.replace(/\\n/g, '');
+ context.responseData = JSON.parse(manifestData);
+ }
+ return zip;
+ })
+ .catch(function (err) {
+ console.error('Request URL: ' + options.url);
+ console.error('Request Method: ' + options.method);
+ throw err;
+ })
+}
+
+function _random() {
+ let d = new Date();
+ return d.getTime().toString().split('').reverse().join('');
+}
+
+function _getJSONFromFile(file) {
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
+}
+
+function _createPayload(fileName) {
+ var body = fs.readFileSync(fileName);
+ let payload = {
+ payloadData: body.toString('base64'),
+ payloadName: fileName.substring(fileName.lastIndexOf("/") + 1 )
+ };
+ return payload;
+}
+
+function addCheckSum(payloadData) {
+ let _md5 = md5(JSON.stringify(payloadData));
+ return btoa(_md5.toLowerCase());
+}
+
+function _getFile(file, format) {
+ if(format === '' ){
+ return fs.readFileSync(file)
+ }
+ return fs.readFileSync(file, format);
+}
+
+
+module.exports = {
+ getFile: _getFile,
+ request: _requestRest,
+ requestPayload: _requestPayload,
+ requestBinaryFormData: _requestBinaryFormData,
+ requestBinaryBody: _requestBinaryBody,
+ random : _random,
+ getJSONFromFile: _getJSONFromFile,
+ download: download,
+ payload: _createPayload
+};