Fix/refactor some UI tests

Affected:
* real-plugin/nics-feature
* real-plugin/component-registry (removed)
* nigtly/workflows
* nigtly/deployment-history

Change-Id: Ie4d8a9bb8c6fc9a941477aa69b18fec3fa636265
This commit is contained in:
ekhomyakova 2017-02-15 19:44:23 +04:00
parent 0de244cf7c
commit d28d766981
32 changed files with 448 additions and 1523 deletions

View File

@ -23,8 +23,6 @@ export REMOTE_SSH_PORT=${REMOTE_SSH_PORT:-22}
export REMOTE_PASSWORD=${REMOTE_PASSWORD:-'r00tme'}
export REMOTE_DIR=${REMOTE_DIR:-'/root'}
export FUEL_UI_HOST=${FUEL_UI_HOST:-${REMOTE_HOST}}
export REMOTE_EXEC="sshpass -p ${REMOTE_PASSWORD}
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
-p ${REMOTE_SSH_PORT} ${REMOTE_USER}@${REMOTE_HOST}"
@ -64,19 +62,18 @@ function install_prepare_plugin {
export plugin_name=$(${REMOTE_EXEC} egrep '^name: ' "${meta}" | cut -d ' ' -f 2)
export plugin_version=$(${REMOTE_EXEC} egrep '^version: ' "${meta}" | cut -d ' ' -f 2)
# Fix package version
${REMOTE_EXEC} sed -i '$!s/4.0.0/5.0.0/' ${PLUGIN_PATH}/metadata.yaml
# Fix package version and release versions
${REMOTE_EXEC} sed -i -e '$!s/4.0.0/5.0.0/' -e '$!s/9.0/10.0/g' -e '$!s/mitaka/newton/' ${meta}
${REMOTE_EXEC} fuel plugins --sync
# Fix components settings
${REMOTE_EXEC} sed -i '/requires/,/+$/s/^/#/' ${PLUGIN_PATH}/components.yaml
${REMOTE_EXEC} fuel plugins --sync
export INSTALLED_PLUGINS="${INSTALLED_PLUGINS};${plugin_name}==${plugin_version//\'/}"
}
function remove_plugin {
function remove_plugins {
for plug in $(echo ${INSTALLED_PLUGINS} | tr ";" "\n")
do
${REMOTE_EXEC} fuel plugins --remove "${plug}" 2>/dev/null && \
@ -92,7 +89,7 @@ function remote_scp {
-P ${REMOTE_SSH_PORT} $local_file ${REMOTE_USER}@${REMOTE_HOST}:/${REMOTE_DIR}/
}
function run_component_tests {
function run_tests {
local GULP='./node_modules/.bin/gulp'
local TESTS_DIR="static/tests/functional/real_plugin/${TESTS_DIR_NAME}"
local TESTS=${TESTS_DIR}/${TEST_PREFIX}.js
@ -106,20 +103,29 @@ function run_component_tests {
remote_scp ${CONF_PATH}/${conf}_plugin2.yaml
${REMOTE_EXEC} cp ${REMOTE_DIR}/${conf}_plugin2.yaml ${PLUGIN_PATH}/${conf}_config.yaml
done
local plugin1_path=${PLUGIN_PATH}/environment_config.yaml
fi
install_prepare_plugin ${plugin_url} "plugin"
if [ ${TESTS_DIR_NAME} == 'feature_nics' ]; then
${REMOTE_EXEC} cp ${PLUGIN_PATH}/environment_config.yaml ${plugin1_path}
${REMOTE_EXEC} sed -i '$!s/fuel.*/dvs/' ${meta}
${REMOTE_EXEC} fuel plugins --sync
fi
${GULP} intern:transpile
for test_case in $TESTS; do
echo "INFO: Running test case ${test_case}"
ARTIFACTS=$ARTIFACTS \
${GULP} intern:functional --suites="${test_case}" || result=1
${GULP} intern:run --suites="${test_case}" || result=1
done
remove_plugin
remove_plugins
return $result
}
run_component_tests
run_tests

View File

@ -28,7 +28,7 @@ class HistoryLib {
}
compareViewsData(rowNumber, nodeName) {
var taskName, taskStatus, startTime, endTime;
var taskName, taskStatus, taskType, startTime, endTime;
var historyToolbarSelector = 'div.deployment-history-toolbar ';
var timelineViewButton = historyToolbarSelector + 'label.timeline-view';
var tableViewButton = historyToolbarSelector + 'label.table-view';
@ -39,6 +39,7 @@ class HistoryLib {
var taskPopover = 'div.popover.deployment-task-info div.popover-content ';
var popoverTaskName = taskPopover + 'div.task_name ';
var popoverStatus = taskPopover + 'div.status ';
var popoverType = taskPopover + 'div.type ';
var popoverStartTime = taskPopover + 'div.time_start ';
var popoverEndTime = taskPopover + 'div.time_end ';
var taskDetailsAttribure = 'div.deployment-task-details-dialog div.modal-body div.row';
@ -57,6 +58,10 @@ class HistoryLib {
.getVisibleText()
.then((value) => {taskStatus = value;})
.end()
.findByCssSelector(popoverType + 'span:last-child')
.getVisibleText()
.then((value) => {taskType = value;})
.end()
.findByCssSelector(popoverStartTime + 'span:last-child')
.getVisibleText()
.then((value) => {startTime = value;})
@ -79,6 +84,10 @@ class HistoryLib {
.getVisibleText()
.then((value) => assert.equal(value, taskStatus, 'Task status is the same in the table'))
.end()
.findByCssSelector(tableBodyRow + ':nth-child(' + rowNumber + ') td:nth-child(4)')
.getVisibleText()
.then((value) => assert.equal(value, taskType, 'Task type is the same in the table'))
.end()
.findByCssSelector(tableBodyRow + ':nth-child(' + rowNumber + ') td:nth-child(5)')
.getVisibleText()
.then((value) => assert.equal(value, startTime, 'Start time is the same in the table'))
@ -103,6 +112,10 @@ class HistoryLib {
.getVisibleText()
.then((value) => assert.equal(value, taskStatus, 'Task status is the same in the dialog'))
.end()
.findByCssSelector(taskDetailsAttribure + ':nth-child(4) span')
.getVisibleText()
.then((value) => assert.equal(value, taskType, 'Task type is the same in the dialog'))
.end()
.findByCssSelector(taskDetailsAttribure + ':nth-child(5) span')
.getVisibleText()
.then((value) => assert.equal(value, startTime, 'Start time is the same in the dialog'))

View File

@ -26,15 +26,15 @@ registerSuite(() => {
var controllerName = 'Supermicro X9DRW';
var computeName = 'Dell Inspiron';
var workflowName = 'epicBoost';
var modalBodySelector = 'div.modal-body';
var modalBody = 'div.modal-body';
var workflowTabSelector = 'div.workflows-tab ';
var toolbarSelector = workflowTabSelector + 'div.deployment-graphs-toolbar ';
var filterWorkflowsButton = toolbarSelector + 'button.btn-filters';
var uploadNewGraphButton = toolbarSelector + 'button.btn-upload-graph';
var workflowTableSelector = workflowTabSelector + 'table.workflows-table ';
var tableBodySelector = workflowTableSelector + 'tbody ';
var tableRowSelector = tableBodySelector + 'tr';
var workflowTab = 'div.workflows-tab ';
var toolbar = workflowTab + 'div.deployment-graphs-toolbar ';
var filterWorkflowsButton = toolbar + 'button.btn-filters';
var uploadNewGraphButton = toolbar + 'button.btn-upload-graph';
var workflowTable = workflowTab + 'table.workflows-table ';
var tableBody = workflowTable + 'tbody ';
var tableRow = tableBody + 'tr';
var deleteGraphButton = 'button.btn-remove-graph';
return {
@ -56,179 +56,219 @@ registerSuite(() => {
beforeEach() {
return this.remote
.then(() => clusterPage.goToTab('Workflows'))
.assertElementAppears(workflowTabSelector, 5000, '"Workflows" tab appears');
.assertElementAppears(workflowTab, 5000, '"Workflows" tab appears');
},
'Check that default "Workflow" is not avaliable as deployment mode'() {
var deployModeMenuSelector = 'ul.dropdown-menu';
var deployModeMenu = 'ul.dropdown-menu';
return this.remote
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => dashboardLib.changeDeploymentMode('Workflow'))
.assertElementNotDisplayed(deployModeMenuSelector, 'Deployment Mode menu is not displayed')
.assertElementNotDisplayed(deployModeMenu, 'Deployment Mode menu is not displayed')
.catch((error) => {
return this.remote
.pressKeys('\uE00C')
.assertElementNotDisplayed(deployModeMenuSelector,
'Default "Workflow" is not avaliable at Deployment Mode menu. Check error message: ' +
error);
.assertElementNotDisplayed(deployModeMenu, 'Default "Workflow" is not ' +
'avaliable at Deployment Mode menu. Check error message: ' +
error);
});
},
'Check that "Workflows" tab is worked'() {
var workflowTitleSelector = workflowTabSelector + 'div.title';
var tableHeaderSelector = workflowTableSelector + 'thead';
var workflowTitle = workflowTab + 'div.title';
var tableHeader = workflowTable + 'thead';
return this.remote
.assertElementExists(workflowTitleSelector, '"Workflows" title exists')
.assertElementMatchesRegExp(workflowTitleSelector, /Workflows/i,
'"Workflows" title has correct description')
.assertElementExists(workflowTitle, '"Workflows" title exists')
.assertElementMatchesRegExp(workflowTitle, /Workflows/i,
'"Workflows" title has correct description')
.assertElementEnabled(filterWorkflowsButton, '"Filter Workflows" button exists')
.assertElementEnabled(uploadNewGraphButton, '"Upload New Workflow" button exists')
.assertElementExists(tableHeaderSelector, '"Workflows" table header exists')
.assertElementMatchesRegExp(tableHeaderSelector, /Name Level Actions Download/i,
'"Workflows" table header has correct description')
.assertElementExists(tableBodySelector, '"Workflows" table body exists')
.assertElementsExist(tableRowSelector, 3,
'Workflows table includes release- and cluster-level default workflows')
.assertElementContainsText(tableRowSelector + ':first-child', 'Type "default"',
'The first row is default resulting graph for the cluster')
.assertElementContainsText(tableRowSelector + ':nth-child(2)', 'Release',
'The second row is "Release" level of graph for the cluster')
.assertElementContainsText(tableRowSelector + ':nth-child(3)', 'Environment',
'The third row is "Environment" level of graph for the cluster')
.assertElementNotExists(tableRowSelector + ':first-child ' + deleteGraphButton,
'User can not delete resulting graph for the cluster')
.assertElementExists(tableRowSelector + ':last-child ' + deleteGraphButton,
'User can delete default cluster graph');
.assertElementExists(tableHeader, '"Workflows" table header exists')
.assertElementMatchesRegExp(tableHeader, /Name Level Actions Download/i,
'"Workflows" table header has correct description')
.assertElementExists(tableBody, '"Workflows" table body exists')
.assertElementsExist(tableRow, 3, 'Workflows table includes release- and ' +
'cluster-level default workflows')
.assertElementContainsText(tableRow + ':first-child', 'Type "default"',
'The first row is default resulting graph for the cluster')
.assertElementContainsText(tableRow + ':nth-child(2)', 'Release',
'The second row is "Release" level of graph for the cluster')
.assertElementContainsText(tableRow + ':nth-child(3)', 'Environment',
'The third row is "Environment" level of graph for the cluster')
.assertElementNotExists(tableRow + ':first-child ' + deleteGraphButton,
'User can not delete resulting graph for the cluster')
.assertElementExists(tableRow + ':last-child ' + deleteGraphButton,
'User can delete default cluster graph');
},
'Check "Workflows" tab support filtering'() {
var filtersPaneSelector = toolbarSelector + 'div.filters ';
var graphTypeButton = filtersPaneSelector + 'div.filter-by-graph_type button';
var graphLevelButton = filtersPaneSelector + 'div.filter-by-graph_level button';
var filterPopover = toolbarSelector + 'div.popover div.popover-content ';
var resetFilter = filtersPaneSelector + 'button.btn-reset-filters';
var alertSelector = workflowTabSelector + 'div.alert';
var filtersPane = toolbar + 'div.filters ';
var graphTypeButton = filtersPane + 'div.filter-by-graph_type button';
var graphLevelButton = filtersPane + 'div.filter-by-graph_level button';
var filterPopover = toolbar + 'div.popover div.popover-content ';
var resetFilter = filtersPane + 'button.btn-reset-filters';
var alert = workflowTab + 'div.alert';
return this.remote
.assertElementAppears(filterWorkflowsButton + ':enabled', 1000,
'Enabled "Filter Workflows" button appears')
'Enabled "Filter Workflows" button appears')
.clickByCssSelector(filterWorkflowsButton)
.assertElementAppears(filtersPaneSelector, 3000, '"Workflows" filter pane appears')
.assertElementAppears(filtersPane, 3000, '"Workflows" filter pane appears')
.assertElementEnabled(graphTypeButton, 'Filter by "Type" button exists')
.assertElementEnabled(graphLevelButton, 'Filter by "Level" button exists')
.assertElementsExist(tableRowSelector, 3,
'Table includes release- and cluster-level default workflows before filtering')
.assertElementsExist(tableRow, 3, 'Table includes release- and cluster-level default ' +
'workflows before filtering')
.clickByCssSelector(graphTypeButton)
.assertElementsAppear(filterPopover, 3000, '"Filter popover" by "Type" appears')
.clickByCssSelector(filterPopover + 'input[name="default"]')
.assertElementsExist(tableRowSelector, 3,
'Table includes release- and cluster-level default workflows after filtering by "Type"')
.assertElementsExist(tableRow, 3, 'Table includes release- and cluster-level default ' +
'workflows after filtering by "Type"')
.clickByCssSelector(graphLevelButton)
.assertElementsAppear(filterPopover, 3000, '"Filter popover" by "Level" appears')
.clickByCssSelector(filterPopover + 'input[name="plugin"]')
.assertElementDisappears(workflowTableSelector, 3000,
'Workflows table doesn`t have plugin workflows, so workflows table disappears')
.assertElementExists(alertSelector, 'Warning message exists')
.assertElementMatchesRegExp(alertSelector, /No workflows matched applied filters./i,
'Warning message has correct description')
.assertElementDisappears(workflowTable, 3000, 'Workflows table doesn`t have plugin ' +
'workflows, so workflows table disappears')
.assertElementExists(alert, 'Warning message exists')
.assertElementMatchesRegExp(alert, /No workflows matched applied filters./i,
'Warning message has correct description')
.clickByCssSelector(filterPopover + 'input[name="release"]')
.assertElementsAppear(workflowTableSelector, 3000, 'Workflows table appears')
.assertElementsExist(tableRowSelector, 2,
'Table includes release-level default workflow after filtering by "Level"')
.assertElementsAppear(workflowTable, 3000, 'Workflows table appears')
.assertElementsExist(tableRow, 2, 'Table includes release-level default workflow after ' +
'filtering by "Level"')
.assertElementEnabled(resetFilter, '"Reset Filter" button exists')
.clickByCssSelector(resetFilter)
.assertElementDisappears(filterPopover, 3000, '"Filter popover" by "Level" disappears')
.assertElementsExist(tableRowSelector, 3,
'Table includes release- and cluster-level default workflows after filter reset');
.assertElementsExist(tableRow, 3, 'Table includes release- and cluster-level default ' +
'workflows after filter reset');
},
'Check that user can upload new custom Graph'() {
var dialogUploadBody = 'div.upload-graph-form ';
var dialogUploadError = dialogUploadBody + 'div.has-error span.help-block';
return this.remote
.assertElementAppears(uploadNewGraphButton + ':enabled', 1000,
'Enabled "Upload New Workflow" button appears')
'Enabled "Upload New Workflow" button appears')
.clickByCssSelector(uploadNewGraphButton)
.then(() => modal.waitToOpen())
.then(() => modal.checkTitle('Upload New Workflow'))
.assertElementsExist(dialogUploadBody, 'Upload graph form is exist in the dialog window')
.then(() => modal.clickFooterButton('Upload'))
.assertElementExists(dialogUploadError, 'There is an error due to type field is empty')
.assertElementMatchesRegExp(dialogUploadError, /Invalid type/i,
'Error message has correct description')
'Error message has correct description')
.setInputValue(dialogUploadBody + 'input[name="type"]', 'default')
.then(() => modal.clickFooterButton('Upload'))
.assertElementExists(dialogUploadError, 'There is an error due to this type already exists')
.assertElementMatchesRegExp(dialogUploadError, /Workflow with this type already exists./i,
'Error message has correct description')
'Error message has correct description')
.setInputValue(dialogUploadBody + 'input[name=name]', workflowName)
.setInputValue(dialogUploadBody + 'input[name=type]', workflowName)
.assertElementDisappears(dialogUploadError, 1000, 'Error message disappears after set type')
.then(() => modal.clickFooterButton('Upload'))
.then(() => modal.waitToClose())
.assertElementsExist(tableRowSelector, 5, 'New graph successfully uploaded')
.assertElementContainsText(tableRowSelector + ':nth-child(4)', 'Type "' + workflowName +
'"', 'New graph includes resulting graph for just uploaded workflow')
.assertElementContainsText(tableRowSelector + ':nth-child(5)', 'Environment',
'New graph includes cluster-level for just uploaded workflow');
.assertElementsExist(tableRow, 5, 'New graph successfully uploaded')
.assertElementContainsText(tableRow + ':nth-child(4)', 'Type "' + workflowName + '"',
'New graph includes resulting graph for just uploaded workflow')
.assertElementContainsText(tableRow + ':nth-child(5)', 'Environment',
'New graph includes cluster-level for just uploaded workflow');
},
'Check that custom Workflow can be executed'() {
this.timeout = 75000;
var progressSelector = 'div.dashboard-tab div.progress';
var workflowPaneSelector = 'div.actions-panel ';
var customGraphSelector = workflowPaneSelector + 'select[name="customGraph"]';
var runWorkflowButton = workflowPaneSelector + 'button.btn-run-graph';
var progress = 'div.dashboard-tab div.progress';
var workflowPane = 'div.actions-panel ';
var customGraph = workflowPane + 'select[name="customGraph"]';
var runWorkflowButton = workflowPane + 'button.btn-run-graph';
return this.remote
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => dashboardLib.changeDeploymentMode('Workflow'))
.assertElementAppears(customGraphSelector, 3000, 'Custom workflow dropdown appears')
.assertElementPropertyEquals(customGraphSelector, 'value', workflowName,
'Custom workflow dropdown exists and shows just uploaded new graph')
.assertElementAppears(customGraph, 3000, 'Custom workflow dropdown appears')
.assertElementPropertyEquals(customGraph, 'value', workflowName, 'Custom workflow ' +
'dropdown exists and shows just uploaded new graph')
.clickByCssSelector(runWorkflowButton)
.then(() => modal.waitToOpen())
.then(() => modal.checkTitle('Run Custom Workflow'))
.assertElementContainsText(modalBodySelector,
'Click Run Workflow to execute custom deployment tasks on the selected nodes.',
'Confirmation message is correct')
.assertElementContainsText(modalBody, 'Click Run Workflow to execute custom deployment ' +
'tasks on the selected nodes.',
'Confirmation message is correct')
.then(() => modal.clickFooterButton('Run Workflow'))
.assertElementDisappears('div.confirmation-question', 5000, 'Confirm dialog disappears')
.assertElementAppears(modalBodySelector, 1000, 'Error message appears')
.assertElementContainsText(modalBodySelector, 'Deployment tasks not found for',
'Workflow can not be started because it contains no deployment tasks')
.assertElementAppears(modalBody, 1000, 'Error message appears')
.assertElementContainsText(modalBody, 'There are no deployment tasks for graph',
'Workflow can not be started because it contains no ' +
'deployment tasks')
.then(() => modal.clickFooterButton('Close'))
.then(() => modal.waitToClose())
.then(() => dashboardLib.changeDeploymentMode('Deploy'))
.then(() => dashboardPage.startDeployment())
.assertElementsAppear(progressSelector, 10000, 'Deployment is started')
.assertElementDisappears(progressSelector, 45000, 'Deployment is finished')
.assertElementsAppear(workflowPaneSelector, 5000, 'Workflow panel is shown on Dashboard')
.assertElementPropertyEquals(customGraphSelector, 'value', workflowName,
'Custom workflow dropdown is shown on the dashboard for the operational cluster')
.assertElementsAppear(progress, 10000, 'Deployment is started')
.assertElementDisappears(progress, 45000, 'Deployment is finished')
.assertElementsAppear(workflowPane, 5000, 'Workflow panel is shown on Dashboard')
.assertElementPropertyEquals(customGraph, 'value', workflowName,
'Custom workflow dropdown is shown on the dashboard for ' +
'the operational cluster')
.assertElementContainsText(runWorkflowButton, 'Run Workflow on 2 Nodes',
'User can run custom graph for operational cluster');
'User can run custom graph for operational cluster');
},
'Check "Workflows" nodes selection dialog supports Quick Search, Sorting and Filtering'() {
this.timeout = 45000;
var deepCheck = [controllerName, computeName, ['input[name="error"]']];
return this.remote
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => dashboardLib.selectNodes('Custom Workflow', 1, 1, 1, 0, deepCheck));
},
'Check that user can delete Workflow'() {
var tableRowLast = tableRowSelector + ':last-child ';
var tableRowLast = tableRow + ':last-child ';
var confirmationForm = 'div.confirmation-form ';
var deleteWorkflowSelector = 'div.modal-footer button.remove-graph-btn';
var deleteWorkflow = 'div.modal-footer button.remove-graph-btn';
return this.remote
.assertElementAppears(tableRowLast + deleteGraphButton, 1000,
'User can delete cluster graph')
'User can delete cluster graph')
.clickByCssSelector(tableRowLast + deleteGraphButton)
.then(() => modal.waitToOpen())
.then(() => modal.checkTitle('Delete Workflow'))
.assertElementExists(modalBodySelector, 'Warning message is shown')
.assertElementContainsText(modalBodySelector, 'Important' +
'Are you sure you want to delete this workflow?', 'Warning message is correct')
.assertElementExists(modalBody, 'Warning message is shown')
.assertElementContainsText(modalBody, 'Important' + 'Are you sure you want to delete ' +
'this workflow?', 'Warning message is correct')
.then(() => modal.clickFooterButton('Delete'))
.assertElementAppears(confirmationForm, 1000, 'Confirmation form for graph removing appers')
.assertElementDisabled(deleteWorkflowSelector,
'Delete button is disabled, until requested confirmation text will be entered')
.assertElementDisabled(deleteWorkflow, 'Delete button is disabled, until requested ' +
'confirmation text will be entered')
.setInputValue(confirmationForm + 'input', workflowName)
.assertElementEnabled(deleteWorkflowSelector,
'Delete button is enabled after requested confirmation text entered')
.assertElementEnabled(deleteWorkflow, 'Delete button is enabled after requested ' +
'confirmation text entered')
.then(() => modal.clickFooterButton('Delete'))
.then(() => modal.waitToClose())
.assertElementNotContainsText(tableRowLast, workflowName,

View File

@ -31,53 +31,56 @@ import 'tests/functional/helpers';
registerSuite(() => {
var common, clusterPage, clustersPage, dashboardPage, nodesLib, genericLib, historyLib, command,
clusterName, firstDeployDate, controllerName;
var nodeNameSelector = 'div.nodes-group div.node div.name';
var progressSelector = 'div.dashboard-tab div.progress';
var showDetailsSelector = 'div.toggle-history button';
var nodeName = 'div.nodes-group div.node div.name';
var progress = 'div.dashboard-tab div.progress';
var showDetails = 'div.toggle-history button';
var historyTabSelector = 'div.history-tab ';
var historyTitleSelector = historyTabSelector + 'div.title';
var historyAlertSelector = historyTabSelector + 'div.alert';
var historyLineSelector = historyTabSelector + 'div.transaction-list ';
var historyPointSelector = historyLineSelector + 'a.transaction-link.ready';
var historyTab = 'div.history-tab ';
var historyTitle = historyTab + 'div.title';
var historyAlert = historyTab + 'div.alert';
var historyLine = historyTab + 'div.transaction-list ';
var historyPoint = historyLine + 'a.transaction-link.ready';
var historyPointText = 'Deployment\n';
var historyToolbarSelector = 'div.deployment-history-toolbar ';
var timelineViewButton = historyToolbarSelector + 'label.timeline-view';
var tableViewButton = historyToolbarSelector + 'label.table-view';
var filterTasksButton = historyToolbarSelector + 'button.btn-filters';
var exportCSVButton = historyToolbarSelector + 'button.btn-export-history-csv';
var zoomInButton = historyToolbarSelector + 'button.btn-zoom-in';
var zoomOutButton = historyToolbarSelector + 'button.btn-zoom-out';
var historyToolbar = 'div.deployment-history-toolbar ';
var timelineViewButton = historyToolbar + 'label.timeline-view';
var tableViewButton = historyToolbar + 'label.table-view';
var filterTasksButton = historyToolbar + 'button.btn-filters';
var exportCSVButton = historyToolbar + 'button.btn-export-history-csv';
var zoomInButton = historyToolbar + 'button.btn-zoom-in';
var zoomOutButton = historyToolbar + 'button.btn-zoom-out';
var timelinePaneSelector = 'div.deployment-timeline ';
var nodeNameLink = timelinePaneSelector + 'div.node-names button.btn-link';
var nodeTaskItem = timelinePaneSelector + 'div.timelines div.node-task';
var timelinePane = 'div.deployment-timeline ';
var nodeNameLink = timelinePane + 'div.node-names button.btn-link';
var nodeTaskItem = timelinePane + 'div.timelines div.node-task';
var taskPopover = 'div.popover.deployment-task-info div.popover-content ';
var popoverTaskName = taskPopover + 'div.task_name ';
var popoverStatus = taskPopover + 'div.status ';
var popoverStartTime = taskPopover + 'div.time_start ';
var popoverEndTime = taskPopover + 'div.time_end ';
var tablePaneSelector = 'div.history-table table ';
var tableBodyRow = tablePaneSelector + 'tbody tr';
var tablePane = 'div.history-table table ';
var tableBodyRow = tablePane + 'tbody tr';
return {
name: 'Deployment History',
setup() {
common = new Common(this.remote);
clusterPage = new ClusterPage(this.remote);
clustersPage = new ClustersPage(this.remote);
dashboardPage = new DashboardPage(this.remote);
nodesLib = new NodesLib(this.remote);
genericLib = new GenericLib(this.remote);
historyLib = new HistoryLib(this.remote);
command = new Command(this.remote);
clusterName = common.pickRandomName('Deployment History');
command = new Command(this.remote);
clusterName = common.pickRandomName('Deployment History');
return this.remote
.then(() => common.getIn())
.then(() => common.createCluster(clusterName))
.then(() => common.addNodesToCluster(1, ['Controller']))
.findByCssSelector(nodeNameSelector)
.findByCssSelector(nodeName)
.getVisibleText()
.then((nodeName) => {controllerName = nodeName;})
.end();
@ -85,93 +88,117 @@ registerSuite(() => {
'Check "History" tab before deployment'() {
return this.remote
.then(() => clusterPage.goToTab('History'))
.assertElementAppears(historyTabSelector, 5000, '"History" tab appears')
.assertElementExists(historyTitleSelector, '"Deployment History" title exists')
.assertElementMatchesRegExp(historyTitleSelector, /Deployment History/i,
'"Deployment History" title has correct description')
.assertElementExists(historyAlertSelector, 'Alert message exists')
.assertElementMatchesRegExp(historyAlertSelector, /No deployment finished yet./i,
'Alert message is correct');
.assertElementAppears(historyTab, 5000, '"History" tab appears')
.assertElementExists(historyTitle, '"Deployment History" title exists')
.assertElementMatchesRegExp(historyTitle, /Deployment History/i,
'"Deployment History" title has correct description')
.assertElementExists(historyAlert, 'Alert message exists')
.assertElementMatchesRegExp(historyAlert, /No deployment finished yet./i,
'Alert message is correct');
},
'Check "History" tab after first deployment'() {
this.timeout = 70000;
return this.remote
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => historyLib.waitForZeroSeconds())
.then(() => dashboardPage.startDeployment())
.then(() => {firstDeployDate = moment().format('HH:mm DD/MM/YYYY');})
.then(() => clusterPage.goToTab('History'))
.assertElementDisappears(historyAlertSelector, 45000, 'Deployment is successful')
.assertElementExists(historyTitleSelector, '"Deployment History" title exists')
.assertElementMatchesRegExp(historyTitleSelector, /Deployment History/i,
'"Deployment History" title has correct description')
.assertElementExists(historyLineSelector, '"History line" pane exists')
.assertElementsExist(historyPointSelector + '.active', 1,
'Only 1 point of "history line" is observed and selected after deployment')
.findByCssSelector(historyPointSelector)
.assertElementDisappears(historyAlert, 45000, 'Deployment is successful')
.assertElementExists(historyTitle, '"Deployment History" title exists')
.assertElementMatchesRegExp(historyTitle, /Deployment History/i,
'"Deployment History" title has correct description')
.assertElementExists(historyLine, '"History line" pane exists')
.assertElementsExist(historyPoint + '.active', 1, 'Only 1 point of "history line" is ' +
'observed and selected after deployment')
.findByCssSelector(historyPoint)
.getVisibleText()
.then((actualText) => assert.equal(actualText, historyPointText + firstDeployDate,
'"History point" has correct description, time and date'))
.end()
.assertElementEnabled(timelineViewButton + '.active',
'"Timeline View" button exists and active')
'"Timeline View" button exists and active')
.assertElementEnabled(tableViewButton + ':not(.active)',
'"Table View" button exists and not active')
'"Table View" button exists and not active')
.assertElementExists(exportCSVButton + ':enabled', '"Export CSV" button exists and enabled')
.assertElementExists(zoomInButton + ':disabled', '"Zoom In" button exists and disabled')
.assertElementExists(zoomOutButton + ':disabled', '"Zoom Out" button exists and disabled')
.assertElementExists(timelinePaneSelector, '"Timeline pane" exists and opened by default')
.assertElementExists(timelinePane, '"Timeline pane" exists and opened by default')
// Check that user can switch between "Timeline View" and "Table View"
.clickByCssSelector(tableViewButton)
.assertElementsAppear(tablePaneSelector, 5000, '"Table pane" appears')
.assertElementsAppear(tablePane, 5000, '"Table pane" appears')
.assertElementEnabled(timelineViewButton + ':not(.active)',
'"Timeline View" button exists and not active')
'"Timeline View" button exists and not active')
.assertElementEnabled(tableViewButton + '.active', '"Table View" button exists and active')
.assertElementExists(filterTasksButton + ':enabled',
'"Filter Tasks" button exists and enabled')
'"Filter Tasks" button exists and enabled')
.assertElementExists(exportCSVButton + ':enabled', '"Export CSV" button exists and enabled')
.clickByCssSelector(timelineViewButton)
.assertElementsAppear(timelinePaneSelector, 5000, '"Timeline pane" appears');
.assertElementsAppear(timelinePane, 5000, '"Timeline pane" appears');
},
'Check that "History timeline" progress indicator is worked'() {
this.timeout = 75000;
var currentTimeMarkerPosition;
var timeMarkerSelector = timelinePaneSelector + 'div.current-time-marker';
var timeMarker = timelinePane + 'div.current-time-marker';
return this.remote
.then(() => common.addNodesToCluster(1, ['Controller']))
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => dashboardPage.startDeployment())
.assertElementAppears(showDetailsSelector, 10000,
'Deployment is started and "Show Details" button is shown')
.clickByCssSelector(showDetailsSelector)
.assertElementsAppear(timelinePaneSelector, 5000, 'Deployment history timeline appears')
.assertElementAppears(showDetails, 10000,
'Deployment is started and "Show Details" button is shown')
.clickByCssSelector(showDetails)
.assertElementsAppear(timelinePane, 5000, 'Deployment history timeline appears')
.clickByCssSelector(tableViewButton)
.assertElementsAppear(tablePaneSelector, 5000, '"Table pane" appears')
.assertElementsAppear(tablePane, 5000, '"Table pane" appears')
.clickByCssSelector(timelineViewButton)
.assertElementsAppear(timelinePaneSelector, 5000, '"Timeline pane" appears')
.assertElementsAppear(timelinePane, 5000, '"Timeline pane" appears')
.assertElementsExist(nodeNameLink, 2, '2 slave nodes are shown')
.assertElementsAppear(nodeTaskItem, 20000, 'Deployment tasks appear on the timeline')
.assertElementAppears(timeMarkerSelector, 5000, 'Time marker appears on the timeline')
.findByCssSelector(timeMarkerSelector)
.assertElementAppears(timeMarker, 5000, 'Time marker appears on the timeline')
.findByCssSelector(timeMarker)
.getComputedStyle('left')
.then((value) => {currentTimeMarkerPosition = parseInt(value.split(' ')[0], 10);})
.end()
.then(pollUntil(() =>
window.$('.deployment-timeline .timelines .node-task').length >= 6 || null, 60000))
.findByCssSelector(timeMarkerSelector)
.findByCssSelector(timeMarker)
.getComputedStyle('left')
.then((value) => {
return assert.isTrue(parseInt(value.split(' ')[0], 10) > currentTimeMarkerPosition,
'Current time marker is moving showing tasks progress');
'Current time marker is moving showing tasks progress');
})
.end()
.assertElementDisappears(progressSelector, 30000, 'Deployment is finished');
.assertElementDisappears(progress, 30000, 'Deployment is finished');
},
'Check "History" tab after third cluster deployment'() {
this.timeout = 80000;
var thirdDeployDate;
var activeHistoryPoint = historyPointSelector + '.active';
var inactiveHistoryPoint = historyPointSelector + ':not(.active)';
var activeHistoryPoint = historyPoint + '.active';
var inactiveHistoryPoint = historyPoint + ':not(.active)';
var lgreyColor = 'rgba(220, 220, 220, 1)';
var greyColor = 'rgba(200, 200, 200, 1)';
var lblueColor = 'rgba(90, 143, 179, 1)';
@ -179,109 +206,143 @@ registerSuite(() => {
var dblueColor = 'rgba(35, 82, 124, 1)';
var lgreenColor = 'rgba(84, 168, 84, 1)';
var greenColor = 'rgba(64, 148, 64, 1)';
return this.remote
// Check that "Deployment History" timeline is worked
.then(() => common.addNodesToCluster(1, ['Controller']))
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => historyLib.waitForZeroSeconds())
.then(() => dashboardPage.startDeployment())
.then(() => {thirdDeployDate = moment().format('HH:mm DD/MM/YYYY');})
.assertElementsAppear(progressSelector, 10000, 'Deployment is started')
.assertElementDisappears(progressSelector, 45000, 'Deployment is finished')
.assertElementsAppear(progress, 10000, 'Deployment is started')
.assertElementDisappears(progress, 45000, 'Deployment is finished')
.then(() => clusterPage.goToTab('History'))
.assertElementsExist(historyPointSelector, 3, '3 points of "history line" are observed')
.assertElementsExist(activeHistoryPoint, 1,
'First point of "history line" is observed and still selected after third deployment')
.assertElementsExist(inactiveHistoryPoint, 2,
'2 points of "history line" are observed and not selected after third deployment')
.assertElementsExist(historyPoint, 3, '3 points of "history line" are observed')
.assertElementsExist(activeHistoryPoint, 1, 'First point of "history line" is observed ' +
'and still selected after third deployment')
.assertElementsExist(inactiveHistoryPoint, 2, '2 points of "history line" are observed ' +
'and not selected after third deployment')
.assertElementTextEquals(activeHistoryPoint, historyPointText + firstDeployDate,
'First "History point" has correct description, time and date after third deployment')
'First "History point" has correct description, time and date ' +
'after third deployment')
.findByCssSelector(inactiveHistoryPoint + ':last-child')
.getVisibleText()
.then((actualText) => assert.equal(actualText, historyPointText + thirdDeployDate,
'Third "History point" has correct description, time and date after deployment'))
'Third "History point" has correct description, ' +
'time and date after deployment'))
.end()
.assertElementsExist(nodeNameLink, 1, 'Only 1 node is observed after first deployment')
.clickByCssSelector(inactiveHistoryPoint + ':last-child')
.assertElementsAppear(timelinePaneSelector, 5000, '"Timeline pane" appears')
.assertElementsAppear(timelinePane, 5000, '"Timeline pane" appears')
.assertElementsAppear(activeHistoryPoint + ':last-child', 5000,
'Thirs "History point" is switched to active state')
'Thirs "History point" is switched to active state')
.assertElementsExist(nodeNameLink, 3, '3 nodes are observed after third deployment')
// Check "Deployment History" timeline visual design for different states
.then(() => genericLib.moveCursorTo(historyTitleSelector))
.sleep(500)
.then(() => genericLib.moveCursorTo(historyTitle)).sleep(500)
.then(() => genericLib.checkSelectorColors('Inactive and unhovered first "History point" ',
inactiveHistoryPoint + ':not(:hover)', lgreyColor, lblueColor, lblueColor))
.then(() => genericLib.moveCursorTo(inactiveHistoryPoint))
inactiveHistoryPoint + ':not(:hover)',
lgreyColor, lblueColor, lblueColor))
.then(() => genericLib.moveCursorTo(inactiveHistoryPoint)).sleep(500)
.then(() => genericLib.checkSelectorColors('Inactive and hovered first "History point"',
inactiveHistoryPoint + ':hover', greyColor, blueColor, blueColor))
.then(() => genericLib.moveCursorTo(historyTitleSelector))
.sleep(500)
inactiveHistoryPoint + ':hover',
greyColor, blueColor, blueColor))
.then(() => genericLib.moveCursorTo(historyTitle)).sleep(500)
.then(() => genericLib.checkSelectorColors('Active and unhovered third "History point"',
activeHistoryPoint + ':not(:hover)', lgreenColor, dblueColor, dblueColor))
.then(() => genericLib.moveCursorTo(activeHistoryPoint))
activeHistoryPoint + ':not(:hover)',
lgreenColor, dblueColor, dblueColor))
.then(() => genericLib.moveCursorTo(activeHistoryPoint)).sleep(500)
.then(() => genericLib.checkSelectorColors('Active and hovered third "History point"',
activeHistoryPoint + ':hover', greenColor, blueColor, blueColor));
activeHistoryPoint + ':hover',
greenColor, blueColor, blueColor));
},
'Check that "Deployment History" results are saved'() {
this.timeout = 60000;
var activeHistoryPoint = historyPointSelector + '.active';
var activeHistoryPoint = historyPoint + '.active';
var tabNames = ['Dashboard', 'Nodes', 'Networks', 'Settings', 'Logs', 'Workflows',
'Health Check'];
'Health Check'];
var chain = this.remote;
chain = chain.then(() => clusterPage.goToTab('History'))
.assertElementsAppear(timelinePaneSelector, 5000, '"Timeline pane" appears')
.clickByCssSelector(historyPointSelector);
.assertElementsAppear(timelinePane, 5000, '"Timeline pane" appears')
.clickByCssSelector(historyPoint);
// Check that "Deployment History" results saved after refreshing of page
chain = chain.then(() => command.refresh())
.waitForCssSelector(activeHistoryPoint, 5000)
.assertElementTextEquals(activeHistoryPoint, historyPointText + firstDeployDate,
'First "History point" still selected after refreshing of page');
'First "History point" still selected after refreshing of page');
// Check that "Deployment History" results saved after switching between cluster tabs
for (let i = 0; i < tabNames.length; i++) {
chain = chain.findByCssSelector('.cluster-page .tabs')
.clickLinkByText(tabNames[i])
.end()
.then(pollUntil((text) => window.$('.cluster-tab.active').text() === text || null,
[tabNames[i]], 3000))
[tabNames[i]], 3000))
.findByCssSelector('.cluster-page .tabs')
.clickLinkByText('History')
.end()
.then(pollUntil((text) => window.$('.cluster-tab.active').text() === text || null,
['History'], 3000))
['History'], 3000))
.waitForCssSelector(activeHistoryPoint, 3000)
.assertElementTextEquals(activeHistoryPoint, historyPointText + firstDeployDate,
'First "History point" still selected after swithing to "' + tabNames[i] + '" tab');
'First "History point" still selected after swithing to "' +
tabNames[i] + '" tab');
}
// Check that "Deployment History" results are not saved after switching to other page
chain = chain.then(() => genericLib.gotoPage('Equipment'))
.then(() => genericLib.gotoPage('Environments'))
.then(() => clustersPage.goToEnvironment(clusterName))
.then(() => clusterPage.goToTab('History'))
.assertElementsAppear(activeHistoryPoint + ':last-child', 5000,
'Last "History point" is switched to active state after switching to other page')
.assertElementsAppear(activeHistoryPoint + ':last-child', 5000, 'Last "History point" is ' +
'switched to active state after switching to other page')
.assertElementNotContainsText(activeHistoryPoint, historyPointText + firstDeployDate,
'First "History point" is not selected after switching to other page');
'First "History point" is not selected after switching to ' +
'other page');
return chain;
},
'Check that "Timeline View" is worked'() {
this.timeout = 60000;
var nodeNameColumn = timelinePaneSelector + 'div.node-names-column ';
var timelineColumn = timelinePaneSelector + 'div.timelines-column ';
var masterNodeSelector = nodeNameColumn + 'div.node-names div[style^="height"]:first-child';
var nodeNameColumn = timelinePane + 'div.node-names-column ';
var timelineColumn = timelinePane + 'div.timelines-column ';
var masterNode = nodeNameColumn + 'div.node-names div[style^="height"]:first-child';
return this.remote
// Check "Timeline View"
.then(() => clusterPage.goToTab('History'))
.assertElementsAppear(timelinePaneSelector, 5000, '"Timeline pane" appears')
.waitForCssSelector(historyPointSelector, 3000)
.clickByCssSelector(historyPointSelector)
.assertElementsAppear(timelinePane, 5000, '"Timeline pane" appears')
.waitForCssSelector(historyPoint, 3000)
.clickByCssSelector(historyPoint)
.assertElementExists(nodeNameColumn, 'Node names column exists')
.assertElementsExist(masterNodeSelector, 1, 'Master node exists')
.assertElementTextEquals(masterNodeSelector, 'Master node', 'Master node has correct name')
.assertElementsExist(masterNode, 1, 'Master node exists')
.assertElementTextEquals(masterNode, 'Master node', 'Master node has correct name')
.assertElementsExist(nodeNameLink, 1, '1 controller node exists')
.assertElementTextEquals(nodeNameLink, controllerName, 'Controller has correct name')
.assertElementExists(timelineColumn, 'Timeline column exists')
.assertElementsExist(nodeTaskItem, 7, '7 node tasks are observed')
.assertElementsExist(nodeTaskItem, 8, '8 node tasks are observed')
// Check popups
.then(() => genericLib.moveCursorTo(nodeTaskItem + ':first-child'))
.assertElementsAppear(taskPopover, 3000, 'Node task popover appears')
@ -289,24 +350,27 @@ registerSuite(() => {
.assertElementContainsText(popoverStatus, 'Status', 'Task "Status" field is observed')
.assertElementContainsText(popoverStartTime, 'Started', 'Task "Started" field is observed')
.assertElementContainsText(popoverEndTime, 'Finished', 'Task "Finished" field is observed')
.then(() => genericLib.moveCursorTo(historyPointSelector))
.then(() => genericLib.moveCursorTo(historyPoint))
.assertElementDisappears(taskPopover, 3000, 'Node task popover disappears');
},
'Check that "Table View" is worked'() {
var currentTime = firstDeployDate.split(' ')[0];
var currentDate = firstDeployDate.split(' ')[1];
var tableHeader = tablePaneSelector + 'thead th';
return this.remote
var tableHeader = tablePane + 'thead th';
this.remote
// Check that deploy start date/time the same as real
.then(() => genericLib.moveCursorTo(nodeTaskItem + ':first-child'))
.assertElementsAppear(taskPopover, 3000, 'Node task popover appears')
.assertElementContainsText(popoverStartTime + 'span:last-child', currentTime,
'Task start time the same as real via "Timeline View"')
'Task start time the same as real via "Timeline View"')
.assertElementContainsText(popoverStartTime + 'span:last-child', currentDate,
'Task start date the same as real via "Timeline View"')
'Task start date the same as real via "Timeline View"')
// Check "Table View"
.clickByCssSelector(tableViewButton)
.assertElementsAppear(tablePaneSelector, 5000, '"Table pane" appears')
.assertElementsAppear(tablePane, 5000, '"Table pane" appears')
.assertElementsExist(tableHeader, 7, '7 columns are observed by default')
.assertElementTextEquals(tableHeader + ':nth-child(1)', 'Task', 'Column has true name')
.assertElementTextEquals(tableHeader + ':nth-child(2)', 'Node', 'Column has true name')
@ -315,123 +379,170 @@ registerSuite(() => {
.assertElementTextEquals(tableHeader + ':nth-child(5)', 'Started', 'Column has true name')
.assertElementTextEquals(tableHeader + ':nth-child(6)', 'Finished', 'Column has true name')
.assertElementTextEquals(tableHeader + ':nth-child(7)', '', 'Column has true name')
.assertElementsExist(tableBodyRow, 7, '7 node tasks are observed')
.assertElementsExist(tableBodyRow + ' td', 49, '49 cells are observed in the table')
.assertElementTextEquals(tableBodyRow + ' td:nth-child(2)', 'Master node',
'Master node has correct name')
.assertElementTextEquals(tableBodyRow + ':nth-child(2) td:nth-child(2)', controllerName,
'Controller node has correct name')
.assertElementsExist(tableBodyRow, 8, '8 node tasks are observed')
.assertElementsExist(tableBodyRow + ' td', 56, '56 cells are observed in the table')
.findAllByCssSelector('table tr td:nth-child(2)')
.then((names) => names.reduce(
(result, name) => name
.getVisibleText()
.then((label) => assert(label === controllerName || label === 'Master node',
'Invalid node name. Expected "' + label + '" to be "' +
controllerName + '" or "Master node"')), false))
.end()
.assertElementContainsText(tableBodyRow + ' td:nth-child(5)', currentTime,
'Task start time the same as real via "Table View"')
'Task start time the same as real via "Table View"')
.assertElementContainsText(tableBodyRow + ' td:nth-child(5)', currentDate,
'Task start date the same as real via "Table View"');
'Task start date the same as real via "Table View"');
},
'Check that "Timeline View" data equals to "Table View" data'() {
this.timeout = 60000;
var filterByNode = 'div.filters div.filter-by-node_id button';
var node = '.filter-by-node_id .popover-content div:nth-child(2) input';
return this.remote
// Filter to exclude master node
.clickByCssSelector('div.deployment-history-toolbar button.btn-filters')
.clickByCssSelector(filterByNode)
.clickByCssSelector(node)
.clickByCssSelector(filterByNode)
.then(() => historyLib.compareViewsData(2, controllerName))
.then(() => historyLib.compareViewsData(3, controllerName))
.then(() => historyLib.compareViewsData(4, controllerName))
.then(() => historyLib.compareViewsData(5, controllerName))
.then(() => historyLib.compareViewsData(6, controllerName))
.then(() => historyLib.compareViewsData(7, controllerName));
.then(() => historyLib.compareViewsData(7, controllerName))
.clickByCssSelector('.btn-reset-filters') // .discard-changes-icon
.clickByCssSelector('.btn-filters');
},
'Check "History" tab support filtering'() {
var filtersPaneSelector = 'div.filters ';
var taskNameButton = filtersPaneSelector + 'div.filter-by-task_name button';
var nodeNameButton = filtersPaneSelector + 'div.filter-by-node_id button';
var taskStatusButton = filtersPaneSelector + 'div.filter-by-status button';
var filtersPane = 'div.filters ';
var taskNameButton = filtersPane + 'div.filter-by-task_name button';
var nodeNameButton = filtersPane + 'div.filter-by-node_id button';
var taskStatusButton = filtersPane + 'div.filter-by-status button';
var filterPopover = 'div.popover div.popover-content ';
var resetFilter = filtersPaneSelector + 'button.btn-reset-filters';
var resetFilter = filtersPane + 'button.btn-reset-filters';
return this.remote
.clickByCssSelector(tableViewButton)
.assertElementsAppear(tablePaneSelector, 5000, '"Table pane" appears')
.assertElementsExist(tableBodyRow, 7, '7 node tasks are observed before filtering')
.assertElementsAppear(tablePane, 5000, '"Table pane" appears')
.assertElementsExist(tableBodyRow, 8, '8 node tasks are observed before filtering')
.clickByCssSelector(filterTasksButton)
.assertElementsAppear(filtersPaneSelector, 5000, '"Filter pane" appears')
.assertElementsAppear(filtersPane, 5000, '"Filter pane" appears')
.clickByCssSelector(taskNameButton)
.assertElementsAppear(filterPopover, 3000, '"Filter popover" for task name appears')
.clickByCssSelector(filterPopover + 'input[name="upload_configuration"]')
.assertElementsExist(tableBodyRow, 2, '2 node tasks are observed after task name filter')
.clickByCssSelector(taskStatusButton)
.assertElementsAppear(filterPopover, 3000, '"Filter popover" for task status appears')
.clickByCssSelector(filterPopover + 'input[name="ready"]')
.assertElementsExist(tableBodyRow, 2, '2 node tasks are observed after task status filter')
.clickByCssSelector(nodeNameButton)
.assertElementsAppear(filterPopover, 3000, '"Filter popover" for node name appears')
.clickByCssSelector(filterPopover + 'input[name="master"]')
.assertElementsExist(tableBodyRow, 1, '1 node task is observed after node name filter')
.assertElementTextEquals(tableBodyRow + ' td:nth-child(1)', 'upload_configuration',
'Task name has correct filtered value')
'Task name has correct filtered value')
.assertElementTextEquals(tableBodyRow + ' td:nth-child(2)', 'Master node',
'Node name has correct filtered value')
'Node name has correct filtered value')
.assertElementTextEquals(tableBodyRow + ' td:nth-child(3)', 'Ready',
'Task status has correct filtered value')
'Task status has correct filtered value')
.assertElementEnabled(resetFilter, '"Reset" button is available')
.clickByCssSelector(resetFilter)
.sleep(1000)
.assertElementsExist(tableBodyRow, 7, '7 node tasks are observed after filter resetting');
.clickByCssSelector(resetFilter).sleep(1000)
.assertElementsExist(tableBodyRow, 8, '8 node tasks are observed after filter resetting');
},
'Check that "Previous Deployments" dropdown is worked'() {
this.timeout = 300000;
var lastHistoryPoint = historyPointSelector + ':last-child';
var buttonPreviousDeployments = historyTabSelector + 'button.dropdown-toggle';
var dropdownMenuSelector = 'ul.dropdown-menu ';
var menuItemSelector = dropdownMenuSelector + 'li';
var lastItemSelector = menuItemSelector + ':last-child a.ready';
var lastHistoryPoint = historyPoint + ':last-child';
var buttonPreviousDeployments = historyTab + 'button.dropdown-toggle';
var dropdownMenu = 'ul.dropdown-menu ';
var menuItem = dropdownMenu + 'li';
var lastItem = menuItem + ':last-child a.ready';
return this.remote
// Precondition
.then(() => common.addNodesToCluster(1, ['Controller']))
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => dashboardPage.startDeployment())
.assertElementsAppear(progressSelector, 10000, 'Deployment is started')
.assertElementDisappears(progressSelector, 45000, 'Deployment is finished')
.assertElementsAppear(progress, 10000, 'Deployment is started')
.assertElementDisappears(progress, 45000, 'Deployment is finished')
.then(() => common.addNodesToCluster(1, ['Controller']))
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => dashboardPage.startDeployment())
.assertElementsAppear(progressSelector, 10000, 'Deployment is started')
.assertElementDisappears(progressSelector, 45000, 'Deployment is finished')
.assertElementsAppear(progress, 10000, 'Deployment is started')
.assertElementDisappears(progress, 45000, 'Deployment is finished')
.then(() => common.addNodesToCluster(1, ['Controller']))
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => dashboardPage.startDeployment())
.assertElementsAppear(progressSelector, 10000, 'Deployment is started')
.assertElementDisappears(progressSelector, 45000, 'Deployment is finished')
.assertElementsAppear(progress, 10000, 'Deployment is started')
.assertElementDisappears(progress, 45000, 'Deployment is finished')
.then(() => nodesLib.removeNodeFromCluster())
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => dashboardPage.startDeployment())
.assertElementsAppear(progressSelector, 10000, 'Deployment is started')
.assertElementDisappears(progressSelector, 45000, 'Deployment is finished')
.assertElementsAppear(progress, 10000, 'Deployment is started')
.assertElementDisappears(progress, 45000, 'Deployment is finished')
.then(() => nodesLib.removeNodeFromCluster())
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => dashboardPage.startDeployment())
.assertElementsAppear(progressSelector, 10000, 'Deployment is started')
.assertElementDisappears(progressSelector, 45000, 'Deployment is finished')
.assertElementsAppear(progress, 10000, 'Deployment is started')
.assertElementDisappears(progress, 45000, 'Deployment is finished')
.then(() => clusterPage.goToTab('History'))
// Restore "Previous Deployments" default state
.assertElementsAppear(lastHistoryPoint, 3000, 'Last "History point" appears')
.clickByCssSelector(lastHistoryPoint)
.assertElementsAppear(lastHistoryPoint + '.active', 1000, 'Last "History point" is active')
// Check "Previous Deployments"
.assertElementsAppear(buttonPreviousDeployments, 1000, '"Previous Deployments" btn appears')
.assertElementTextEquals(buttonPreviousDeployments, 'Previous Deployments',
'"Previous Deployments" button has correct title and dropdown toggle on it')
'"Previous Deployments" button has correct title and dropdown ' +
'toggle on it')
.clickByCssSelector(buttonPreviousDeployments)
.assertElementsAppear(dropdownMenuSelector, 1000, '"Previous Deployments" menu appears')
.assertElementsExist(menuItemSelector, 2, '2 menu items are observed after few deployments')
.assertElementTextEquals(lastItemSelector, historyPointText.slice(0, -1) + firstDeployDate,
'Menu item has correct description, time and date of first deployment')
.clickByCssSelector(lastItemSelector)
.waitForElementDeletion(dropdownMenuSelector, 1000)
.sleep(500)
.assertElementsAppear(dropdownMenu, 1000, '"Previous Deployments" menu appears')
.assertElementsExist(menuItem, 2, '2 menu items are observed after few deployments')
.assertElementTextEquals(lastItem, historyPointText.slice(0, -1) + firstDeployDate,
'Menu item has correct description, time and date of first ' +
'deployment')
.clickByCssSelector(lastItem)
.waitForElementDeletion(dropdownMenu, 1000).sleep(500)
.assertElementTextEquals(buttonPreviousDeployments + '.ready.active',
historyPointText + firstDeployDate,
'First "History point" has correct description, time and date after few deployments')
historyPointText + firstDeployDate, 'First "History point" has ' +
'correct description, time and date after few deployments')
.waitForCssSelector(nodeNameLink, 5000)
.assertElementsExist(nodeNameLink, 1, 'Only 1 node is observed after first deployment')
.clickByCssSelector(buttonPreviousDeployments)
.assertElementsAppear(dropdownMenuSelector, 1000, '"Previous Deployments" menu appears')
.assertElementsExist(menuItemSelector, 1,
'Only 1 menu item is observed after one of "Previous Deployments" is selected')
.assertElementsAppear(dropdownMenu, 1000, '"Previous Deployments" menu appears')
.assertElementsExist(menuItem, 1, 'Only 1 menu item is observed after one of ' +
'"Previous Deployments" is selected')
.pressKeys('\uE00C');
}
/*
@ -440,25 +551,25 @@ registerSuite(() => {
'Check "History" tab after environment reset'() {
this.timeout = 60000;
var firstHistoryPoint = historyTabSelector + 'button.dropdown-toggle.ready.active';
var firstHistoryPoint = historyTab + 'button.dropdown-toggle.ready.active';
return this.remote
.assertElementsAppear(firstHistoryPoint, 3000, 'First "History point" appears')
.assertElementTextEquals(firstHistoryPoint, historyPointText + firstDeployDate,
'First "History point" has correct description, time and date before environment reset')
.assertElementsExist(historyPointSelector, 6,
.assertElementsExist(historyPoint, 6,
'6 "History points" are observed before environment reset')
.then(() => clusterPage.goToTab('Dashboard'))
.then(() => clusterPage.resetEnvironment(clusterName))
.then(() => dashboardPage.discardChanges())
.then(() => clusterPage.goToTab('History'))
.assertElementAppears(historyTabSelector, 5000, '"History" tab appears')
.assertElementExists(historyTitleSelector, '"Deployment History" title exists')
.assertElementMatchesRegExp(historyTitleSelector, /Deployment History/i,
.assertElementAppears(historyTab, 5000, '"History" tab appears')
.assertElementExists(historyTitle, '"Deployment History" title exists')
.assertElementMatchesRegExp(historyTitle, /Deployment History/i,
'"Deployment History" title has correct description')
.assertElementExists(historyAlertSelector, 'Alert message exists')
.assertElementMatchesRegExp(historyAlertSelector, /No deployment finished yet./i,
.assertElementExists(historyAlert, 'Alert message exists')
.assertElementMatchesRegExp(historyAlert, /No deployment finished yet./i,
'Alert message is correct.')
.assertElementNotExists(historyPointSelector,
.assertElementNotExists(historyPoint,
'All history was removed after environment reset');
}
*/

