From 1befa52126fc94305643f5772d6123271e3b6ccb Mon Sep 17 00:00:00 2001 From: ekhomyakova Date: Thu, 2 Mar 2017 14:35:35 +0400 Subject: [PATCH] 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 (cherry picked from commit 5eadafc910df612c38e3e8705e4b86d158678e50) --- run_real_plugin_tests_on_real_nailgun.sh | 26 +- .../functional/nightly/library/history.js | 15 +- .../nightly/test_cluster_workflows.js | 228 +++++---- .../nightly/test_deployment_history.js | 443 +++++++++++------- .../functional/real_plugin/plugin_helpers.js | 13 +- 5 files changed, 448 insertions(+), 277 deletions(-) diff --git a/run_real_plugin_tests_on_real_nailgun.sh b/run_real_plugin_tests_on_real_nailgun.sh index e7938f853..3301dddc5 100755 --- a/run_real_plugin_tests_on_real_nailgun.sh +++ b/run_real_plugin_tests_on_real_nailgun.sh @@ -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 diff --git a/static/tests/functional/nightly/library/history.js b/static/tests/functional/nightly/library/history.js index 69cf45df5..04fa3e200 100755 --- a/static/tests/functional/nightly/library/history.js +++ b/static/tests/functional/nightly/library/history.js @@ -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')) diff --git a/static/tests/functional/nightly/test_cluster_workflows.js b/static/tests/functional/nightly/test_cluster_workflows.js index 2550eb828..337debb3b 100755 --- a/static/tests/functional/nightly/test_cluster_workflows.js +++ b/static/tests/functional/nightly/test_cluster_workflows.js @@ -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, diff --git a/static/tests/functional/nightly/test_deployment_history.js b/static/tests/functional/nightly/test_deployment_history.js index 7ba64630d..d15e6d55d 100755 --- a/static/tests/functional/nightly/test_deployment_history.js +++ b/static/tests/functional/nightly/test_deployment_history.js @@ -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'); } */ diff --git a/static/tests/functional/real_plugin/plugin_helpers.js b/static/tests/functional/real_plugin/plugin_helpers.js index 2952ae97f..5a160c77b 100644 --- a/static/tests/functional/real_plugin/plugin_helpers.js +++ b/static/tests/functional/real_plugin/plugin_helpers.js @@ -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) {