From 57df9b1e64b1d40d77325c942a5269cf46e0cccf Mon Sep 17 00:00:00 2001 From: thuva4 Date: Mon, 30 Oct 2017 20:43:36 +0530 Subject: add simple e2e tests for PodsCotroller Change-Id: I9baa04ff062f36569c1e143014239931de64cf32 Signed-off-by: thuva4 --- testapi/.gitignore | 2 + testapi/3rd_party/static/testapi-ui/Gruntfile.js | 155 +++++++++++++++++ testapi/3rd_party/static/testapi-ui/package.json | 18 ++ .../tests/UI/e2e/podsControllerSpec.js | 188 +++++++++++++++++++++ testapi/opnfv_testapi/tests/UI/karma.conf.js | 14 ++ testapi/opnfv_testapi/tests/UI/protractor-conf.js | 18 ++ 6 files changed, 395 insertions(+) create mode 100644 testapi/3rd_party/static/testapi-ui/Gruntfile.js create mode 100644 testapi/3rd_party/static/testapi-ui/package.json create mode 100644 testapi/opnfv_testapi/tests/UI/e2e/podsControllerSpec.js create mode 100644 testapi/opnfv_testapi/tests/UI/karma.conf.js create mode 100644 testapi/opnfv_testapi/tests/UI/protractor-conf.js (limited to 'testapi') diff --git a/testapi/.gitignore b/testapi/.gitignore index 21bb264..e34365e 100644 --- a/testapi/.gitignore +++ b/testapi/.gitignore @@ -11,3 +11,5 @@ build .tox .ven docs/_build +opnfv_testapi/tests/UI/coverage +3rd_party/static/testapi-ui/testapi-ui \ No newline at end of file diff --git a/testapi/3rd_party/static/testapi-ui/Gruntfile.js b/testapi/3rd_party/static/testapi-ui/Gruntfile.js new file mode 100644 index 0000000..8ff2802 --- /dev/null +++ b/testapi/3rd_party/static/testapi-ui/Gruntfile.js @@ -0,0 +1,155 @@ + +module.exports = function (grunt) { + require('load-grunt-tasks')(grunt); + require('grunt-protractor-coverage')(grunt); + grunt.loadNpmTasks('grunt-shell-spawn'); + grunt.loadNpmTasks('grunt-wait'); + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.initConfig({ + connect: { + server: { + options: { + port: 8000, + base: './', + middleware: function(connect, options, middlewares) { + middlewares.unshift(function(req, res, next) { + if (req.method.toUpperCase() == 'POST') req.method='GET'; + return next(); + }); + return middlewares; + } + } + } + }, + copy: { + assets: { + expand: true, + cwd: 'assets', + src: '**', + dest: 'testapi-ui/assets', + }, + components: { + expand: true, + cwd: 'components', + src: '**', + dest: 'testapi-ui/components', + }, + shared: { + expand: true, + cwd: 'shared', + src: '**', + dest: 'testapi-ui/shared', + }, + filesPng: { + expand: true, + src: '*.png', + dest: 'testapi-ui/', + }, + filesIco: { + expand: true, + src: '*.ico', + dest: 'testapi-ui/', + }, + filesJs: { + expand: true, + src: 'app.js', + dest: 'testapi-ui/', + }, + filesJson: { + expand: true, + src: 'config.json', + dest: 'testapi-ui/', + } + }, + wait: { + default: { + options: { + delay: 3000 + } + } + }, + shell: { + updateSelenium: { + command: 'node_modules/protractor/bin/webdriver-manager update', + options: { + async: false + } + }, + startSelenium: { + command: 'node_modules/protractor/bin/webdriver-manager start', + options: { + async: true + } + }, + options: { + stdout: false, + stderr: false + } + }, + instrument: { + files: ['components/**/*.js'], + options: { + lazy: false, + basePath: "./testapi-ui/" + } + }, + karma: { + unit: { + configFile: '../../../opnfv_testapi/tests/UI/karma.conf.js' + } + }, + protractor_coverage: { + options: { + keepAlive: true, + noColor: false, + coverageDir: '../../../opnfv_testapi/tests/UI/coverage', + args: { + specs: ['../../../opnfv_testapi/tests/UI/e2e/podsControllerSpec.js'] + } + }, + local: { + options: { + configFile: '../../../opnfv_testapi/tests/UI/protractor-conf.js' + } + } + }, + makeReport: { + src: '../../../opnfv_testapi/tests/UI/coverage/*.json', + options: { + print: 'detail' + } + }, + protractor: { + e2e: { + options: { + args: { + specs: ['../../../opnfv_testapi/tests/UI/e2e/podsControllerSpec.js'] + }, + configFile: '../../../opnfv_testapi/tests/UI/protractor-conf.js', + keepAlive: true + } + } + } + }); + grunt.registerTask('test', [ + 'karma:unit' + ]); + grunt.registerTask('e2e', [ + 'copy:assets', + 'copy:components', + 'copy:shared', + 'copy:filesPng', + 'copy:filesIco', + 'copy:filesJs', + 'copy:filesJson', + 'instrument', + 'connect', + 'shell:updateSelenium', + 'shell:startSelenium', + 'wait:default', + 'protractor_coverage', + 'makeReport' + // 'protractor' + ]); +} diff --git a/testapi/3rd_party/static/testapi-ui/package.json b/testapi/3rd_party/static/testapi-ui/package.json new file mode 100644 index 0000000..dc99239 --- /dev/null +++ b/testapi/3rd_party/static/testapi-ui/package.json @@ -0,0 +1,18 @@ +{ + "devDependencies": { + "grunt": "~1.0.1", + "grunt-contrib-connect": "^1.0.2", + "grunt-contrib-copy": "^1.0.0", + "grunt-karma": "~2.0.0", + "grunt-protractor-coverage": "^0.2.18", + "grunt-protractor-runner": "~5.0.0", + "grunt-shell-spawn": "~0.3.10", + "grunt-wait": "~0.1.0", + "karma": "~1.7.1", + "karma-chrome-launcher": "~2.2.0", + "karma-coverage": "~1.1.1", + "karma-jasmine": "~1.1.0", + "load-grunt-tasks": "~3.5.2", + "protractor-http-mock": "^0.10.0" + } +} diff --git a/testapi/opnfv_testapi/tests/UI/e2e/podsControllerSpec.js b/testapi/opnfv_testapi/tests/UI/e2e/podsControllerSpec.js new file mode 100644 index 0000000..66a57f2 --- /dev/null +++ b/testapi/opnfv_testapi/tests/UI/e2e/podsControllerSpec.js @@ -0,0 +1,188 @@ +'use strict'; + +var mock = require('protractor-http-mock'); +var baseURL = "http://localhost:8000" +describe('testing the Pods page for anonymous user', function () { + + beforeEach(function(){ + mock([{ + request: { + path: '/api/v1/pods', + method: 'GET' + }, + response: { + data: { + pods: [{role: "community-ci", name: "test", owner: "testUser", details: "DemoDetails", mode: "metal", _id: "59f02f099a07c84bfc5c7aed", creation_date: "2017-10-25 11:58:25.926168"}] + } + } + }]); + }); + + it( 'should navigate to pods link ', function() { + browser.get(baseURL); + var podslink = element(by.linkText('Pods')).click(); + var EC = browser.ExpectedConditions; + browser.wait(EC.urlContains(baseURL+ '/#/pods'), 10000); + }); + + it('create button is not visible for anonymous user', function () { + browser.get(baseURL+'#/pods'); + var buttonCreate = element(by.buttonText('Create')); + expect(buttonCreate.isDisplayed()).toBeFalsy(); + }); + + it('filter button is visible for anonymous user', function () { + var buttonFilter = element(by.buttonText('Filter')); + expect(buttonFilter.isDisplayed()).toBe(true) + }); + + it('clear button is visible for anonymous user', function () { + var buttonClear = element(by.buttonText('Clear')); + expect(buttonClear.isDisplayed()).toBe(true) + }); + + it('Show results when click filter button', function () { + var buttonFilter = element(by.buttonText('Filter')); + buttonFilter.click(); + var pod = element(by.css('.show-pod')); + expect(pod.isPresent()).toBe(true); + }); + + it('Show results when click clear button', function () { + browser.get(baseURL+'#/pods'); + var buttonClear = element(by.buttonText('Clear')); + buttonClear.click(); + var pod = element(by.css('.show-pod')); + expect(pod.isPresent()).toBe(true); + }); + + it('If details is not shown then show details when click the link',function() { + expect(element(by.css('.show-pod.hidden')).isPresent()).toBe(true); + var podslink = element(by.linkText('test')).click(); + expect(element(by.css('.show-pod.hidden')).isPresent()).toBe(false); + }); + + it('If details is shown then hide details when click the link',function() { + expect(element(by.css('.show-pod.hidden')).isPresent()).toBe(false); + var podslink = element(by.linkText('test')).click(); + expect(element(by.css('.show-pod.hidden')).isPresent()).toBe(true); + }); + + it('If backend is not responding then show error when click filter button', function () { + browser.get(baseURL + '/#/pods'); + mock.teardown(); + var buttonFilter = element(by.buttonText('Filter')); + buttonFilter.click().then(function(){ + expect(element(by.css('.alert.alert-danger.ng-binding.ng-scope')).isDisplayed()).toBe(true); + }); + }); + +}); + +describe('testing the Pods page for authorized user', function () { + + beforeEach(function(){ + mock([ + { + request: { + path: '/api/v1/pods', + method: 'POST' + }, + response: { + data: { + href: baseURL+"/api/v1/pods/test" + } + } + }, + { + request: { + path: '/api/v1/pods', + method: 'POST', + data: { + name: 'test1', + details : 'DemoDetails', + role : 'community-ci', + mode : 'metal' + } + }, + response: { + status : 403 + } + }, + { + request: { + path: '/api/v1/profile', + method: 'GET' + }, + response: { + data: { + "fullname": "Test User", "_id": "79f82eey9a00c84bfhc7aed", "user": "testUser", "groups": ["opnfv-testapi-users"], "email": "testuser@test.com" + } + } + } + ]); + }); + + it('create button is visible for authorized user', function () { + browser.get(baseURL + '/#/pods'); + var buttonCreate = element(by.buttonText('Create')); + expect(buttonCreate.isDisplayed()).toBe(true); + }); + + it('Do not show error if input is acceptable', function () { + var name = element(by.model('ctrl.name')); + var details = element(by.model('ctrl.details')); + name.sendKeys('test'); + details.sendKeys('DemoDetails'); + var buttonCreate = element(by.buttonText('Create')); + buttonCreate.click().then(function(){ + expect(element(by.css('.alert.alert-danger.ng-binding.ng-scope')).isDisplayed()).toBe(false); + }); + }); + + it('Show error when user click the create button with a empty name', function () { + browser.get(baseURL+ '/#/pods'); + var details = element(by.model('ctrl.details')); + details.sendKeys('DemoDetails'); + var buttonCreate = element(by.buttonText('Create')); + buttonCreate.click(); + expect(element(by.cssContainingText(".alert","Name is missing.")).isDisplayed()).toBe(true); + }); + + it('Show error when user click the create button with an already existing name', function () { + browser.get(baseURL+ '/#/pods'); + var name = element(by.model('ctrl.name')); + var details = element(by.model('ctrl.details')); + name.sendKeys('test1'); + details.sendKeys('DemoDetails'); + var buttonCreate = element(by.buttonText('Create')); + buttonCreate.click(); + expect(element(by.cssContainingText(".alert","Error creating the new pod from server: Pod's name already exists")).isDisplayed()).toBe(true); + }); + + it('If backend is not responding then show error when user click the create button',function(){ + mock.teardown(); + mock([ + { + request: { + path: '/api/v1/profile', + method: 'GET' + }, + response: { + data: { + "fullname": "Test User", "_id": "79f82eey9a00c84bfhc7aed", "user": "testUser", "groups": ["opnfv-testapi-users"], "email": "testuser@test.com" + } + } + } + ]); + browser.get(baseURL+ '/#/pods'); + var name = element(by.model('ctrl.name')); + var details = element(by.model('ctrl.details')); + name.sendKeys('test'); + details.sendKeys('DemoDetails'); + var buttonCreate = element(by.buttonText('Create')); + buttonCreate.click().then(function(){ + expect(element(by.css('.alert.alert-danger.ng-binding.ng-scope')).isDisplayed()).toBe(true); + }); + }) +}); \ No newline at end of file diff --git a/testapi/opnfv_testapi/tests/UI/karma.conf.js b/testapi/opnfv_testapi/tests/UI/karma.conf.js new file mode 100644 index 0000000..eaded5a --- /dev/null +++ b/testapi/opnfv_testapi/tests/UI/karma.conf.js @@ -0,0 +1,14 @@ +module.exports = function (config) { + config.set({ + frameworks: ['jasmine'], + files: [ + "assets/lib/angular/angular.js", + "assets/lib/angular-mocks/angular-mocks.js", + ], + autoWatch: true, + browsers: ['Chrome'], + singleRun: true, + reporters: ['progress', 'coverage'], + preprocessors: { 'src/*.js': ['coverage'] } + }); +}; diff --git a/testapi/opnfv_testapi/tests/UI/protractor-conf.js b/testapi/opnfv_testapi/tests/UI/protractor-conf.js new file mode 100644 index 0000000..affbe5d --- /dev/null +++ b/testapi/opnfv_testapi/tests/UI/protractor-conf.js @@ -0,0 +1,18 @@ +exports.config = { + seleniumAddress: 'http://localhost:4444/wd/hub', + capabilities: { + 'browserName': 'chrome', + 'chromeOptions': { + 'args': ['show-fps-counter=true', '--disable-web-security', "no-sandbox", "--headless", "--disable-gpu"] + } + }, + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000 + }, + onPrepare: function(){ + require('protractor-http-mock').config = { + rootDirectory: __dirname + }; + } +}; -- cgit 1.2.3-korg