View File

@ -1,12 +0,0 @@
- name: 'network:neutron:contrail'
label: 'Contrail'
description: 'Contrail SDN networking'
bind: !!pairs
- "cluster:net_provider": "neutron"
- "cluster:net_segment_type": "tun"
compatible:
- name: 'hypervisor:kvm'
- name: 'hypervisor:qemu'
incompatible:
- name: 'hypervisor:vmware'
description: 'Contrail plugin is not compatible with VMware for now'

View File

@ -1,11 +0,0 @@
- name: 'network:neutron:ml2:dvs'
label: 'Neutron with VMware DVS'
description: 'Neutron with VMware DVS ML2 plugin'
requires:
- name: 'network:neutron:core:ml2'
- name: 'hypervisor:vmware'
message: 'The VMware DVS plugin requires vCenter as the hypervisor option.'
compatible:
- name: 'hypervisor:*'
- name: 'network:neutron:ml2:vlan'
- name: 'network:neutron:core:ml2'

View File

@ -1,21 +0,0 @@
- name: "network:neutron:core:nsx"
label: "Neutron with NSXv plugin."
description: "NSXv plugin for Fuel allows to integrate Mirantis OpenStack with VMware NSXv network virtualization platform."
bind: !!pairs
- "cluster:net_segment_type": "tun"
compatible:
- name: "hypervisor:vmware"
- name: "hypervisor:qemu"
- name: "storage:block:lvm"
- name: "storage:image:ceph"
- name: "storage:object:ceph"
- name: "additional_service:ceilometer"
incompatible:
- name: "storage:block:ceph"
- name: "storage:ephemeral:ceph"
- name: "additional_service:sahara"
- name: "additional_service:murano"
- name: "additional_service:ironic"
requires:
- name: "hypervisor:vmware"
message: "NSXv requires use vCenter."

