Fix/refactor UI tests after migration from 9.x

Affected:
* real-plugin/nics-feature
* nigtly/workflows
* nigtly/deployment-history

Closes-Bug: #1669337
Change-Id: Ie4d8a9bb8c6fc9a941477aa69b18fec3fa636265
This commit is contained in:
ekhomyakova 2017-03-02 14:35:35 +04:00
parent 0de244cf7c
commit 5eadafc910
5 changed files with 448 additions and 277 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

@ -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) {