[Intern] Deployment preparation and process tests
Also introduces some fixes and optimizations to login page tests and cluster settings tab. Related to blueprint ui-functional-tests-with-intern Change-Id: I40446e454cc7a47be13b5f8ee291e110bd421182
This commit is contained in:
parent
92d8355d6e
commit
e48d16d84e
@ -690,8 +690,10 @@ define([
|
||||
constructorName: 'Volume',
|
||||
urlRoot: '/api/volumes/',
|
||||
getMinimalSize: function(minimum) {
|
||||
var currentDisk = this.collection.disk;
|
||||
var groupAllocatedSpace = currentDisk.collection.reduce(function(sum, disk) {return disk.id == currentDisk.id ? sum : sum + disk.get('volumes').findWhere({name: this.get('name')}).get('size');}, 0, this);
|
||||
var currentDisk = this.collection.disk,
|
||||
groupAllocatedSpace = 0;
|
||||
if (currentDisk && currentDisk.collection)
|
||||
groupAllocatedSpace = currentDisk.collection.reduce(function(sum, disk) {return disk.id == currentDisk.id ? sum : sum + disk.get('volumes').findWhere({name: this.get('name')}).get('size');}, 0, this);
|
||||
return minimum - groupAllocatedSpace;
|
||||
},
|
||||
getMaxSize: function() {
|
||||
|
@ -15,46 +15,54 @@
|
||||
**/
|
||||
|
||||
define(['underscore',
|
||||
'../../helpers'], function(_, Helpers) {
|
||||
'tests/functional/pages/modal',
|
||||
'../../helpers'], function(_, ModalWindow, Helpers) {
|
||||
'use strict';
|
||||
function ClusterPage(remote) {
|
||||
this.remote = remote;
|
||||
this.modal = new ModalWindow(remote);
|
||||
}
|
||||
|
||||
ClusterPage.prototype = {
|
||||
constructor: ClusterPage,
|
||||
goToTab: function(tabName) {
|
||||
var that = this;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return Helpers.clickLinkByText(
|
||||
that.remote,
|
||||
self.remote,
|
||||
'.tabs-box .tabs a',
|
||||
tabName);
|
||||
});
|
||||
},
|
||||
removeCluster: function() {
|
||||
var that = this;
|
||||
removeCluster: function(clusterName) {
|
||||
var self = this;
|
||||
return this.remote
|
||||
.then(
|
||||
function() {
|
||||
return this.parent
|
||||
.setFindTimeout(2000)
|
||||
.then(function() {
|
||||
return that.goToTab('Actions');
|
||||
})
|
||||
.findByCssSelector('button.delete-environment-btn')
|
||||
.click()
|
||||
.end()
|
||||
.setFindTimeout(2000)
|
||||
.findByCssSelector('div.modal-content')
|
||||
.findByCssSelector('button.remove-cluster-btn')
|
||||
.click()
|
||||
.end()
|
||||
.setFindTimeout(2000)
|
||||
.waitForDeletedByCssSelector('div.modal-content');
|
||||
}
|
||||
);
|
||||
.then(function() {
|
||||
return self.goToTab('Dashboard');
|
||||
})
|
||||
.findByCssSelector('button.delete-environment-btn')
|
||||
.click()
|
||||
.end()
|
||||
.then(function() {
|
||||
return self.modal.waitToOpen();
|
||||
})
|
||||
.then(function() {
|
||||
return self.modal.clickFooterButton('Delete');
|
||||
})
|
||||
.findAllByCssSelector('div.confirm-deletion-form input[type=text]')
|
||||
.then(function(confirmInputs) {
|
||||
if (confirmInputs.length)
|
||||
return confirmInputs[0]
|
||||
.type(clusterName)
|
||||
.then(function() {
|
||||
return self.modal.clickFooterButton('Delete');
|
||||
});
|
||||
})
|
||||
.end()
|
||||
.then(function() {
|
||||
return self.modal.waitToClose();
|
||||
});
|
||||
},
|
||||
checkNodeRoles: function(assignRoles) {
|
||||
return this.remote
|
||||
@ -79,13 +87,13 @@ define(['underscore',
|
||||
});
|
||||
},
|
||||
checkNodes: function(amount) {
|
||||
var that = this;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.setFindTimeout(2000)
|
||||
.then(function() {
|
||||
return _.range(amount).reduce(
|
||||
function(result, index) {
|
||||
return that.remote
|
||||
return self.remote
|
||||
.setFindTimeout(1000)
|
||||
.findAllByCssSelector('.node.discover > label')
|
||||
.then(function(nodes) {
|
||||
@ -97,6 +105,47 @@ define(['underscore',
|
||||
},
|
||||
true);
|
||||
});
|
||||
},
|
||||
resetEnvironment: function(clusterName) {
|
||||
var self = this;
|
||||
return this.remote
|
||||
.findByCssSelector('button.reset-environment-btn')
|
||||
.click()
|
||||
.end()
|
||||
.then(function() {
|
||||
return self.modal.waitToOpen();
|
||||
})
|
||||
.then(function() {
|
||||
return self.modal.checkTitle('Reset Environment');
|
||||
})
|
||||
.then(function() {
|
||||
return self.modal.clickFooterButton('Reset');
|
||||
})
|
||||
.setFindTimeout(20000)
|
||||
.findAllByCssSelector('div.confirm-reset-form input[type=text]')
|
||||
.then(function(confirmationInputs) {
|
||||
if (confirmationInputs.length)
|
||||
return confirmationInputs[0]
|
||||
.type(clusterName)
|
||||
.then(function() {
|
||||
return self.modal.clickFooterButton('Reset');
|
||||
});
|
||||
})
|
||||
.end()
|
||||
.then(function() {
|
||||
return self.modal.waitToClose();
|
||||
})
|
||||
.setFindTimeout(10000)
|
||||
.waitForDeletedByCssSelector('div.progress-bar');
|
||||
},
|
||||
isTabLocked: function(tabName) {
|
||||
var self = this;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return self.goToTab(tabName);
|
||||
})
|
||||
.findByCssSelector('div.tab-content div.row.changes-locked')
|
||||
.then(_.constant(true), _.constant(false));
|
||||
}
|
||||
};
|
||||
return ClusterPage;
|
||||
|
@ -14,22 +14,25 @@
|
||||
* under the License.
|
||||
**/
|
||||
|
||||
define([], function() {
|
||||
define(['tests/functional/pages/modal'], function(ModalWindow) {
|
||||
'use strict';
|
||||
function ClustersPage(remote) {
|
||||
this.remote = remote;
|
||||
this.modal = new ModalWindow(remote);
|
||||
}
|
||||
|
||||
ClustersPage.prototype = {
|
||||
constructor: ClustersPage,
|
||||
createCluster: function(clusterName) {
|
||||
var self = this;
|
||||
return this.remote
|
||||
.setFindTimeout(1000)
|
||||
.findByClassName('create-cluster')
|
||||
.click()
|
||||
.end()
|
||||
.setFindTimeout(2000)
|
||||
.findByCssSelector('div.modal-content')
|
||||
.then(function() {
|
||||
return self.modal.waitToOpen();
|
||||
})
|
||||
.findByName('name')
|
||||
.clearValue()
|
||||
.type(clusterName)
|
||||
@ -41,16 +44,16 @@ define([], function() {
|
||||
.pressKeys('\uE007')
|
||||
.pressKeys('\uE007')
|
||||
.end()
|
||||
.setFindTimeout(4000)
|
||||
.waitForDeletedByCssSelector('div.modal-content')
|
||||
.end();
|
||||
.then(function() {
|
||||
return self.modal.waitToClose();
|
||||
});
|
||||
},
|
||||
clusterSelector: '.clusterbox div.name',
|
||||
goToEnvironment: function(clusterName) {
|
||||
var that = this;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.setFindTimeout(5000)
|
||||
.findAllByCssSelector(that.clusterSelector)
|
||||
.findAllByCssSelector(self.clusterSelector)
|
||||
.then(function(divs) {
|
||||
return divs.reduce(
|
||||
function(matchFound, element) {
|
||||
|
@ -36,27 +36,27 @@ define([
|
||||
});
|
||||
},
|
||||
getOut: function() {
|
||||
var that = this;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return that.welcomePage.skip();
|
||||
return self.welcomePage.skip();
|
||||
})
|
||||
.then(function() {
|
||||
return that.loginPage.logout();
|
||||
return self.loginPage.logout();
|
||||
});
|
||||
},
|
||||
getIn: function() {
|
||||
var that = this;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return that.loginPage.logout();
|
||||
return self.loginPage.logout();
|
||||
})
|
||||
.then(function() {
|
||||
return that.loginPage.login();
|
||||
return self.loginPage.login();
|
||||
})
|
||||
.waitForDeletedByClassName('login-btn')
|
||||
.then(function() {
|
||||
return that.welcomePage.skip();
|
||||
return self.welcomePage.skip();
|
||||
});
|
||||
},
|
||||
clickLink: function(text) {
|
||||
@ -66,78 +66,67 @@ define([
|
||||
.click()
|
||||
.end();
|
||||
},
|
||||
waitForModal: function() {
|
||||
return this.remote
|
||||
.setFindTimeout(2000)
|
||||
.findByCssSelector('div.modal-content')
|
||||
.end();
|
||||
},
|
||||
closeModal: function() {
|
||||
return this.remote
|
||||
.findByCssSelector('.modal-header button.close')
|
||||
.click()
|
||||
.end();
|
||||
},
|
||||
waitForElementDeletion: function(cssSelector) {
|
||||
return this.remote
|
||||
.setFindTimeout(2000)
|
||||
.setFindTimeout(5000)
|
||||
.waitForDeletedByCssSelector(cssSelector)
|
||||
.catch() // For cases when element is destroyed already
|
||||
.findByCssSelector(cssSelector)
|
||||
.then(function() {
|
||||
throw new Error('Element ' + cssSelector + ' was not destroyed');
|
||||
}, _.constant(true));
|
||||
},
|
||||
waitForModalToClose: function() {
|
||||
return this.waitForElementDeletion('div.modal-content');
|
||||
.catch(function(error) {
|
||||
if (error.name != 'Timeout')
|
||||
throw error;
|
||||
}) // For cases when element is destroyed already
|
||||
.findAllByCssSelector(cssSelector)
|
||||
.then(function(elements) {
|
||||
if (elements.length)
|
||||
throw new Error('Element ' + cssSelector + ' was not destroyed');
|
||||
});
|
||||
},
|
||||
goToEnvironment: function(clusterName, tabName) {
|
||||
var that = this;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return that.clickLink('Environments');
|
||||
return self.clickLink('Environments');
|
||||
})
|
||||
.then(function() {
|
||||
return that.clustersPage.goToEnvironment(clusterName);
|
||||
return self.clustersPage.goToEnvironment(clusterName);
|
||||
})
|
||||
.then(function() {
|
||||
if (tabName) return that.clusterPage.goToTab(tabName);
|
||||
if (tabName) return self.clusterPage.goToTab(tabName);
|
||||
});
|
||||
},
|
||||
createCluster: function(clusterName) {
|
||||
var that = this;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return that.clickLink('Environments');
|
||||
return self.clickLink('Environments');
|
||||
})
|
||||
.then(function() {
|
||||
return that.clustersPage.createCluster(clusterName);
|
||||
return self.clustersPage.createCluster(clusterName);
|
||||
});
|
||||
},
|
||||
removeCluster: function(clusterName, suppressErrors) {
|
||||
var that = this;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return that.clickLink('Environments');
|
||||
return self.clickLink('Environments');
|
||||
})
|
||||
.then(function() {
|
||||
return that.clustersPage.goToEnvironment(clusterName);
|
||||
return self.clustersPage.goToEnvironment(clusterName);
|
||||
})
|
||||
.then(function() {
|
||||
return that.clusterPage.removeCluster();
|
||||
return self.clusterPage.removeCluster(clusterName);
|
||||
})
|
||||
.catch(function() {
|
||||
if (!suppressErrors) throw new Error('Unable to delete cluster ' + clusterName);
|
||||
});
|
||||
},
|
||||
doesClusterExist: function(clusterName) {
|
||||
var that = this;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.setFindTimeout(2000)
|
||||
.then(function() {
|
||||
return that.clickLink('Environments');
|
||||
return self.clickLink('Environments');
|
||||
})
|
||||
.findAllByCssSelector(that.clustersPage.clusterSelector)
|
||||
.findAllByCssSelector(self.clustersPage.clusterSelector)
|
||||
.then(function(divs) {
|
||||
return divs.reduce(function(matchFound, element) {
|
||||
return element.getVisibleText().then(
|
||||
@ -148,19 +137,21 @@ define([
|
||||
});
|
||||
},
|
||||
addNodesToCluster: function(nodesAmount, nodesRoles) {
|
||||
var that = this;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.setFindTimeout(5000)
|
||||
.findByCssSelector('a.btn-add-nodes')
|
||||
.then(function() {
|
||||
return self.clusterPage.goToTab('Nodes');
|
||||
})
|
||||
.findByCssSelector('button.btn-add-nodes')
|
||||
.click()
|
||||
.end()
|
||||
.findByCssSelector('div.role-panel')
|
||||
.end()
|
||||
.then(function() {
|
||||
return that.clusterPage.checkNodeRoles(nodesRoles);
|
||||
return self.clusterPage.checkNodeRoles(nodesRoles);
|
||||
})
|
||||
.then(function() {
|
||||
return that.clusterPage.checkNodes(nodesAmount);
|
||||
return self.clusterPage.checkNodes(nodesAmount);
|
||||
})
|
||||
.findByCssSelector('button.btn-apply')
|
||||
.click()
|
||||
@ -168,6 +159,17 @@ define([
|
||||
.setFindTimeout(2000)
|
||||
.findByCssSelector('button.btn-add-nodes')
|
||||
.end();
|
||||
},
|
||||
doesCssSelectorContainText: function(cssSelector, searchedText) {
|
||||
return this.remote
|
||||
.findAllByCssSelector(cssSelector)
|
||||
.then(function(messages) {
|
||||
return messages.reduce(function(result, message) {
|
||||
return message.getVisibleText().then(function(visibleText) {
|
||||
return visibleText == searchedText || result;
|
||||
});
|
||||
}, false)
|
||||
});
|
||||
}
|
||||
};
|
||||
return CommonMethods;
|
||||
|
75
nailgun/static/tests/functional/pages/dashboard.js
Normal file
75
nailgun/static/tests/functional/pages/dashboard.js
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2015 Mirantis, Inc.
|
||||
*
|
||||
* 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.
|
||||
**/
|
||||
|
||||
define(['underscore', 'tests/functional/pages/modal'], function(_, ModalWindow) {
|
||||
'use strict';
|
||||
function DashboardPage(remote) {
|
||||
this.remote = remote;
|
||||
this.modal = new ModalWindow(remote);
|
||||
}
|
||||
|
||||
DashboardPage.prototype = {
|
||||
constructor: DashboardPage,
|
||||
isDeploymentButtonVisible: function() {
|
||||
return this.remote
|
||||
.setFindTimeout(100)
|
||||
.findAllByCssSelector('button.deploy-btn')
|
||||
.then(function(buttons) {
|
||||
return buttons.length > 0;
|
||||
});
|
||||
},
|
||||
startDeployment: function() {
|
||||
var self = this;
|
||||
return this.remote
|
||||
.setFindTimeout(2000)
|
||||
.findByCssSelector('div.deploy-block button.deploy-btn')
|
||||
.click()
|
||||
.end()
|
||||
.then(function() {
|
||||
return self.modal.waitToOpen();
|
||||
})
|
||||
.then(function() {
|
||||
return self.modal.checkTitle('Deploy Changes');
|
||||
})
|
||||
.then(function() {
|
||||
return self.modal.clickFooterButton('Deploy');
|
||||
})
|
||||
.then(function() {
|
||||
return self.modal.waitToClose();
|
||||
});
|
||||
},
|
||||
stopDeployment: function() {
|
||||
var self = this;
|
||||
return this.remote
|
||||
.findByCssSelector('button.stop-deployment-btn')
|
||||
.click()
|
||||
.end()
|
||||
.then(function() {
|
||||
return self.modal.waitToOpen();
|
||||
})
|
||||
.then(function() {
|
||||
return self.modal.checkTitle('Stop Deployment');
|
||||
})
|
||||
.then(function() {
|
||||
return self.modal.clickFooterButton('Stop');
|
||||
})
|
||||
.then(function() {
|
||||
return self.modal.waitToClose();
|
||||
});
|
||||
}
|
||||
};
|
||||
return DashboardPage;
|
||||
});
|
@ -28,7 +28,7 @@ define([
|
||||
login: function(username, password) {
|
||||
username = username || Helpers.username;
|
||||
password = password || Helpers.password;
|
||||
var that = this;
|
||||
var self = this;
|
||||
|
||||
return this.remote
|
||||
.setWindowSize(1280, 1024)
|
||||
@ -36,7 +36,7 @@ define([
|
||||
.getCurrentUrl()
|
||||
.then(function(url) {
|
||||
if (url !== Helpers.serverUrl + '/#login') {
|
||||
return that.logout();
|
||||
return self.logout();
|
||||
}
|
||||
})
|
||||
.setFindTimeout(10000)
|
||||
|
62
nailgun/static/tests/functional/pages/modal.js
Normal file
62
nailgun/static/tests/functional/pages/modal.js
Normal file
@ -0,0 +1,62 @@
|
||||
define([
|
||||
'intern/chai!assert'
|
||||
],
|
||||
function(assert) {
|
||||
'use strict';
|
||||
function ModalWindow(remote) {
|
||||
this.remote = remote;
|
||||
}
|
||||
|
||||
ModalWindow.prototype = {
|
||||
constructor: ModalWindow,
|
||||
waitToOpen: function() {
|
||||
return this.remote
|
||||
.setFindTimeout(2000)
|
||||
.findByCssSelector('div.modal-content')
|
||||
.end();
|
||||
},
|
||||
checkTitle: function(expectedTitle) {
|
||||
return this.remote
|
||||
.findByCssSelector('h4.modal-title')
|
||||
.getVisibleText()
|
||||
.then(function(title) {
|
||||
assert.equal(title, expectedTitle, 'Unexpected modal window title');
|
||||
})
|
||||
.end();
|
||||
},
|
||||
close: function() {
|
||||
return this.remote
|
||||
.findByCssSelector('.modal-header button.close')
|
||||
.click()
|
||||
.end();
|
||||
},
|
||||
clickFooterButton: function(buttonText) {
|
||||
return this.remote
|
||||
.findAllByCssSelector('.modal-footer button')
|
||||
.then(function(buttons) {
|
||||
return buttons.reduce(function(result, button) {
|
||||
return button.getVisibleText()
|
||||
.then(function(buttonTitle) {
|
||||
if (buttonTitle == buttonText)
|
||||
return button.isEnabled()
|
||||
.then(function(isEnabled) {
|
||||
if (isEnabled) {
|
||||
return button.click();
|
||||
} else
|
||||
throw Error('Unable to click disabled button "' + buttonText + '"');
|
||||
});
|
||||
return result;
|
||||
});
|
||||
}, null);
|
||||
});
|
||||
},
|
||||
waitToClose: function() {
|
||||
var CommonPage = require('tests/functional/pages/common'),
|
||||
common = new CommonPage(this.remote);
|
||||
|
||||
return common.waitForElementDeletion('div.modal-content');
|
||||
}
|
||||
};
|
||||
return ModalWindow;
|
||||
}
|
||||
);
|
223
nailgun/static/tests/functional/test_cluster_deployment.js
Normal file
223
nailgun/static/tests/functional/test_cluster_deployment.js
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright 2015 Mirantis, Inc.
|
||||
*
|
||||
* 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.
|
||||
**/
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'intern!object',
|
||||
'intern/chai!assert',
|
||||
'tests/functional/pages/common',
|
||||
'tests/functional/pages/cluster',
|
||||
'tests/functional/pages/dashboard',
|
||||
'tests/functional/pages/modal'
|
||||
], function(_, registerSuite, assert, Common, ClusterPage, DashboardPage, ModalWindow) {
|
||||
'use strict';
|
||||
|
||||
registerSuite(function() {
|
||||
var common,
|
||||
clusterPage,
|
||||
dashboardPage,
|
||||
modal,
|
||||
clusterName;
|
||||
|
||||
return {
|
||||
name: 'Cluster deployment',
|
||||
setup: function() {
|
||||
common = new Common(this.remote);
|
||||
clusterPage = new ClusterPage(this.remote);
|
||||
dashboardPage = new DashboardPage(this.remote);
|
||||
modal = new ModalWindow(this.remote);
|
||||
clusterName = common.pickRandomName('Test Cluster');
|
||||
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.getIn();
|
||||
})
|
||||
.then(function() {
|
||||
return common.createCluster(clusterName);
|
||||
});
|
||||
},
|
||||
beforeEach: function() {
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
});
|
||||
},
|
||||
teardown: function() {
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.removeCluster(clusterName);
|
||||
});
|
||||
},
|
||||
'No deployment button when there are no nodes added': function() {
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return dashboardPage.isDeploymentButtonVisible();
|
||||
})
|
||||
.then(function(isVisible) {
|
||||
assert.isFalse(isVisible, 'No deployment should be possible without nodes added');
|
||||
});
|
||||
},
|
||||
'No controller warning': function() {
|
||||
this.timeout = 120000;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
// Adding single compute
|
||||
return common.addNodesToCluster(1, ['Compute']);
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.isDeploymentButtonVisible();
|
||||
})
|
||||
.then(function(isVisible) {
|
||||
assert.isFalse(isVisible, 'No deployment should be possible without controller nodes added');
|
||||
})
|
||||
.findByCssSelector('div.instruction.invalid')
|
||||
// Invalid configuration message is shown
|
||||
.end()
|
||||
.then(function() {
|
||||
return common.doesCssSelectorContainText(
|
||||
'div.validation-result ul.danger li',
|
||||
'At least 1 Controller nodes are required (0 selected currently).');
|
||||
})
|
||||
.then(function(messageFound) {
|
||||
assert.isTrue(messageFound, 'No controllers added warning should be shown');
|
||||
});
|
||||
},
|
||||
'Discard changes': function() {
|
||||
this.timeout = 120000;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
// Adding three controllers
|
||||
return common.addNodesToCluster(1, ['Controller']);
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return common.clickLink('Discard Changes');
|
||||
})
|
||||
.then(function() {
|
||||
return modal.waitToOpen();
|
||||
})
|
||||
.then(function() {
|
||||
return common.doesCssSelectorContainText('h4.modal-title', 'Discard Changes');
|
||||
})
|
||||
.then(function(result) {
|
||||
assert.isTrue(result, 'Discard Changes confirmation modal expected');
|
||||
})
|
||||
.then(function() {
|
||||
return modal.clickFooterButton('Discard');
|
||||
})
|
||||
.then(function() {
|
||||
return modal.waitToClose();
|
||||
})
|
||||
.findByCssSelector('div.deploy-readiness a.btn-add-nodes')
|
||||
// All changes discarded, add nodes button gets visible
|
||||
// in deploy readiness block
|
||||
.end();
|
||||
},
|
||||
'Start/stop deployment': function() {
|
||||
this.timeout = 120000;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(3, ['Controller']);
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.startDeployment();
|
||||
})
|
||||
.setFindTimeout(2000)
|
||||
.findAllByCssSelector('div.deploy-process div.progress')
|
||||
.then(function(elements) {
|
||||
assert.ok(elements.length, 'Deployment progress bar expected to appear');
|
||||
})
|
||||
.end()
|
||||
.then(function() {
|
||||
return dashboardPage.stopDeployment();
|
||||
})
|
||||
.then(function() {
|
||||
// Progress bar disappears
|
||||
return common.waitForElementDeletion('div.deploy-process div.progress');
|
||||
})
|
||||
// Deployment button available
|
||||
.findByCssSelector('div.deploy-block button.deploy-btn')
|
||||
.end()
|
||||
.findByCssSelector('div.alert-warning strong')
|
||||
.getVisibleText()
|
||||
.then(function(alertTitle) {
|
||||
assert.equal(alertTitle, 'Success', 'Deployment successfully stopped alert is expected');
|
||||
})
|
||||
.end()
|
||||
// Reset environment button is available
|
||||
.then(function() {
|
||||
return clusterPage.resetEnvironment(clusterName);
|
||||
});
|
||||
},
|
||||
'Test tabs locking after deployment completed': function() {
|
||||
this.timeout = 120000;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
// Adding single controller (enough for deployment)
|
||||
return common.addNodesToCluster(1, ['Controller']);
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.isTabLocked('Networks');
|
||||
})
|
||||
.then(function(isLocked) {
|
||||
assert.isFalse(isLocked, 'Networks tab is not locked for undeployed cluster');
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.isTabLocked('Settings');
|
||||
})
|
||||
.then(function(isLocked) {
|
||||
assert.isFalse(isLocked, 'Settings tab is not locked for undeployed cluster');
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.startDeployment();
|
||||
})
|
||||
.setFindTimeout(120000)
|
||||
// Deployment competed
|
||||
.findByCssSelector('div.horizon')
|
||||
.end()
|
||||
.then(function() {
|
||||
return clusterPage.isTabLocked('Networks');
|
||||
})
|
||||
.then(function(isLocked) {
|
||||
assert.isTrue(isLocked, 'Networks tab should turn locked after deployment');
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.isTabLocked('Settings');
|
||||
})
|
||||
.then(function(isLocked) {
|
||||
assert.isTrue(isLocked, 'Settings tab should turn locked after deployment');
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.resetEnvironment(clusterName);
|
||||
})
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
@ -18,12 +18,14 @@ define([
|
||||
'underscore',
|
||||
'intern!object',
|
||||
'intern/chai!assert',
|
||||
'tests/functional/pages/modal',
|
||||
'tests/functional/pages/common'
|
||||
], function(_, registerSuite, assert, Common) {
|
||||
], function(_, registerSuite, assert, ModalWindow, Common) {
|
||||
'use strict';
|
||||
|
||||
registerSuite(function() {
|
||||
var common,
|
||||
modal,
|
||||
clusterName,
|
||||
nodesAmount = 4;
|
||||
|
||||
@ -31,6 +33,7 @@ define([
|
||||
name: 'Cluster Nodes page',
|
||||
setup: function() {
|
||||
common = new Common(this.remote);
|
||||
modal = new ModalWindow(this.remote);
|
||||
clusterName = common.pickRandomName('Test Cluster');
|
||||
|
||||
return this.remote
|
||||
@ -47,7 +50,7 @@ define([
|
||||
teardown: function() {
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.removeCluster(clusterName, true);
|
||||
return common.removeCluster(clusterName);
|
||||
});
|
||||
},
|
||||
afterEach: function() {
|
||||
@ -99,7 +102,7 @@ define([
|
||||
.click()
|
||||
.end()
|
||||
.then(function() {
|
||||
return common.waitForModal();
|
||||
return modal.waitToOpen();
|
||||
})
|
||||
.findByCssSelector('.modal-header h4.modal-title')
|
||||
.getVisibleText()
|
||||
@ -108,10 +111,10 @@ define([
|
||||
})
|
||||
.end()
|
||||
.then(function() {
|
||||
return common.closeModal();
|
||||
return modal.close();
|
||||
})
|
||||
.then(function() {
|
||||
return common.waitForModalToClose();
|
||||
return modal.waitToClose();
|
||||
});
|
||||
},
|
||||
'Compact View Mode': function() {
|
||||
@ -126,7 +129,7 @@ define([
|
||||
.findByCssSelector('div.node-checkbox')
|
||||
.click()
|
||||
.findByCssSelector('i.glyphicon-ok')
|
||||
// Check that node is selectable
|
||||
// Check self node is selectable
|
||||
.end()
|
||||
.end();
|
||||
},
|
||||
@ -154,13 +157,13 @@ define([
|
||||
return common.waitForElementDeletion('div.node-popover');
|
||||
})
|
||||
.then(function() {
|
||||
return common.waitForModal();
|
||||
return modal.waitToOpen();
|
||||
})
|
||||
.then(function() {
|
||||
return common.closeModal();
|
||||
return modal.close();
|
||||
})
|
||||
.then(function() {
|
||||
return common.waitForModalToClose();
|
||||
return modal.waitToClose();
|
||||
})
|
||||
.findByCssSelector('div.compact-node div.node-hardware p.btn')
|
||||
// Open popover again
|
||||
@ -172,14 +175,14 @@ define([
|
||||
.end()
|
||||
.then(function() {
|
||||
// Deletion confirmation shows up
|
||||
return common.waitForModal();
|
||||
return modal.waitToOpen();
|
||||
})
|
||||
.findByCssSelector('div.modal-content button.btn-delete')
|
||||
// Confirm deletion
|
||||
.click()
|
||||
.end()
|
||||
.then(function() {
|
||||
return common.waitForModalToClose();
|
||||
return modal.waitToClose();
|
||||
})
|
||||
.findAllByCssSelector('div.compact-node')
|
||||
.then(function(nodes) {
|
||||
|
@ -70,14 +70,14 @@ define([
|
||||
},
|
||||
'Add Cluster Nodes': function() {
|
||||
var nodesAmount = 3,
|
||||
that = this,
|
||||
self = this,
|
||||
applyButton;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.goToEnvironment(clusterName);
|
||||
})
|
||||
.setFindTimeout(5000)
|
||||
.findByCssSelector('button.btn-add-nodes')
|
||||
.findByCssSelector('a.btn-add-nodes')
|
||||
.click()
|
||||
.end()
|
||||
.findByCssSelector('button.btn-apply')
|
||||
@ -113,7 +113,7 @@ define([
|
||||
.then(function() {
|
||||
return _.range(1, 1 + nodesAmount).reduce(
|
||||
function(nodesFound, index) {
|
||||
return that.remote
|
||||
return self.remote
|
||||
.setFindTimeout(1000)
|
||||
.findByCssSelector('div.node:nth-child(' + index + ')')
|
||||
.catch(function() {
|
||||
|
@ -43,7 +43,7 @@ define([
|
||||
afterEach: function() {
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.removeCluster(clusterName, true);
|
||||
return common.removeCluster(clusterName);
|
||||
});
|
||||
},
|
||||
'Create Cluster': function() {
|
||||
|
@ -41,11 +41,10 @@ define([
|
||||
.then(function() {
|
||||
return loginPage.login('login', '*****');
|
||||
})
|
||||
.findByCssSelector('div.login-fields-box p.text-danger')
|
||||
.isDisplayed()
|
||||
.then(function(errorShown) {
|
||||
assert.ok(errorShown, 'Error message is expected to be displayed');
|
||||
});
|
||||
.findAllByCssSelector('div.login-error')
|
||||
.then(function(elements) {
|
||||
assert.ok(elements.length, 'Error message is expected to get displayed');
|
||||
});
|
||||
},
|
||||
'Login with proper credentials': function() {
|
||||
return this.remote
|
||||
|
@ -195,10 +195,14 @@ function($, _, i18n, React, utils, models, Expression, componentMixins, controls
|
||||
lockedCluster = !cluster.isAvailableForSettingsChanges(),
|
||||
someSettingsEditable = _.any(settings.attributes, function(group) {return group.metadata.always_editable;}),
|
||||
hasChanges = this.hasChanges(),
|
||||
allocatedRoles = _.uniq(_.flatten(_.union(cluster.get('nodes').pluck('roles'), cluster.get('nodes').pluck('pending_roles'))));
|
||||
allocatedRoles = _.uniq(_.flatten(_.union(cluster.get('nodes').pluck('roles'), cluster.get('nodes').pluck('pending_roles')))),
|
||||
classes = {
|
||||
row: true,
|
||||
'changes-locked': lockedCluster
|
||||
};
|
||||
|
||||
return (
|
||||
<div key={this.state.key} className='row'>
|
||||
<div key={this.state.key} className={utils.classNames(classes)}>
|
||||
<div className='title'>{i18n('cluster_page.settings_tab.title')}</div>
|
||||
<SettingSubtabs
|
||||
settings={settings}
|
||||
|
@ -26,7 +26,7 @@ casper.then(function() {
|
||||
var authenticated = this.evaluate(function() {
|
||||
return window.app.user.get('authenticated');
|
||||
}),
|
||||
token = this.evaluate(function() {
|
||||
token = this.evaluate(function() {
|
||||
return window.app.keystoneClient.token;
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user