View File

@ -1,16 +0,0 @@
- name: 'additional_service:smile'
label: 'smile'
description: 'smile'
incompatible:
- name: 'network:nova_network'
requires:
- name: 'hypervisor:vmware'
- name: 'network:neutron:ml2:dvs'
compatible:
- name: 'additional_service:sahara'
- name: 'network:neutron:ml2:dvs'
label: 'dvs'
description: 'dvs'
- name: 'network:nova_network'
label: 'Nova network'

View File

@ -1,9 +0,0 @@
- name: 'additional_service:smile'
label: 'smile'
description: 'smile'
incompatible:
- name: 'additional_service:ceilometer'
requires:
- name: 'additional_service:murano'
compatible:
- name: 'additional_service:sahara'

View File

@ -1,9 +0,0 @@
- name: 'additional_service:smile'
label: 'smile'
description: 'smile'
incompatible:
- name: 'additional_service:ironic'
requires:
- name: 'additional_service:sahara'
compatible:
- name: 'additional_service:murano'

View File

@ -1,12 +0,0 @@
- name: 'additional_service:smile'
label: 'smile'
description: 'smile'
incompatible:
- name: 'network:neutron:ml2:tun'
- name: 'hypervisor:vmware'
requires:
- name: 'additional_service:sahara'
compatible:
- name: 'storage:block:ceph'
- name: 'network:neutron:ml2:dvs'
label: 'DVS network'

