[Intern] Dashboard tests
- also fixed tags on Dashboard tab Related to blueprint ui-functional-tests-with-intern Change-Id: If517cb0bd6386812710e2dcbb7f7622e4178c5d2
This commit is contained in:
parent
6ddaaef18d
commit
8cee51e582
|
@ -3985,14 +3985,17 @@ input[type=range] {
|
|||
height: auto;
|
||||
}
|
||||
&.name {
|
||||
a {
|
||||
.btn-link {
|
||||
padding-left: 0;
|
||||
border-left: 0;
|
||||
text-align: left;
|
||||
display: inline-block;
|
||||
max-width: 220px;
|
||||
max-width: 180px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
text-overflow: ellipsis;
|
||||
height: 19px;
|
||||
line-height: 20px;
|
||||
height: 27px;
|
||||
line-height: 19px;
|
||||
}
|
||||
.glyphicon {
|
||||
margin-left: 10px;
|
||||
|
@ -4071,6 +4074,10 @@ input[type=range] {
|
|||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.discard-changes {
|
||||
padding-left: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
.changes-list {
|
||||
padding: @dashboard-offset @dashboard-offset 0 @dashboard-offset;
|
||||
a {cursor: pointer;}
|
||||
|
|
|
@ -79,20 +79,21 @@ define([
|
|||
);
|
||||
});
|
||||
},
|
||||
checkNodes: function(amount) {
|
||||
checkNodes: function(amount, status) {
|
||||
var self = this;
|
||||
status = status || 'discover';
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return _.range(amount).reduce(
|
||||
function(result, index) {
|
||||
return self.remote
|
||||
.findAllByCssSelector('.node.discover > label')
|
||||
.then(function(nodes) {
|
||||
return nodes[index].click();
|
||||
})
|
||||
.catch(function() {
|
||||
throw new Error('Failed to add ' + amount + ' nodes to the cluster');
|
||||
});
|
||||
.findAllByCssSelector('.node' + '.' + status + ' > label')
|
||||
.then(function(nodes) {
|
||||
return nodes[index].click();
|
||||
})
|
||||
.catch(function() {
|
||||
throw new Error('Failed to add ' + amount + ' nodes to the cluster');
|
||||
});
|
||||
},
|
||||
true);
|
||||
});
|
||||
|
|
|
@ -102,7 +102,7 @@ define([
|
|||
)}, false);
|
||||
});
|
||||
},
|
||||
addNodesToCluster: function(nodesAmount, nodesRoles) {
|
||||
addNodesToCluster: function(nodesAmount, nodesRoles, nodeStatus) {
|
||||
var self = this;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
|
@ -115,7 +115,7 @@ define([
|
|||
return self.clusterPage.checkNodeRoles(nodesRoles);
|
||||
})
|
||||
.then(function() {
|
||||
return self.clusterPage.checkNodes(nodesAmount);
|
||||
return self.clusterPage.checkNodes(nodesAmount, nodeStatus);
|
||||
})
|
||||
.clickByCssSelector('.btn-apply')
|
||||
.waitForElementDeletion('.btn-apply', 2000);
|
||||
|
@ -126,7 +126,7 @@ define([
|
|||
.then(function(element) {
|
||||
return element.getVisibleText()
|
||||
.then(function(visibleText) {
|
||||
assert.isTrue(visibleText == searchedText, message);
|
||||
assert.include(visibleText, searchedText, message);
|
||||
});
|
||||
})
|
||||
.end();
|
||||
|
|
|
@ -15,14 +15,15 @@
|
|||
**/
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'intern/chai!assert',
|
||||
'tests/functional/pages/modal',
|
||||
'../../helpers'
|
||||
], function(_, ModalWindow) {
|
||||
], function(assert, ModalWindow) {
|
||||
'use strict';
|
||||
function DashboardPage(remote) {
|
||||
this.remote = remote;
|
||||
this.modal = new ModalWindow(this.remote);
|
||||
this.modal = new ModalWindow(remote);
|
||||
this.deployButtonSelector = 'button.deploy-btn';
|
||||
}
|
||||
|
||||
DashboardPage.prototype = {
|
||||
|
@ -30,8 +31,7 @@ define([
|
|||
startDeployment: function() {
|
||||
var self = this;
|
||||
return this.remote
|
||||
.setFindTimeout(2000)
|
||||
.clickByCssSelector('.deploy-block button.deploy-btn')
|
||||
.clickByCssSelector(this.deployButtonSelector)
|
||||
.then(function() {
|
||||
return self.modal.waitToOpen();
|
||||
})
|
||||
|
@ -61,6 +61,46 @@ define([
|
|||
.then(function() {
|
||||
return self.modal.waitToClose();
|
||||
});
|
||||
},
|
||||
startClusterRenaming: function() {
|
||||
return this.remote
|
||||
.clickByCssSelector('.cluster-info-value.name .glyphicon-pencil');
|
||||
},
|
||||
setClusterName: function(name) {
|
||||
var self = this;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return self.startClusterRenaming();
|
||||
})
|
||||
.findByCssSelector('.rename-block input[type=text]')
|
||||
.clearValue()
|
||||
.type(name)
|
||||
// Enter
|
||||
.type('\uE007')
|
||||
.end();
|
||||
},
|
||||
discardChanges: function() {
|
||||
var self = this;
|
||||
return this.remote
|
||||
.clickByCssSelector('button.discard-changes')
|
||||
.then(function() {
|
||||
return self.modal.waitToOpen();
|
||||
})
|
||||
.then(function() {
|
||||
return self.modal.clickFooterButton('Discard');
|
||||
})
|
||||
.then(function() {
|
||||
return self.modal.waitToClose();
|
||||
});
|
||||
},
|
||||
assertIsIntegerContentPositive: function(cssSelector, attributeName) {
|
||||
return this.remote
|
||||
.findByCssSelector(cssSelector)
|
||||
.getVisibleText()
|
||||
.then(function(text) {
|
||||
return assert.isTrue(parseInt(text) > 0, attributeName + ' is greater than 0');
|
||||
})
|
||||
.end();
|
||||
}
|
||||
};
|
||||
return DashboardPage;
|
||||
|
|
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
* 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([
|
||||
'intern!object',
|
||||
'intern/chai!assert',
|
||||
'tests/functional/pages/common',
|
||||
'tests/functional/pages/cluster',
|
||||
'tests/functional/pages/dashboard'
|
||||
], function(registerSuite, assert, Common, ClusterPage, DashboardPage) {
|
||||
'use strict';
|
||||
|
||||
registerSuite(function() {
|
||||
var common,
|
||||
clusterPage,
|
||||
dashboardPage,
|
||||
clusterName;
|
||||
|
||||
return {
|
||||
name: 'Dashboard tab',
|
||||
setup: function() {
|
||||
common = new Common(this.remote);
|
||||
clusterPage = new ClusterPage(this.remote);
|
||||
dashboardPage = new DashboardPage(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');
|
||||
});
|
||||
},
|
||||
'Renaming cluster works': function() {
|
||||
var initialName = clusterName,
|
||||
newName = clusterName + '!!!',
|
||||
renameInputSelector = '.rename-block input[type=text]',
|
||||
nameSelector = '.cluster-info-value.name .btn-link';
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return dashboardPage.startClusterRenaming();
|
||||
})
|
||||
.findByCssSelector(renameInputSelector)
|
||||
// Escape
|
||||
.type('\uE00C')
|
||||
.end()
|
||||
.then(function() {
|
||||
return common.assertElementNotExists(renameInputSelector, 'Rename control disappears');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo(nameSelector, initialName,
|
||||
'Switching rename control does not change cluster name');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.setClusterName(newName);
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo(nameSelector, newName, 'New name is applied');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.setClusterName(initialName);
|
||||
});
|
||||
},
|
||||
'Provision button availability': function() {
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(1, ['Virtual']);
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo(dashboardPage.deployButtonSelector, 'Provision VMs',
|
||||
'After adding Virtual node deploy button has appropriate text');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.discardChanges();
|
||||
});
|
||||
},
|
||||
'Network validation error warning': function() {
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(1, ['Controller']);
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Networks');
|
||||
})
|
||||
.clickByCssSelector('.verify-networks-btn')
|
||||
.waitForCssSelector('.verification-box .alert-danger', 200)
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementContainsText('.warnings-block',
|
||||
'Networks verification', 'Network verification warning is shown');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.discardChanges();
|
||||
});
|
||||
},
|
||||
'No controller warning': function() {
|
||||
return this.remote
|
||||
.then(function() {
|
||||
// Adding single compute
|
||||
return common.addNodesToCluster(1, ['Compute']);
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementNotExists(dashboardPage.deployButtonSelector, 'No deployment should be possible without controller nodes added');
|
||||
})
|
||||
.findByCssSelector('div.instruction.invalid')
|
||||
// Invalid configuration message is shown
|
||||
.end()
|
||||
.then(function() {
|
||||
return common.assertElementContainsText(
|
||||
'div.validation-result ul.danger li',
|
||||
'At least 1 Controller nodes are required (0 selected currently).',
|
||||
'No controllers added warning should be shown'
|
||||
);
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.discardChanges();
|
||||
});
|
||||
},
|
||||
'Capacity table tests': function() {
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(1, ['Controller', 'Storage - Cinder']);
|
||||
})
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(2, ['Compute']);
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.assertIsIntegerContentPositive('.capacity-items .cpu .capacity-value', 'CPU');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.assertIsIntegerContentPositive('.capacity-items .hdd .capacity-value', 'HDD');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.assertIsIntegerContentPositive('.capacity-items .ram .capacity-value', 'RAM');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.discardChanges();
|
||||
});
|
||||
},
|
||||
'Test statistics update': function() {
|
||||
this.timeout = 90000;
|
||||
var controllerNodes = 3,
|
||||
storageCinderNodes = 1,
|
||||
computeNodes = 2,
|
||||
operatingSystemNodes = 1,
|
||||
virtualNodes = 1,
|
||||
valueSelector = '.statistics-block .cluster-info-value',
|
||||
total = controllerNodes + storageCinderNodes + computeNodes + operatingSystemNodes + virtualNodes;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(controllerNodes, ['Controller']);
|
||||
})
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(storageCinderNodes, ['Storage - Cinder']);
|
||||
})
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(computeNodes, ['Compute']);
|
||||
})
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(operatingSystemNodes, ['Operating System'], 'error');
|
||||
})
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(virtualNodes, ['Virtual'], 'offline');
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo(valueSelector + '.total',
|
||||
total,
|
||||
'The number of Total nodes in statistics is updated according to added nodes');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo(valueSelector + '.controller',
|
||||
controllerNodes,
|
||||
'The number of controllerNodes nodes in statistics is updated according to added nodes');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo(valueSelector + '.compute',
|
||||
computeNodes,
|
||||
'The number of Compute nodes in statistics is updated according to added nodes');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo(valueSelector + '.base-os',
|
||||
operatingSystemNodes,
|
||||
'The number of Operating Systems nodes in statistics is updated according to added nodes');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo(valueSelector + '.virt',
|
||||
virtualNodes,
|
||||
'The number of Virtual nodes in statistics is updated according to added nodes');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo(valueSelector + '.offline',
|
||||
1,
|
||||
'The number of Offline nodes in statistics is updated according to added nodes');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo(valueSelector + '.error',
|
||||
1,
|
||||
'The number of Error nodes in statistics is updated according to added nodes');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo(valueSelector + '.pending_addition',
|
||||
total,
|
||||
'The number of Pending Addition nodes in statistics is updated according to added nodes');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.discardChanges();
|
||||
});
|
||||
},
|
||||
'Testing error nodes in cluster deploy': function() {
|
||||
this.timeout = 60000;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(1, ['Controller'], 'error');
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo('.statistics-block .cluster-info-value.error',
|
||||
1, 'Error node is reflected in Statistics block');
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.startDeployment();
|
||||
})
|
||||
.waitForElementDeletion('.deploy-block .progress', 10000)
|
||||
.waitForCssSelector('.dashboard-tab .alert strong', 1000)
|
||||
.then(function() {
|
||||
return common.assertElementTextEqualTo('.dashboard-tab .alert strong', 'Error',
|
||||
'Deployment failed in case of adding offline nodes');
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.resetEnvironment(clusterName);
|
||||
})
|
||||
.then(function() {
|
||||
return dashboardPage.discardChanges();
|
||||
});
|
||||
},
|
||||
'VCenter warning appears': function() {
|
||||
var vCenterClusterName = clusterName + 'VCenter test';
|
||||
return this.remote
|
||||
.clickLinkByText('Environments')
|
||||
// needed here to wait for transition
|
||||
.waitForCssSelector('a.clusterbox', 2000)
|
||||
.then(function() {
|
||||
return common.createCluster(
|
||||
vCenterClusterName,
|
||||
{
|
||||
Compute: function() {
|
||||
// Selecting VCenter
|
||||
return this.remote
|
||||
.clickByCssSelector('.custom-tumbler input[name=vcenter]');
|
||||
},
|
||||
'Networking Setup': function() {
|
||||
// Selecting Nova Network
|
||||
return this.remote
|
||||
.clickByCssSelector('.custom-tumbler input[value=nova-network]');
|
||||
}
|
||||
}
|
||||
);
|
||||
})
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(1, ['Controller']);
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementContainsText('.warnings-block',
|
||||
'VMware settings are invalid', 'VMware warning is shown');
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
|
@ -65,30 +65,7 @@ define([
|
|||
'No deployment button when there are no nodes added': function() {
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.assertElementNotExists('button.deploy-btn', 'No deployment should be possible without nodes added')
|
||||
});
|
||||
},
|
||||
'No controller warning': function() {
|
||||
return this.remote
|
||||
.then(function() {
|
||||
// Adding single compute
|
||||
return common.addNodesToCluster(1, ['Compute']);
|
||||
})
|
||||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.then(function() {
|
||||
return common.assertElementNotExists('button.deploy-btn', 'No deployment should be possible without controller nodes added')
|
||||
})
|
||||
.findByCssSelector('div.instruction.invalid')
|
||||
// Invalid configuration message is shown
|
||||
.end()
|
||||
.then(function() {
|
||||
return common.assertElementContainsText(
|
||||
'div.validation-result ul.danger li',
|
||||
'At least 1 Controller nodes are required (0 selected currently).',
|
||||
'No controllers added warning should be shown'
|
||||
);
|
||||
return common.assertElementNotExists(dashboardPage.deployButtonSelector, 'No deployment should be possible without nodes added')
|
||||
});
|
||||
},
|
||||
'Discard changes': function() {
|
||||
|
@ -100,7 +77,7 @@ define([
|
|||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.clickLinkByText('Discard Changes')
|
||||
.clickByCssSelector('.discard-changes')
|
||||
.then(function() {
|
||||
return modal.waitToOpen();
|
||||
})
|
||||
|
@ -118,6 +95,7 @@ define([
|
|||
.waitForCssSelector('div.deploy-readiness a.btn-add-nodes', 2000);
|
||||
},
|
||||
'Start/stop deployment': function() {
|
||||
this.timeout = 60000;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(3, ['Controller']);
|
||||
|
@ -125,7 +103,7 @@ define([
|
|||
.then(function() {
|
||||
return clusterPage.goToTab('Dashboard');
|
||||
})
|
||||
.waitForCssSelector('.dashboard-tab', 2000)
|
||||
.waitForCssSelector('.dashboard-tab', 200)
|
||||
.then(function() {
|
||||
return dashboardPage.startDeployment();
|
||||
})
|
||||
|
@ -135,10 +113,14 @@ define([
|
|||
})
|
||||
.waitForElementDeletion('div.deploy-process div.progress', 5000)
|
||||
// Deployment button available
|
||||
.waitForCssSelector('div.deploy-block button.deploy-btn', 1000)
|
||||
.waitForCssSelector(dashboardPage.deployButtonSelector, 1000)
|
||||
.then(function() {
|
||||
return common.assertElementContainsText('div.alert-warning strong', 'Success', 'Deployment successfully stopped alert is expected');
|
||||
})
|
||||
//@todo: uncomment this after bug fix https://bugs.launchpad.net/fuel/+bug/1493291
|
||||
//.then(function() {
|
||||
// return common.assertElementNotExists('.go-to-healthcheck', 'Healthcheck link is not visible after stopped deploy');
|
||||
//})
|
||||
// Reset environment button is available
|
||||
.then(function() {
|
||||
return clusterPage.resetEnvironment(clusterName);
|
||||
|
@ -171,6 +153,15 @@ define([
|
|||
})
|
||||
// Deployment competed
|
||||
.waitForCssSelector('div.horizon', 50000)
|
||||
.then(function() {
|
||||
return common.assertElementExists('.go-to-healthcheck', 'Healthcheck link is visible after deploy');
|
||||
})
|
||||
.findByCssSelector('div.horizon a.btn-success')
|
||||
.getAttribute('href')
|
||||
.then(function(value) {
|
||||
return assert.isTrue(_.startsWith(value, 'http'), 'Link to Horizon is formed');
|
||||
})
|
||||
.end()
|
||||
.then(function() {
|
||||
return clusterPage.isTabLocked('Networks');
|
||||
})
|
||||
|
|
|
@ -500,12 +500,13 @@ function(_, i18n, $, React, utils, models, dispatcher, dialogs, componentMixins,
|
|||
)
|
||||
}
|
||||
{nodes.hasChanges() &&
|
||||
<a
|
||||
<button
|
||||
className='btn-link discard-changes'
|
||||
key='discard-changes'
|
||||
onClick={_.partial(this.showDialog, dialogs.DiscardNodeChangesDialog)}
|
||||
>
|
||||
{i18n('cluster_page.discard_changes')}
|
||||
</a>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
@ -712,7 +713,7 @@ function(_, i18n, $, React, utils, models, dispatcher, dialogs, componentMixins,
|
|||
</div>
|
||||
</div>
|
||||
<div className='col-xs-2'>
|
||||
<div className='cluster-info-value pull-right'>
|
||||
<div className={'cluster-info-value pull-right ' + field}>
|
||||
{numberOfNodes}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -788,9 +789,9 @@ function(_, i18n, $, React, utils, models, dispatcher, dialogs, componentMixins,
|
|||
/>
|
||||
:
|
||||
<div className='cluster-info-value name' onClick={this.startClusterRenaming}>
|
||||
<a>
|
||||
<button className='btn-link cluster-name'>
|
||||
{cluster.get('name')}
|
||||
</a>
|
||||
</button>
|
||||
<i className='glyphicon glyphicon-pencil'></i>
|
||||
</div>
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue