From 4c2d7de3467a39db6a11452e7436929b67e2c875 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Mon, 22 Aug 2016 15:15:28 +0200 Subject: [PATCH] SONAR-7846 Display error of a failing CE task in the background page --- .../BackgroundTasksTest.java | 36 ++++++++++--- .../java/pageobjects/BackgroundTaskItem.java | 16 ++++++ .../components/TaskActions.js | 36 +++++++++++-- .../background-tasks/views/StacktraceView.hbs | 23 +++++++++ .../background-tasks/views/StacktraceView.js | 50 +++++++++++++++++++ .../sonar-web/src/main/less/init/icons.less | 2 + .../resources/org/sonar/l10n/core.properties | 4 ++ 7 files changed, 156 insertions(+), 11 deletions(-) create mode 100644 server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.hbs create mode 100644 server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.js diff --git a/it/it-tests/src/test/java/it/projectAdministration/BackgroundTasksTest.java b/it/it-tests/src/test/java/it/projectAdministration/BackgroundTasksTest.java index 1a7f8795b05..a27df0b5015 100644 --- a/it/it-tests/src/test/java/it/projectAdministration/BackgroundTasksTest.java +++ b/it/it-tests/src/test/java/it/projectAdministration/BackgroundTasksTest.java @@ -25,6 +25,7 @@ import com.sonar.orchestrator.selenium.Selenese; import it.Category1Suite; import org.junit.BeforeClass; import org.junit.ClassRule; +import org.junit.Rule; import org.junit.Test; import pageobjects.BackgroundTaskItem; import pageobjects.BackgroundTasksPage; @@ -36,7 +37,10 @@ import static util.ItUtils.projectDir; public class BackgroundTasksTest { @ClassRule - public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; + public static Orchestrator ORCHESTRATOR = Category1Suite.ORCHESTRATOR; + + @Rule + public Navigation nav = Navigation.get(ORCHESTRATOR); @BeforeClass public static void beforeClass() { @@ -49,13 +53,12 @@ public class BackgroundTasksTest { Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("should_not_display_failing_and_search_and_filter_elements_on_project_level_page", "/projectAdministration/BackgroundTasksTest/should_not_display_failing_and_search_and_filter_elements_on_project_level_page.html" ).build(); - new SeleneseTest(selenese).runOn(orchestrator); + new SeleneseTest(selenese).runOn(ORCHESTRATOR); } @Test public void display_scanner_context() { - Navigation nav = Navigation.get(orchestrator); - nav.openHomepage().logIn().submitCredentials("admin", "admin"); + nav.logIn().submitCredentials("admin", "admin"); BackgroundTasksPage page = nav.openBackgroundTasksPage(); BackgroundTaskItem task = page.getTasksAsItems().get(0); @@ -65,11 +68,32 @@ public class BackgroundTasksTest { .assertScannerContextContains("Global properties:"); } + @Test + public void display_error_message_and_stacktrace() { + executeBuild("test-project", "Test Project", "2010-01-01"); + + nav.logIn().submitCredentials("admin", "admin"); + BackgroundTasksPage page = nav.openBackgroundTasksPage(); + + BackgroundTaskItem task = page.getTasksAsItems().get(0); + task.openActions() + .openErrorStacktrace() + .assertErrorMessageContains("Date of analysis cannot be older than the date of the last known analysis") + .assertErrorStacktraceContains("Date of analysis cannot be older than the date of the last known analysis"); + } + private static void executeBuild(String projectKey, String projectName) { - orchestrator.executeBuild( + ORCHESTRATOR.executeBuild( + SonarScanner.create(projectDir("shared/xoo-sample")) + .setProjectKey(projectKey) + .setProjectName(projectName)); + } + + private static void executeBuild(String projectKey, String projectName, String date) { + ORCHESTRATOR.executeBuild( SonarScanner.create(projectDir("shared/xoo-sample")) .setProjectKey(projectKey) .setProjectName(projectName) - ); + .setProperty("sonar.projectDate", date)); } } diff --git a/it/it-tests/src/test/java/pageobjects/BackgroundTaskItem.java b/it/it-tests/src/test/java/pageobjects/BackgroundTaskItem.java index e749c9c54e6..75ea6965468 100644 --- a/it/it-tests/src/test/java/pageobjects/BackgroundTaskItem.java +++ b/it/it-tests/src/test/java/pageobjects/BackgroundTaskItem.java @@ -53,4 +53,20 @@ public class BackgroundTaskItem { $(".js-task-scanner-context").should(hasText(text)); return this; } + + public BackgroundTaskItem openErrorStacktrace () { + elt.$(".js-task-show-stacktrace").click(); + $(".js-task-error-message").shouldBe(visible); + return this; + } + + public BackgroundTaskItem assertErrorMessageContains(String text) { + $(".js-task-error-message").should(hasText(text)); + return this; + } + + public BackgroundTaskItem assertErrorStacktraceContains(String text) { + $(".js-task-stacktrace").should(hasText(text)); + return this; + } } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js index 82be5d23870..d6de9d26c63 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js @@ -20,8 +20,9 @@ import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; import ScannerContextView from '../views/ScannerContextView'; +import StacktraceView from '../views/StacktraceView'; import { STATUSES } from './../constants'; -import { translate } from '../../../helpers/l10n'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export default class TaskActions extends React.Component { shouldComponentUpdate (nextProps, nextState) { @@ -43,9 +44,23 @@ export default class TaskActions extends React.Component { new ScannerContextView({ task: this.props.task }).render(); } + handleShowStacktraceClick (e) { + e.preventDefault(); + new StacktraceView({ task: this.props.task }).render(); + } + render () { const { component, task } = this.props; + const canFilter = component == null; + const canCancel = task.status === STATUSES.PENDING; + const canShowStacktrace = task.errorMessage != null; + const hasActions = canFilter || canCancel || task.hasScannerContext || canShowStacktrace; + + if (!hasActions) { + return  ; + } + return (
@@ -53,15 +68,15 @@ export default class TaskActions extends React.Component {
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.hbs b/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.hbs new file mode 100644 index 00000000000..1a4d2eb4753 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.hbs @@ -0,0 +1,23 @@ +
+ + + +
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.js b/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.js new file mode 100644 index 00000000000..809467dff01 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.js @@ -0,0 +1,50 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import Modal from '../../../components/common/modals'; +import Template from './StacktraceView.hbs'; +import { getTask } from '../../../api/ce'; + +export default Modal.extend({ + template: Template, + className: 'modal modal-large', + + initialize () { + this.loaded = false; + this.stacktrace = null; + this.loadStacktrace(); + }, + + loadStacktrace() { + getTask(this.options.task.id, ['stacktrace']).then(task => { + this.loaded = true; + this.stacktrace = task.errorStacktrace; + this.render(); + }); + }, + + serializeData() { + return { + task: this.options.task, + stacktrace: this.stacktrace, + loaded: this.loaded + }; + } +}); + diff --git a/server/sonar-web/src/main/less/init/icons.less b/server/sonar-web/src/main/less/init/icons.less index 86dc018eeda..4cf3404984f 100644 --- a/server/sonar-web/src/main/less/init/icons.less +++ b/server/sonar-web/src/main/less/init/icons.less @@ -62,6 +62,8 @@ a[class^="icon-"], a[class*=" icon-"] { .icon-black { color: @baseFontColor; } +.icon-gray { color: #999; } +.icon-gray path { fill: #999; } .icon-red { color: @red; } .icon-green { color: @green; } .icon-color-link { color: @darkBlue; } diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index d68b0ad98d7..e9c4b7d0379 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -2972,10 +2972,14 @@ background_tasks.table.finished=Finished background_tasks.table.duration=Duration background_tasks.logs=Logs +background_tasks.filter_by_component_x=Filter by Component "{0}" background_tasks.cancel_task=Cancel Task background_tasks.cancel_all_tasks=Cancel All Pending Tasks background_tasks.scanner_context=Scanner Context background_tasks.show_scanner_context=Show Scanner Context +background_tasks.show_stacktrace=Show Error Stacktrace +background_tasks.error_message=Error Message +background_tasks.error_stacktrace=Error Stacktrace background_tasks.pending=pending background_tasks.failures=still failing background_tasks.in_progress_duration=Duration of the current task in progress. -- 2.39.5