View File

@ -1,13 +0,0 @@
- name: 'network:neutron:core:nsx'
label: 'Neutron with NSXv plugin.'
description: 'NSXv plugin for Fuel allows to integrate Mirantis OpenStack with VMware NSXv network virtualization platform.'
bind: !!pairs
- 'cluster:net_segment_type': 'tun'
compatible:
- name: 'hypervisor:vmware'
- name: 'hypervisor:kvm'
- name: 'hypervisor:qemu'
- name: 'storage:block:lvm'
requires:
- name: 'hypervisor:vmware'
message: 'NSXv requires the usage of vCenter.'

View File

@ -1,11 +0,0 @@
- name: 'network:neutron:core:nsx'
label: 'Neutron with NSXv plugin.'
description: 'NSXv plugin for Fuel allows to integrate Mirantis OpenStack with VMware NSXv network virtualization platform.'
bind: !!pairs
- 'cluster:net_segment_type': 'tun'
compatible:
- name: 'hypervisor:vmware'
- name: 'storage:block:lvm'
requires:
- name: 'hypervisor:vmware'
message: 'NSXv requires the usage of vCenter.'

View File

@ -1,8 +0,0 @@
- name: 'hypervisor:libvirt:rain'
label: 'rain'
description: 'rain hypervisor'
incompatible:
- name: 'hypervisor:xen'
- name: 'hypervisor:xen'
label: 'xen'
description: 'xen hypervisor'

