[CORD-1133] E2E GUI Tests
Change-Id: I521d0cc068a3e328f3d4f421ba4b342bea167e19
diff --git a/e2e/README.md b/e2e/README.md
new file mode 100644
index 0000000..a578c20
--- /dev/null
+++ b/e2e/README.md
@@ -0,0 +1,33 @@
+# End to end test
+
+NOTE: Require protractor to be installed as a global module.
+
+## Setup
+```
+webdriver-manager update
+webdriver-manager start
+```
+
+## Run tests
+
+_Note that this tests are designed to work with the Mock R-CORD config_
+
+```
+protractor conf/protractor.conf.js
+```
+
+Other paramenters you can pass are:
+
+| Variable Name | Description |
+|---------------|--------------------------------------------------------------|
+| UI_URL | Address of the GUI (deaults to `http://192.168.46.100/spa/#` |
+| UI_PWD | Password to login (needed only for remote connections) |
+| TIMEOUT | Time allowed for each test |
+
+ ### Test suites
+
+ If you need to run test for only a particural suite you can use:
+
+ `protractor conf/protractor.conf.js --suite login`
+
+ Suites are defined in `cong/protractor.conf.js`
\ No newline at end of file
diff --git a/e2e/crud/crud.po.js b/e2e/crud/crud.po.js
new file mode 100644
index 0000000..6568819
--- /dev/null
+++ b/e2e/crud/crud.po.js
@@ -0,0 +1,21 @@
+module.exports = new function(){
+
+ // list view
+ this.tableRows = element.all(by.repeater('item in vm.data'));
+ this.tableColumn = element(by.repeater('item in vm.data').row(0))
+ .all(by.repeater('col in vm.columns'));
+
+ this.actionsColumn = element(by.repeater('item in vm.data').row(0))
+ .element(by.css('td:last-child'));
+
+ this.deleteBtn = this.actionsColumn.all(by.tagName('a'));
+
+ this.addBtn = element(by.linkText('Add'));
+
+ // detail page
+ this.formInputs = element.all(by.repeater('field in vm.config.inputs'));
+ this.formBtn = element(by.buttonText('Save'));
+
+ this.nameField = element(by.css('[name="name"]'));
+ this.successFeedback = element(by.css('.alert.alert-success'));
+};
diff --git a/e2e/crud/crud.spec.js b/e2e/crud/crud.spec.js
new file mode 100644
index 0000000..f3660b4
--- /dev/null
+++ b/e2e/crud/crud.spec.js
@@ -0,0 +1,51 @@
+const user = require('../test_helpers/user');
+const page = require('./crud.po');
+const config = require('../test_helpers/config');
+
+describe('XOS CRUD Page', function() {
+
+ beforeEach((done) => {
+ user.login()
+ .then(() => {
+ done();
+ });
+ });
+
+ describe('list view', () => {
+ beforeEach(() => {
+ browser.get(`${config.url}/core/nodes/`);
+ });
+ it('should have a table', () => {
+ expect(page.tableRows.count()).toBe(2);
+ expect(page.tableColumn.count()).toBe(5);
+ expect(page.deleteBtn.count()).toBe(1); // per row
+ });
+
+ it('should have an add button', () => {
+ expect(page.addBtn.isDisplayed()).toBeTruthy();
+ page.addBtn.click();
+ expect(browser.getCurrentUrl()).toBe(`${config.url}/core/nodes/add`);
+ });
+ });
+
+ describe('details view', () => {
+
+ describe('for an existing model', () => {
+ beforeEach(() => {
+ browser.get(`${config.url}/core/nodes/1`);
+ });
+ it('should have a form', () => {
+ expect(page.formInputs.count()).toBe(5);
+ expect(page.formBtn.isPresent()).toBeTruthy();
+ });
+
+ it('should save the model', () => {
+ page.nameField.clear().sendKeys('test');
+ page.formBtn.click();
+ expect(page.nameField.getAttribute('value')).toBe('test');
+ expect(page.successFeedback.isDisplayed()).toBeTruthy();
+ browser.sleep(3000)
+ });
+ })
+ });
+});
\ No newline at end of file
diff --git a/e2e/dashboard/dashboard.po.js b/e2e/dashboard/dashboard.po.js
new file mode 100644
index 0000000..18c1ea8
--- /dev/null
+++ b/e2e/dashboard/dashboard.po.js
@@ -0,0 +1,8 @@
+module.exports = new function(){
+
+ this.graphTitle = element(by.css('xos-coarse-tenancy-graph h1'));
+ this.graphSvg = element(by.css('xos-coarse-tenancy-graph svg'));
+
+ this.summaryTitle = element(by.css('xos-dashboard > .row > .col-xs-12 > h2'));
+ this.summaryBoxes = element.all(by.css('.panel.panel-filled'));
+};
diff --git a/e2e/dashboard/dashboard.spec.js b/e2e/dashboard/dashboard.spec.js
new file mode 100644
index 0000000..d18d6b1
--- /dev/null
+++ b/e2e/dashboard/dashboard.spec.js
@@ -0,0 +1,12 @@
+const user = require('../test_helpers/user');
+const dashboardPage = require('./dashboard.po');
+
+describe('XOS Dashboard', function() {
+ it('should have a graph and system summary', () => {
+ user.login();
+ expect(dashboardPage.graphTitle.isPresent()).toBeTruthy();
+ expect(dashboardPage.graphSvg.isPresent()).toBeTruthy();
+ expect(dashboardPage.summaryTitle.isPresent()).toBeTruthy();
+ expect(dashboardPage.summaryBoxes.count()).toBe(3);
+ });
+});
\ No newline at end of file
diff --git a/e2e/keyboard-shortcuts/keyboard.po.js b/e2e/keyboard-shortcuts/keyboard.po.js
new file mode 100644
index 0000000..7c84e62
--- /dev/null
+++ b/e2e/keyboard-shortcuts/keyboard.po.js
@@ -0,0 +1,11 @@
+module.exports = new function(){
+
+ const body = element(by.css('body'));
+
+ this.pressKey = (key) => {
+ body.sendKeys(key);
+ };
+
+ this.sidePanel = element(by.css('xos-side-panel > section'));
+ this.searchField = element(by.model('vm.query'));
+};
diff --git a/e2e/keyboard-shortcuts/shortcut.spec.js b/e2e/keyboard-shortcuts/shortcut.spec.js
new file mode 100644
index 0000000..3756a52
--- /dev/null
+++ b/e2e/keyboard-shortcuts/shortcut.spec.js
@@ -0,0 +1,19 @@
+const user = require('../test_helpers/user');
+const page = require('./keyboard.po');
+
+describe('XOS Keyboard Shortcuts', function() {
+
+ beforeEach(() => {
+ user.login();
+ });
+
+ it('should open the side panel when ? is pressed', () => {
+ page.pressKey('?');
+ expect(page.sidePanel.getAttribute('class')).toMatch('open');
+ });
+
+ it('should select the search form when f is pressed', () => {
+ page.pressKey('f');
+ expect(page.searchField.getAttribute('placeholder')).toEqual(browser.driver.switchTo().activeElement().getAttribute('placeholder'));
+ });
+});
\ No newline at end of file
diff --git a/e2e/login/login.po.js b/e2e/login/login.po.js
new file mode 100644
index 0000000..52c2b3c
--- /dev/null
+++ b/e2e/login/login.po.js
@@ -0,0 +1,18 @@
+module.exports = new function(){
+
+ const usernameField = element(by.model('username'));
+ const passwordField = element(by.model('password'));
+ const submitBtn = element(by.css('.btn.btn-accent'));
+
+ this.sendUsername = (username) => {
+ usernameField.sendKeys(username);
+ };
+
+ this.sendPassword = (pwd) => {
+ passwordField.sendKeys(pwd);
+ };
+
+ this.submit = () => {
+ submitBtn.click();
+ }
+};
diff --git a/e2e/login/login.spec.js b/e2e/login/login.spec.js
new file mode 100644
index 0000000..cab3b15
--- /dev/null
+++ b/e2e/login/login.spec.js
@@ -0,0 +1,29 @@
+const config = require('../test_helpers/config');
+const user = require('../test_helpers/user');
+const pwd = user.pwd;
+const username = user.username;
+const loginPage = require('./login.po');
+
+describe('XOS Login page', function() {
+
+ beforeEach(() => {
+ browser.get(`${config.url}/login`);
+ });
+
+ it('should not login with a wrong password', function() {
+ loginPage.sendUsername(username);
+ loginPage.sendPassword('wrongpwd');
+ loginPage.submit();
+
+ const alert = element(by.css('.alert.alert-danger'));
+ expect(alert.isDisplayed()).toBeTruthy();
+ });
+
+ it('should login', () => {
+ loginPage.sendUsername(username);
+ loginPage.sendPassword(pwd);
+ loginPage.submit();
+
+ expect(browser.getCurrentUrl()).toEqual(`${config.url}/dashboard`);
+ });
+});
\ No newline at end of file
diff --git a/e2e/test_helpers/config.js b/e2e/test_helpers/config.js
new file mode 100644
index 0000000..53db281
--- /dev/null
+++ b/e2e/test_helpers/config.js
@@ -0,0 +1 @@
+exports.url = process.env.UI_URL || 'http://192.168.46.100/xos/#';
\ No newline at end of file
diff --git a/e2e/test_helpers/user.js b/e2e/test_helpers/user.js
new file mode 100644
index 0000000..9acf2aa
--- /dev/null
+++ b/e2e/test_helpers/user.js
@@ -0,0 +1,36 @@
+const fs = require('fs');
+const config = require('./config');
+const P = require('bluebird');
+
+const username = 'xosadmin@opencord.org';
+
+const getPwd = () => {
+
+ if (process.env.UI_PWD) {
+ return process.env.UI_PWD;
+ }
+
+ const pwdFile = fs.readFileSync('../../build/platform-install/credentials/xosadmin@opencord.org', 'utf8');
+ return pwdFile;
+};
+
+exports.pwd = getPwd();
+
+exports.username = username;
+
+exports.login = P.promisify((done) => {
+ browser.get(`${config.url}/login`);
+
+ browser.getCurrentUrl()
+ .then((url) => {
+ // NOTE login only if it is not yet
+ if (url.indexOf('login') !== -1) {
+ const loginPage = require('../login/login.po');
+ loginPage.sendUsername(username);
+ loginPage.sendPassword(getPwd());
+ loginPage.submit();
+ }
+ browser.waitForAngular();
+ done();
+ });
+});
\ No newline at end of file