View File

@ -1,9 +0,0 @@
- name: 'hypervisor:libvirt:rain1'
label: 'rain'
description: 'rain hypervisor'
incompatible:
- name: 'hypervisor:qemu'
- name: 'hypervisor:xen'
- name: 'hypervisor:xen'
label: 'xen'
description: 'xen hypervisor'

View File

@ -1,5 +0,0 @@
- name: 'hypervisor:libvirt:sun'
label: 'sun'
description: 'sun hypervisor'
incompatible:
- name: 'hypervisor:qemu'

View File

@ -1,9 +0,0 @@
- name: 'hypervisor:xen'
label: 'xen'
description: 'hypervisor:xen'
requires:
- name: 'hypervisor:qemu'
incompatible:
- name: 'hypervisor:vmware'
description: 'xen not compatible with vmware'

View File

@ -1,14 +0,0 @@
- name: 'hypervisor:xen'
label: 'xen'
description: 'xen'
requires:
- name: 'additional_service:murano'
compatible:
- name: 'additional_service:ceilometer'
incompatible:
- name: 'hypervisor:test:*'
- name: 'hypervisor:test:sun'
label: 'sun'
- name: 'hypervisor:test:rain'
label: 'rain'

View File

@ -1,13 +0,0 @@
- name: 'network:neutron:contrail'
label: 'Contrail'
description: 'Contrail SDN networking'
bind: !!pairs
- 'cluster:net_provider': 'neutron'
- 'cluster:net_segment_type': 'tun'
compatible:
- name: 'hypervisor:*'
incompatible:
- name: 'hypervisor:vmware'
description: 'Contrail is not compatible with VMware for now'
- name: 'network:neutron:ml2:dvs'
description: 'Contrail is not compatible with VMware for now'

View File

@ -1,8 +0,0 @@
- name: 'network:neutron:ml2:dvs'
label: 'DVS network'
description: 'DVS network type'
requires:
- name: 'network:neutron:core:ml2'
- name: 'hypervisor:vmware'
incompatible:
- name: 'network:neutron:core:contrail'

View File

@ -1,25 +0,0 @@
- name: 'network:neutron:ml2:dvs'
label: 'DVS network'
description: 'DVS network type'
requires:
- name: 'network:neutron:core:ml2'
- name: 'hypervisor:vmware'
- name: 'network:neutron:ml2:frog'
label: 'frog'
description: 'frog'
incompatible:
- name: 'network:neutron:ml2:tun'
- name: 'storage:ephemeral:ceph'
requires:
- name: 'additional_service:sahara'
- name: 'network:neutron:core:ml2'
compatible:
- name: 'network:neutron:ml2:dvs'
- name: 'storage:block:ceph'
- name: 'hypervisor:libvirt:qemu'
- name: 'additional_service:murano'
- name: 'hypervisor:xen'
label: 'Xen'
description: 'Xen hypervisor'
incompatible:
- name: 'hypervisor:vmware'

View File

@ -1,14 +0,0 @@
- name: 'storage:block:nfs'
label: 'nfs'
description: 'nfs'
incompatible:
- name: 'storage:object:sheepdog'
message: 'not compatible with sheepdog'
- name: 'storage:object:cat'
message: 'not compatible with cat'
- name: 'storage:object:sheepdog'
label: 'sheepdog'
description: 'sheepdog'
- name: 'storage:object:cat'
label: 'cat'
description: 'cat'

View File

@ -1,8 +0,0 @@
- name: 'storage:block:zfs'
label: 'zfs'
description: 'zfs'
incompatible:
- name: 'storage:image:nfs'
- name: 'storage:image:nfs'
label: 'nfs'
description: 'nfs'

View File

@ -1,5 +0,0 @@
- name: 'storage:image:swift'
label: 'swift'
description: 'swift'
incompatible:
- name: 'storage:image:ceph'

View File

@ -1,10 +0,0 @@
- name: 'storage:image:swift'
label: 'swift'
description: 'swift'
incompatible:
- name: 'storage:image:ceph'
compatible:
- name: 'storage:image:cat'
- name: 'storage:image:cat'
label: 'cat'
description: 'cat'

View File

@ -1,5 +0,0 @@
- name: 'storage:object:cat'
label: 'Stor ceph'
description: 'stor ceph'
incompatible:
- name: 'storage:block:lvm'

View File

@ -1,207 +0,0 @@
/*
* Copyright 2016 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.
**/
import registerSuite from 'intern!object';
import Common from 'tests/functional/pages/common';
import Modal from 'tests/functional/pages/modal';
import 'tests/functional/helpers';
import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal;
return {
name: 'Additional components',
setup() {
common = new Common(this.remote);
modal = new Modal(this.remote);
return this.remote
.then(() => common.getIn());
},
afterEach() {
return this.remote
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal)
.catch(() => modal.close().then(() => modal.waitToClose()));
},
'Test additional, -network, !vmware, !dvs, +Sahara'() {
var smile = 'input[value=additional_service\\:smile]';
var ml2 = 'input[value=network\\:neutron\\:core\\:ml2]';
var vlan = 'input[value=network\\:neutron\\:ml2\\:vlan]';
return this.remote
.updatePlugin('dvs_default test_addit_smile')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.clickByCssSelector('input[value=hypervisor\\:vmware]')
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
//Check that smile is disabled when Nova network is enabled
.clickByCssSelector('input[value=network\\:nova_network]')
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.assertElementDisabled(smile, 'Smile checkbox is enabled with Nova network')
.clickByCssSelector('button.prev-pane-btn') // back to Storage
.clickByCssSelector('button.prev-pane-btn') // back to Networking
// Check that smile is disabled when dvs network is disabled
.clickByCssSelector(ml2)
.clickByCssSelector(vlan)
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.assertElementDisabled(smile, 'Smile checkbox is enabled without dvs network')
.clickByCssSelector('button.prev-pane-btn') // back to Storage
.clickByCssSelector('button.prev-pane-btn') // back to Networking
// Create cluster with vCenter + Neutron with ML2 plugin + dvs + Sahara + smile
.clickByCssSelector(ml2)
.clickByCssSelector(vlan)
.clickByCssSelector('input[value=network\\:neutron\\:ml2\\:dvs]')
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.clickByCssSelector('input[value=additional_service\\:sahara]')
.clickByCssSelector(smile)
.pressKeys('\uE007'); // Finish
},
'Test additional, -Ceilometer, !Murano, +Sahara'() {
var smile = 'input[value=additional_service\\:smile]';
var ceilometer = 'input[value=additional_service\\:ceilometer]';
return this.remote
.updatePlugin('dvs_default test_addit_smile_ceil')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
// Check that smile is disabled when Murano is not enabled (by default)
.assertElementDisabled(smile, 'Smile is enabled without Murano')
// Check that smile is not compatible with Ceilometer
.clickByCssSelector('input[value=additional_service\\:murano]') // enable required Murano
.clickByCssSelector(ceilometer)
.assertElementDisabled(smile, 'Smile is enabled with Ceilometer')
.clickByCssSelector(ceilometer) // disable Ceilometer
.clickByCssSelector(smile)
.assertElementDisabled(ceilometer, 'Ceilometer is enabled with smile')
.assertElementsExist('i.tooltip-icon.glyphicon-warning-sign' +
'[data-original-title="Not compatible with smile"]', 1,
'No warning that Ceilometer is not compatible with smile')
// Create cluster with smile + murano
.pressKeys('\uE007'); // Finish
},
'Test additional, -Ironic, !Sahara, +Murano'() {
var smile = 'input[value=additional_service\\:smile]';
var ironic = 'input[value=additional_service\\:ironic]';
return this.remote
.updatePlugin('dvs_default test_addit_smile_ironic')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
// Check that smile is disabled when Sahara is not enabled (by default)
.assertElementDisabled(smile, 'Smile is enabled without Sahara')
// Check that smile is not compatible with Ironic
.clickByCssSelector('input[value=additional_service\\:sahara]') // enable required Sahara
.clickByCssSelector(ironic)
.assertElementDisabled(smile, 'Smile is enabled with Ironic')
.clickByCssSelector(ironic) // disable Ironic
.clickByCssSelector(smile)
.assertElementDisabled(ironic, 'Ironic is enabled with smile')
.assertElementExists('i.tooltip-icon.glyphicon-warning-sign' +
'[data-original-title="Not compatible with smile"]',
1, 'No warning that Ironic is incompatible with smile')
// Create cluster with smile + Sahara
.pressKeys('\uE007'); // Finish
},
'Test additional, -ml2:tun, -vmware, !Sahara, +block:ceph'() {
var smile = 'input[value=additional_service\\:smile]';
var vmware = 'input[value=hypervisor\\:vmware]';
var vlan = 'input[value=network\\:neutron\\:ml2\\:vlan]';
var tun = 'input[value=network\\:neutron\\:ml2\\:tun]';
var sahara = 'input[value=additional_service\\:sahara]';
return this.remote
.updatePlugin('dvs_default test_addit_smile_sahara')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Check that smile is disabled when vCenter is enabled
.clickByCssSelector(vmware)
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.clickByCssSelector(sahara)
.assertElementDisabled(smile, 'Smile checkbox is enabled with vCenter')
.clickByCssSelector('button.prev-pane-btn') // back to Storage
.clickByCssSelector('button.prev-pane-btn') // back to Networking
.clickByCssSelector('button.prev-pane-btn') // back to Compute
.clickByCssSelector(vmware)
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
// Check that smile is disabled when Neutron with tunneling segmentation is enabled
.clickByCssSelector(vlan)
.clickByCssSelector(tun)
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.clickByCssSelector(sahara)
.assertElementDisabled(smile, 'Smile checkbox is enabled with tunneling segmentation')
.clickByCssSelector('button.prev-pane-btn') // back to Storage
.clickByCssSelector('button.prev-pane-btn') // back to Networking
// Create cluster with VLAN + Ceph Block Storage + Sahara + smile
.clickByCssSelector(tun)
.clickByCssSelector(vlan)
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.clickByCssSelector('input[value=storage\\:block\\:ceph]')
.pressKeys('\uE007') // Additional Services
.clickByCssSelector(sahara)
.clickByCssSelector(smile)
.pressKeys('\uE007'); // Finish
}
};
});

View File

@ -1,241 +0,0 @@
/*
* Copyright 2016 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.
**/
import registerSuite from 'intern!object';
import Common from 'tests/functional/pages/common';
import Modal from 'tests/functional/pages/modal';
import 'tests/functional/helpers';
import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal;
return {
name: 'Hypervisors',
setup() {
common = new Common(this.remote);
modal = new Modal(this.remote);
return this.remote
.then(() => common.getIn());
},
afterEach() {
return this.remote
.then(() => modal.close())
.catch(() => true)
.then(() => modal.waitToClose());
},
'Test description of components in wizard with qemu'() {
return this.remote
.updatePlugin('dvs_default test_hyperv_green_light_1')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.clickByCssSelector('input[value=hypervisor\\:vmware]') // Enable vcenter
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
// Select Neutron with NSXv plugin and check that it has green light
.clickByCssSelector('input[value=network\\:neutron\\:core\\:nsx]')
.assertElementsExist('i.tooltip-icon.glyphicon-ok-sign[data-original-title=' +
'"The component was tested with all the selected components"]',
2, 'Neutron with NSXv plugin has no green light');
},
'Test description of components in wizard without qemu'() {
return this.remote
.updatePlugin('dvs_default test_hyperv_green_light_2')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.clickByCssSelector('input[value=hypervisor\\:vmware]') // enable vCenter
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
// Select Neutron with NSXv plugin and check that it has green light
.clickByCssSelector('input[value=network\\:neutron\\:core\\:nsx]')
.assertElementsExist('i.tooltip-icon.glyphicon-info-sign[data-original-title=' +
'"This component was not tested with the following ' +
'components: QEMU-KVM"]', 1,
'Neutron with NSXv plugin has green light with QEMU-KVM');
},
'Test hypervisor:libvirt, -xen'() {
var rain = 'input[name=hypervisor\\:libvirt\\:rain]';
var xen = 'input[name=hypervisor\\:xen]';
return this.remote
.updatePlugin('dvs_default test_hyperv_rain')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Enable xen, check that rain is disabled
.clickByCssSelector(xen)
.assertElementDisabled(rain, 'Rain checkbox is enabled with xen')
// Disable xen, enable rain, check that xen is disabled
.clickByCssSelector(xen)
.clickByCssSelector(rain)
.assertElementDisabled(xen, 'Xen checkbox is enabled with rain')
// Create cluster with rain hypervisor
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
},
'Test hypervisor:libvirt, -qemu, -xen'() {
return this.remote
.updatePlugin('dvs_default test_hyperv_rain1')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Check that rain and xen hypervisors are displayed as checkboxes
.assertElementExists('input[name=hypervisor\\:xen][type="checkbox"]',
'Xen is not displayed as a checkbox')
.assertElementExists('input[name=hypervisor\\:libvirt\\:rain1][type="checkbox"]',
'Rain is not displayed as a checkbox');
},
'Test hypervisor:libvirt, -qemu'() {
var sun = 'input[value=hypervisor\\:libvirt\\:sun]';
var qemu = 'input[value=hypervisor\\:qemu]';
return this.remote
.updatePlugin('dvs_default test_hyperv_sun')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Check that sun hypervisor is disabled when qemu is enabled (by default)
.assertElementDisabled(sun, 'Sun checkbox is enabled with qemu')
// Disable qemu, enable sun and check that qemu is disabled
.clickByCssSelector(qemu)
.clickByCssSelector(sun)
.assertElementDisabled(qemu, 'Qemu checkbox is enabled with sun')
// Create cluster with sun hypervisor
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
},
'Test hypervisor, -vmware, !qemu'() {
var vmware = 'input[name=hypervisor\\:vmware]';
var xen = 'input[name=hypervisor\\:xen]';
return this.remote
.updatePlugin('dvs_default test_hyperv_xen')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Enable vCenter and check that xen is disabled
.clickByCssSelector(vmware)
.assertElementDisabled(xen, 'Xen checkbox is enabled with vCenter')
// Disable vCenter, enable xen and check that vCenter is disabled
.clickByCssSelector(vmware)
.clickByCssSelector(xen)
.assertElementDisabled(vmware, 'vCenter checkbox is enabled with xen')
// Create cluster with xen hypervisor
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
},
'Test hypervisor, -hyperv*, !Murano, +Ceilometer'() {
var sun = 'input[value=hypervisor\\:test\\:sun]';
var rain = 'input[value=hypervisor\\:test\\:rain]';
var xen = 'input[value=hypervisor\\:xen]';
return this.remote
.updatePlugin('dvs_default test_hyperv_xen_sun')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Check that xen is not compatible with sun and rain hypervisors
.clickByCssSelector(sun)
.assertElementDisabled(xen, 'Xen checkbox is enabled with sun')
.clickByCssSelector(rain)
.assertElementDisabled(xen, 'Xen checkbox is enabled with sun + rain')
.clickByCssSelector(sun)
.assertElementDisabled(xen, 'Xen checkbox is enabled with rain')
.clickByCssSelector(rain)
.clickByCssSelector(xen)
.assertElementDisabled(sun, 'Sun checkbox is enabled with xen')
.assertElementDisabled(rain, 'Rain checkbox is enabled with xen')
// Try to create cluster with xen without Murano
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
.assertElementTextEquals('div.text-error', 'Component \'hypervisor:xen\' requires ' +
'any of components from [u\'additional_service:murano\'] set.',
'Error was not displayed');
},
'Test create cluster with xen + Murano + Ceilometer'() {
return this.remote
.updatePlugin('dvs_default test_hyperv_xen_sun')
.newClusterFillName(modal)
// Create cluster with xen + Murano + Ceilometer
.pressKeys('\uE007') // go to Compute
.clickByCssSelector('input[value=hypervisor\\:xen]')
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.clickByCssSelector('input[value=additional_service\\:murano]')
.clickByCssSelector('input[value=additional_service\\:ceilometer]')
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
}
};
});

View File

@ -1,258 +0,0 @@
/*
* Copyright 2016 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.
**/
import registerSuite from 'intern!object';
import Common from 'tests/functional/pages/common';
import Modal from 'tests/functional/pages/modal';
import 'tests/functional/helpers';
import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal;
return {
name: 'Networking',
setup() {
common = new Common(this.remote);
modal = new Modal(this.remote);
return this.remote
.then(() => common.getIn());
},
afterEach() {
return this.remote
.then(() => modal.close())
.catch(() => true)
.then(() => modal.waitToClose());
},
'Test network, -vmware, -dvs, +hyperv*, bind:tun'() {
var vmware = 'input[name=hypervisor\\:vmware]';
var contrail = 'input[value=network\\:neutron\\:contrail]';
return this.remote
.updatePlugin('dvs_default test_network_contr_binded')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Check that Contrail is disabled when vCenter is enabled
.clickByCssSelector(vmware)
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
// Go back to Compute and disable vCenter
.clickByCssSelector('.prev-pane-btn')
.clickByCssSelector(vmware)
// Create cluster with qemu + Contrail network + ceph + Sahara
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.clickByCssSelector(contrail)
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.clickByCssSelector('input[value=storage\\:block\\:ceph]')
.pressKeys('\uE007') // Additional Services
.clickByCssSelector('input[value=additional_service\\:sahara]')
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Check that all network configuration of neutron tun is available in Network tab
.clickByCssSelector('a.network.cluster-tab')
.assertElementTextEquals('.title .segmentation-type',
'(Neutron with tunneling segmentation)',
'No tunneling segmentation message')
// Back to Dashboard and delete created environment
.clickByCssSelector('a.dashboard.cluster-tab')
.deleteCluster(modal);
},
'Create cluster with vCenter + dvs network'() {
return this.remote
.updatePlugin('dvs_default test_network_contr_binded')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Create cluster with vCenter + dvs network
.clickByCssSelector('input[name=hypervisor\\:vmware]')
.assertNextButtonEnabled()
.pressKeys('\uE007') // go to Networking
.clickByCssSelector('input[value=network\\:neutron\\:ml2\\:dvs]')
// Create env with vCenter + nsxv
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
},
'Test that it is not possibility to create cluster with nsx + dvs'() {
return this.remote
.updatePlugin('dvs_default nsxv_default')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.clickByCssSelector('input[name=hypervisor\\:vmware]') // enable vCenter
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
// Check that there is no possibility to select multiple networks neutron:nsx and
// neutron:ml2:dvs (choose nsxv, then ml2 + vlan + dvs)
.clickByCssSelector('input[value=network\\:neutron\\:core\\:nsx]')
.clickByCssSelector('input[value=network\\:neutron\\:core\\:ml2]')
.clickByCssSelector('input[name=network\\:neutron\\:ml2\\:vlan]')
.clickByCssSelector('input[name=network\\:neutron\\:ml2\\:dvs]')
// Create env with vCenter + ml2
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
},
'Create cluster with neutron:nsx'() {
return this.remote
.updatePlugin('dvs_default nsxv_default')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.clickByCssSelector('input[name=hypervisor\\:vmware]') // enable vCenter
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
// Check that there is no possibility to select multiple networks neutron:nsx and
// neutron:ml2:dvs (choose nsxv)
.clickByCssSelector('input[value=network\\:neutron\\:core\\:nsx]')
// Create env with vCenter + nsxv
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
},
'Test network, -contrail, !ml2, !vmware'() {
return this.remote
.updatePlugin('contrail_default test_network_ml2')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
// Check in wizard that network contrail is blocked when dvs network is selected
// (choose contrail)
.clickByCssSelector('input[value=network\\:neutron\\:contrail]')
// Create cluster with contrail
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
},
'Test network, -tun, -e:ceph, !Sahara, !ml2, +dvs, +b:ceph, +qemu, +Murano'() {
var vmware = 'input[value=hypervisor\\:vmware]';
var xen = 'input[value=hypervisor\\:xen]';
var vlan = 'input[value=network\\:neutron\\:ml2\\:vlan]';
var tun = 'input[value=network\\:neutron\\:ml2\\:tun]';
var frog = 'input[value=network\\:neutron\\:ml2\\:frog]';
return this.remote
.updatePlugin('dvs_default test_network_ml2_frog')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Check that xen is incompatible with vCenter
.clickByCssSelector(vmware)
.assertElementDisabled(xen, 'Xen is enabled with vCenter')
.clickByCssSelector(vmware)
.clickByCssSelector(xen)
.assertElementDisabled(vmware, 'vCenter is enabled with xen')
.clickByCssSelector(xen)
// Check that frog is disabled with ml2:tun
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.clickByCssSelector(vlan)
.clickByCssSelector(tun)
.assertElementDisabled(frog, 'frog is enabled with tun')
.clickByCssSelector(tun)
.clickByCssSelector(vlan)
// Create cluster with KVM + vCenter, frog + DVS network, Sahara + Murano
.clickByCssSelector('button.prev-pane-btn') // back to Compute
.clickByCssSelector(vmware)
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.clickByCssSelector('input[value=network\\:neutron\\:ml2\\:dvs]')
.clickByCssSelector(frog)
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.assertElementDisabled('input[value=storage\\:ephemeral\\:ceph]',
'Ephemerap Ceph is enabled with frog')
.pressKeys('\uE007') // Additional Services
.clickByCssSelector('input[value=additional_service\\:sahara]')
.clickByCssSelector('input[value=additional_service\\:murano]')
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
},
'Test create cluster without required Sahara'() {
return this.remote
.updatePlugin('dvs_default test_network_ml2_frog')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Try to create cluster with KVM + vCenter hypervisors, frog + DVS network
// without Sahara additional service (should not be created)
.clickByCssSelector('input[value=hypervisor\\:vmware]')
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.clickByCssSelector('input[value=network\\:neutron\\:ml2\\:frog]')
.clickByCssSelector('input[value=network\\:neutron\\:ml2\\:dvs]')
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
.assertElementTextEquals('.text-error', 'Component \'network:neutron:ml2:frog\' ' +
'requires any of components from [u\'additional_service:' +
'sahara\'] set.', 'Error was not displayed');
}
};
});

View File

@ -1,192 +0,0 @@
/*
* Copyright 2016 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.
**/
import registerSuite from 'intern!object';
import Common from 'tests/functional/pages/common';
import Modal from 'tests/functional/pages/modal';
import 'tests/functional/helpers';
import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal;
return {
name: 'Storage',
setup() {
common = new Common(this.remote);
modal = new Modal(this.remote);
return this.remote
.then(() => common.getIn());
},
afterEach() {
return this.remote
.then(() => modal.close())
.catch(() => true)
.then(() => modal.waitToClose());
},
'Test storage, -object'() {
var nfs = 'input[value=storage\\:block\\:nfs]';
var cat = 'input[value=storage\\:object\\:cat]';
var sheepdog = 'input[value=storage\\:object\\:sheepdog]';
return this.remote
.updatePlugin('dvs_default test_storage_block_nfs')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
// Check that cat and sheepdog are disabled when nfs is enabled
.clickByCssSelector(nfs)
.assertElementDisabled(cat, 'Cat checkbox is enabled with nfs')
.assertElementDisabled(sheepdog, 'Sheepdog checkbox is enabled with nfs')
// Check that nfs is disabled when cat and sheepdog are enabled
.clickByCssSelector(nfs)
.clickByCssSelector(cat)
.assertElementDisabled(nfs, 'Nfs checkbox is enabled with cat')
.clickByCssSelector(sheepdog)
.assertElementDisabled(nfs, 'Nfs checkbox is enabled with sheepdog')
.clickByCssSelector(cat)
.clickByCssSelector(sheepdog)
// Create cluster with nfs Block Storage
.clickByCssSelector(nfs)
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
},
'Test storage -storage:image'() {
var nfs = 'input[value=storage\\:image\\:nfs]';
var zfs = 'input[value=storage\\:block\\:zfs]';
return this.remote
.updatePlugin('dvs_default test_storage_block_zfs')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
// Check that zfs block storage is disabled when nfs image storage enabled
.clickByCssSelector(nfs)
.assertElementDisabled(zfs, 'Zfs checkbox is enabled with nfs')
// Check that nfs image storage is disabled when zfs block storage enabled
.clickByCssSelector(nfs) // disable nfs
.clickByCssSelector(zfs)
.assertElementDisabled(nfs, 'Nfs checkbox is enabled with zfs')
// Create cluster with zfs
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
},
'Test storage:image, -image:ceph'() {
var swift = 'input[value=storage\\:image\\:swift]';
var ceph = 'input[value=storage\\:image\\:ceph]';
return this.remote
.updatePlugin('dvs_default test_storage_image_swift')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
// Check that Ceph image storage is inactive when swift image storage is
// active and vice versa
.clickByCssSelector(swift)
.assertElementPropertyEquals(ceph, 'checked', false, 'Ceph is enabled with swift')
.clickByCssSelector(ceph)
.assertElementPropertyEquals(swift, 'checked', false, 'Swift is enabled with ceph');
},
'Test storage:image, -image:ceph, +storage:image'() {
var ceph = 'input[value=storage\\:image\\:ceph]';
var swift = 'input[value=storage\\:image\\:swift]';
return this.remote
.updatePlugin('dvs_default test_storage_image_swift_cat')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
// Check that Ceph image storage is inactive when swift image storage is
// active and vice versa
.clickByCssSelector('input[value=storage\\:image\\:cat]')
.clickByCssSelector(ceph)
.assertElementDisabled(swift, 'Swift is enabled with ceph')
.clickByCssSelector(ceph) // disable Ceph
.clickByCssSelector(swift)
.assertElementDisabled(ceph, 'Ceph is enabled with swift')
// Create cluster with qemu + Neutron vlan + Swift + cat
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
},
'Test storage:object, -block:lvm'() {
var cat = 'input[value=storage\\:object\\:cat]';
return this.remote
.updatePlugin('dvs_default test_storage_object_cat')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
// Check that cat is disabled when LVM is enabled (by default)
.assertElementDisabled(cat, 'cat is enabled with LVM')
// Create cluster with Ceph block storage + Stor ceph
.clickByCssSelector('input[value=storage\\:block\\:ceph]')
.clickByCssSelector(cat)
.pressKeys('\uE007') // Additional Services
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Delete created environment
.deleteCluster(modal);
}
};
});

View File

@ -1,101 +0,0 @@
/*
* Copyright 2016 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.
**/
import registerSuite from 'intern!object';
import Common from 'tests/functional/pages/common';
import Modal from 'tests/functional/pages/modal';
import 'tests/functional/helpers';
import 'tests/functional/real_plugin/plugin_helpers';
registerSuite(() => {
var common, modal;
return {
name: 'UI components',
setup() {
common = new Common(this.remote);
modal = new Modal(this.remote);
return this.remote
.then(() => common.getIn());
},
'Test that all components, chosen in Wizard tab, are enabled on Setting tab'() {
return this.remote
.updatePlugin('dvs_default contrail_default')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Create cluster with all compatible elements in wizard
.clickByCssSelector('input[value=hypervisor\\:vmware]') // vCenter
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.clickByCssSelector('input[value=network\\:neutron\\:ml2\\:dvs]') // VMware DVS
.assertNextButtonEnabled()
.pressKeys('\uE007') // Storage
.clickByCssSelector('input[value=storage\\:image\\:ceph]') // image Ceph
.clickByCssSelector('input[value=storage\\:object\\:ceph]') // object Ceph
.clickByCssSelector('input[value=storage\\:ephemeral\\:ceph]') // ephemeral Ceph
.pressKeys('\uE007') // Additional Services
.clickByCssSelector('input[value=additional_service\\:sahara]') // Sahara
.clickByCssSelector('input[value=additional_service\\:murano]') // Murano
.clickByCssSelector('input[value=additional_service\\:ceilometer]') // Ceilometer
.clickByCssSelector('input[value=additional_service\\:ironic]') // Ironic
.pressKeys('\uE007') // Finish
.pressKeys('\uE007') // Create
.then(() => modal.waitToClose())
// Check that all components, chosen in Wizard tab, are enabled on Setting tab
.clickByCssSelector('a.settings.cluster-tab')
.clickByCssSelector('a.subtab-link-storage')
.assertElementPropertyEquals('input[name=images_ceph]', 'checked', true,
'image Ceph is disabled') // image Ceph
.assertElementPropertyEquals('input[name=objects_ceph]', 'checked', true,
'object Ceph is disabled') // object Ceph
.assertElementPropertyEquals('input[name=ephemeral_ceph]', 'checked', true,
'ephemeral Ceph is disabled') // ephemeral Ceph
.clickByCssSelector('a.subtab-link-openstack_services')
.assertElementPropertyEquals('input[name=sahara]', 'checked', true,
'Sahara is disabled') // Sahara
.assertElementPropertyEquals('input[name=murano]', 'checked', true,
'Murano is disabled') // Murano
.assertElementPropertyEquals('input[name=ceilometer]', 'checked', true,
'Ceilometer is disabled') // Ceilometer
.assertElementPropertyEquals('input[name=ironic]', 'checked', true,
'Ironic is disabled') // Ironic
.assertElementExists('a.vmware.cluster-tab',
'VMware tab is not presented') // vCenter
// Delete created environment
.clickByCssSelector('a.dashboard.cluster-tab')
.deleteCluster(modal);
},
'Test that when vcenter is selected as compute, contrail should be turned off'() {
return this.remote
.updatePlugin('dvs_default contrail_default')
.newClusterFillName(modal)
.pressKeys('\uE007') // go to Compute
// Check that contrail is disabled when vCenter is enabled
.clickByCssSelector('input[value=hypervisor\\:vmware]')
.assertNextButtonEnabled()
.pressKeys('\uE007') // Networking
.assertElementDisabled('input[value=network\\:neutron\\:contrail]',
'Contrail checkbox is enabled with vCenter')
.then(() => modal.waitToClose());
}
};
});

View File

@ -38,7 +38,7 @@ _.defaults(Command.prototype, {
return this.parent
.clickByCssSelector('.create-cluster')
.then(() => modal.waitToOpen())
.setInputValue('[name=name]', 'Temp');
.setInputValue('[name=name]', 'Temp' + String(Math.random()).slice(2));
});
},
newClusterWithPlugin(modal) {
@ -46,7 +46,7 @@ _.defaults(Command.prototype, {
return this.parent
.clickByCssSelector('.create-cluster')
.then(() => modal.waitToOpen())
.setInputValue('[name=name]', 'Temp')
.setInputValue('[name=name]', 'Temp' + String(Math.random()).slice(2))
.pressKeys('\uE007') // go to Compute
.pressKeys('\uE007') // Networking
@ -83,15 +83,16 @@ _.defaults(Command.prototype, {
.clickIfExists('a.dashboard.cluster-tab')
.clickIfExists('.btn-danger')
.then(() => modal.waitToClose())
.then(() => modal.waitToClose()).catch(() => true)
.clickIfExists('button.delete-environment-btn')
.then(() => modal.waitToOpen())
.then(() => modal.waitToOpen()).catch(() => true)
.clickIfExists('button.remove-cluster-btn')
.then(() => modal.waitToClose())
.then(() => modal.waitToClose()).catch(() => true)
.waitForCssSelector('.create-cluster', 1000);
.waitForCssSelector('.create-cluster', 1000)
.sleep(1000 * 7);
});
},
clickObjectByIndex(objectsCssSelector, index) {