@@ -1,5 +1,5 @@ | |||
sonar.projectKey=sample | |||
sonar.projectName=Sample | |||
sonar.projectVersion=1.0-SNAPSHOT | |||
sonar.projectVersion=0.9-SNAPSHOT | |||
sonar.sources=src/main/xoo | |||
sonar.language=xoo |
@@ -1,2 +1,4 @@ | |||
ncloc:12 | |||
classes:1 | |||
complexity:3 | |||
complexity_in_classes:3 |
@@ -1,2 +1,4 @@ | |||
ncloc:12 | |||
classes:1 | |||
complexity:3 | |||
complexity_in_classes:3 |
@@ -1,3 +1,4 @@ | |||
ncloc:12 | |||
classes:1 | |||
complexity:3 | |||
complexity_in_classes:3 |
@@ -1,3 +1,4 @@ | |||
ncloc:16 | |||
classes:1 | |||
complexity:5 | |||
complexity_in_classes:4 |
@@ -1,2 +1,4 @@ | |||
ncloc:12 | |||
classes:1 | |||
complexity:3 | |||
complexity_in_classes:3 |
@@ -41,6 +41,12 @@ package it;/* | |||
import com.sonar.orchestrator.Orchestrator; | |||
import it.authorisation.IssuePermissionTest; | |||
import it.i18n.I18nTest; | |||
import it.measureHistory.DifferentialPeriodsTest; | |||
import it.measureHistory.HistoryUiTest; | |||
import it.measureHistory.SincePreviousVersionHistoryTest; | |||
import it.measureHistory.SinceXDaysHistoryTest; | |||
import it.measureHistory.TimeMachineTest; | |||
import it.measureHistory.TimeMachineUiTest; | |||
import it.projectAdministration.BulkDeletionTest; | |||
import it.projectAdministration.ProjectAdministrationTest; | |||
import it.qualityGate.QualityGateNotificationTest; | |||
@@ -72,7 +78,14 @@ import static util.ItUtils.xooPlugin; | |||
QualityGateTest.class, | |||
QualityGateNotificationTest.class, | |||
// permission | |||
IssuePermissionTest.class | |||
IssuePermissionTest.class, | |||
// measure history | |||
DifferentialPeriodsTest.class, | |||
HistoryUiTest.class, | |||
SincePreviousVersionHistoryTest.class, | |||
SinceXDaysHistoryTest.class, | |||
TimeMachineTest.class, | |||
TimeMachineUiTest.class | |||
}) | |||
public class Category1Suite { | |||
@@ -52,8 +52,6 @@ import it.issue.ManualRulesTest; | |||
import it.measureFilter.MeasureFiltersTest; | |||
import it.measure.NewDebtRatioMeasureTest; | |||
import it.measure.TechnicalDebtMeasureVariationTest; | |||
import it.measureHistory.DifferentialPeriodsTest; | |||
import it.measureHistory.TimeMachineTest; | |||
import it.test.CoverageTest; | |||
import it.test.CoverageTrackingTest; | |||
import it.test.NewCoverageTest; | |||
@@ -69,9 +67,6 @@ import static util.ItUtils.xooPlugin; | |||
@Suite.SuiteClasses({ | |||
// custom measure | |||
CustomMeasuresTest.class, | |||
// measure history | |||
DifferentialPeriodsTest.class, | |||
TimeMachineTest.class, | |||
// measure | |||
TechnicalDebtMeasureVariationTest.class, | |||
NewDebtRatioMeasureTest.class, |
@@ -5,7 +5,9 @@ import com.sonar.orchestrator.locator.FileLocation; | |||
import it.Category2Suite; | |||
import java.util.List; | |||
import javax.annotation.Nullable; | |||
import org.junit.AfterClass; | |||
import org.junit.Before; | |||
import org.junit.BeforeClass; | |||
import org.junit.ClassRule; | |||
import org.junit.Test; | |||
import org.sonar.wsclient.services.Measure; | |||
@@ -15,6 +17,7 @@ import util.ItUtils; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.assertj.core.api.Assertions.within; | |||
import static util.ItUtils.setServerProperty; | |||
/** | |||
* SONAR-5876 | |||
@@ -26,6 +29,18 @@ public class NewDebtRatioMeasureTest { | |||
@ClassRule | |||
public static Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; | |||
@BeforeClass | |||
public static void initPeriods() throws Exception { | |||
setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period2", "30"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_version"); | |||
} | |||
@AfterClass | |||
public static void resetPeriods() throws Exception { | |||
ItUtils.resetPeriods(orchestrator); | |||
} | |||
@Before | |||
public void cleanUpAnalysisData() { | |||
orchestrator.resetData(); |
@@ -4,7 +4,9 @@ import com.sonar.orchestrator.Orchestrator; | |||
import com.sonar.orchestrator.locator.FileLocation; | |||
import it.Category2Suite; | |||
import java.util.List; | |||
import org.junit.AfterClass; | |||
import org.junit.Before; | |||
import org.junit.BeforeClass; | |||
import org.junit.ClassRule; | |||
import org.junit.Test; | |||
import org.sonar.wsclient.services.Measure; | |||
@@ -13,6 +15,7 @@ import org.sonar.wsclient.services.ResourceQuery; | |||
import util.ItUtils; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static util.ItUtils.setServerProperty; | |||
/** | |||
* SONAR-4776 | |||
@@ -22,6 +25,18 @@ public class TechnicalDebtMeasureVariationTest { | |||
@ClassRule | |||
public static Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; | |||
@BeforeClass | |||
public static void initPeriods() throws Exception { | |||
setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period2", "30"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_analysis"); | |||
} | |||
@AfterClass | |||
public static void resetPeriods() throws Exception { | |||
ItUtils.resetPeriods(orchestrator); | |||
} | |||
@Before | |||
public void cleanUpAnalysisData() { | |||
orchestrator.resetData(); |
@@ -3,7 +3,8 @@ package it.measureHistory; | |||
import com.sonar.orchestrator.Orchestrator; | |||
import com.sonar.orchestrator.build.SonarRunner; | |||
import com.sonar.orchestrator.locator.FileLocation; | |||
import it.Category2Suite; | |||
import com.sonar.orchestrator.selenium.Selenese; | |||
import it.Category1Suite; | |||
import java.util.List; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
@@ -15,22 +16,29 @@ import org.sonar.wsclient.services.ResourceQuery; | |||
import util.ItUtils; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static util.ItUtils.projectDir; | |||
import static util.ItUtils.setServerProperty; | |||
public class DifferentialPeriodsTest { | |||
@ClassRule | |||
public static final Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; | |||
public static final Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; | |||
@Before | |||
public void cleanUpAnalysisData() { | |||
orchestrator.resetData(); | |||
} | |||
@Before | |||
public void initPeriods() throws Exception { | |||
setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period2", "previous_analysis"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_analysis"); | |||
} | |||
@After | |||
public void tearDown() throws Exception { | |||
String propertyKey = "sonar.timemachine.period4"; | |||
unsetProperty(propertyKey); | |||
unsetProperty("sonar.timemachine.period5"); | |||
public void resetPeriods() throws Exception { | |||
ItUtils.resetPeriods(orchestrator); | |||
} | |||
/** | |||
@@ -38,19 +46,19 @@ public class DifferentialPeriodsTest { | |||
*/ | |||
@Test | |||
public void ensure_differential_period_4_and_5_defined_at_project_level_is_taken_into_account() throws Exception { | |||
setProperty("sonar.timemachine.period4", "30"); | |||
setProperty("sonar.timemachine.period5", "previous_analysis"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period4", "30"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period5", "previous_analysis"); | |||
// Execute an analysis in the past to have a past snapshot without any issues | |||
orchestrator.getServer().provisionProject("sample", "sample"); | |||
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "empty"); | |||
orchestrator.executeBuild(SonarRunner.create(ItUtils.projectDir("shared/xoo-sample")) | |||
orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample")) | |||
.setProperty("sonar.projectDate", "2013-01-01")); | |||
// Second analysis -> issues will be created | |||
orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/measureHistory/one-issue-per-line-profile.xml")); | |||
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); | |||
orchestrator.executeBuild(SonarRunner.create(ItUtils.projectDir("shared/xoo-sample"))); | |||
orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample"))); | |||
// New technical debt only comes from new issues | |||
Resource newTechnicalDebt = orchestrator.getServer().getWsClient() | |||
@@ -61,7 +69,7 @@ public class DifferentialPeriodsTest { | |||
// Third analysis, with exactly the same profile -> no new issues so no new technical debt | |||
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); | |||
orchestrator.executeBuild(SonarRunner.create(ItUtils.projectDir("shared/xoo-sample"))); | |||
orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample"))); | |||
newTechnicalDebt = orchestrator.getServer().getWsClient().find( | |||
ResourceQuery.createForMetrics("sample:src/main/xoo/sample/Sample.xoo", "new_technical_debt").setIncludeTrends(true) | |||
@@ -71,16 +79,25 @@ public class DifferentialPeriodsTest { | |||
assertThat(newTechnicalDebt).isNull(); | |||
} | |||
private static void unsetProperty(String propertyKey) { | |||
setProperty(propertyKey, ""); | |||
} | |||
/** | |||
* SONAR-4700 | |||
*/ | |||
@Test | |||
public void not_display_periods_selection_dropdown_on_first_analysis() { | |||
orchestrator.getServer().provisionProject("sample", "sample"); | |||
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "empty"); | |||
orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample"))); | |||
private static void setProperty(String propertyKey, String propertyValue) { | |||
orchestrator.getServer().adminWsClient().post( | |||
"/api/properties?", | |||
"id", propertyKey, | |||
"value", propertyValue | |||
); | |||
// Use old way to execute Selenium because 'assertSelectOptions' action is not supported by SeleneseTest | |||
orchestrator.executeSelenese(Selenese.builder().setHtmlTestsInClasspath("not-display-periods-selection-dropdown-on-first-analysis", | |||
"/measureHistory/DifferentialPeriodsTest/not-display-periods-selection-dropdown-on-dashboard.html" | |||
).build()); | |||
orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample"))); | |||
orchestrator.executeSelenese(Selenese.builder().setHtmlTestsInClasspath("display-periods-selection-dropdown-after-first-analysis", | |||
"/measureHistory/DifferentialPeriodsTest/display-periods-selection-dropdown-on-dashboard.html" | |||
).build()); | |||
} | |||
} |
@@ -0,0 +1,84 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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. | |||
*/ | |||
package it.measureHistory; | |||
import com.sonar.orchestrator.Orchestrator; | |||
import com.sonar.orchestrator.build.SonarRunner; | |||
import com.sonar.orchestrator.locator.FileLocation; | |||
import com.sonar.orchestrator.selenium.Selenese; | |||
import it.Category1Suite; | |||
import org.junit.BeforeClass; | |||
import org.junit.ClassRule; | |||
import org.junit.Test; | |||
import util.selenium.SeleneseTest; | |||
import static util.ItUtils.projectDir; | |||
public class HistoryUiTest { | |||
@ClassRule | |||
public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; | |||
@BeforeClass | |||
public static void initialize() { | |||
orchestrator.resetData(); | |||
orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/measureHistory/one-issue-per-line-profile.xml")); | |||
orchestrator.getServer().provisionProject("sample", "sample"); | |||
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); | |||
analyzeProject("shared/xoo-history-v1", "2014-10-19"); | |||
analyzeProject("shared/xoo-history-v2", "2014-11-13"); | |||
} | |||
private static void analyzeProject(String path, String date) { | |||
orchestrator.executeBuild(SonarRunner.create(projectDir(path)) | |||
.setProperties("sonar.projectDate", date)); | |||
} | |||
@Test | |||
public void test_timeline_widget() { | |||
new SeleneseTest(Selenese.builder().setHtmlTestsInClasspath("history-timeline-widget", | |||
"/measureHistory/HistoryUiTest/history-timeline-widget/timeline-widget.html", | |||
// SONAR-3561 | |||
"/measureHistory/HistoryUiTest/history-timeline-widget/should-display-even-if-one-missing-metric.html" | |||
).build()).runOn(orchestrator); | |||
} | |||
@Test | |||
public void test_timemachine_widget() { | |||
// Use old way to execute Selenium because 'waitForTextPresent' action is not supported by SeleneseTest | |||
orchestrator.executeSelenese(Selenese.builder().setHtmlTestsInClasspath("history-timemachine-widget", | |||
"/measureHistory/HistoryUiTest/history-timemachine-widget/time-machine-widget.html", | |||
// SONAR-3354 & SONAR-3353 | |||
"/measureHistory/HistoryUiTest/history-timemachine-widget/should-display-empty-table-if-no-measure.html", | |||
// SONAR-3650 | |||
"/measureHistory/HistoryUiTest/history-timemachine-widget/should-exclude-new-metrics.html" | |||
).build()); | |||
} | |||
/** | |||
* SONAR-2911 | |||
*/ | |||
@Test | |||
public void test_comparison_page_between_project_versions() { | |||
new SeleneseTest(Selenese.builder().setHtmlTestsInClasspath("comparison-page", | |||
"/measureHistory/HistoryUiTest/comparison/should-compare-project-versions.html" | |||
).build()).runOn(orchestrator); | |||
} | |||
} |
@@ -0,0 +1,95 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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. | |||
*/ | |||
package it.measureHistory; | |||
import com.sonar.orchestrator.Orchestrator; | |||
import com.sonar.orchestrator.build.SonarRunner; | |||
import it.Category1Suite; | |||
import org.junit.AfterClass; | |||
import org.junit.BeforeClass; | |||
import org.junit.ClassRule; | |||
import org.junit.Test; | |||
import org.sonar.wsclient.services.Measure; | |||
import org.sonar.wsclient.services.Resource; | |||
import org.sonar.wsclient.services.ResourceQuery; | |||
import util.ItUtils; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static util.ItUtils.projectDir; | |||
import static util.ItUtils.setServerProperty; | |||
public class SincePreviousVersionHistoryTest { | |||
@ClassRule | |||
public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; | |||
private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample"; | |||
@BeforeClass | |||
public static void initPeriods() throws Exception { | |||
setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period2", "30"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_version"); | |||
} | |||
@AfterClass | |||
public static void resetPeriods() throws Exception { | |||
ItUtils.resetPeriods(orchestrator); | |||
} | |||
/** | |||
* SONAR-2496 | |||
*/ | |||
@Test | |||
public void test_since_previous_version_period() { | |||
orchestrator.resetData(); | |||
analyzeProject("0.9", "**/*2.xoo"); | |||
analyzeProject("1.0-SNAPSHOT", null); | |||
analyzeProject("1.0-SNAPSHOT", null); | |||
Resource project = getProject("files"); | |||
Measure measure = project.getMeasure("files"); | |||
// There are 4 files | |||
assertThat(measure.getValue()).isEqualTo(4); | |||
// nothing changed in the previous analysis | |||
assertThat(project.getPeriod1Mode()).isEqualTo("previous_analysis"); | |||
assertThat(measure.getVariation1()).isEqualTo(0); | |||
// but 2 files were added since the first analysis which was version 0.9 | |||
assertThat(project.getPeriod3Mode()).isEqualTo("previous_version"); | |||
assertThat(project.getPeriod3Param()).isEqualTo("0.9"); | |||
assertThat(measure.getVariation3()).isEqualTo(2); | |||
} | |||
private static void analyzeProject(String version, String exclusions) { | |||
SonarRunner build = SonarRunner.create(projectDir("shared/xoo-multi-modules-sample")) | |||
.setProperties("sonar.projectVersion", version); | |||
if (exclusions != null) { | |||
build.setProperties("sonar.exclusions", exclusions); | |||
} | |||
orchestrator.executeBuild(build); | |||
} | |||
private Resource getProject(String... metricKeys) { | |||
return orchestrator.getServer().getWsClient().find(ResourceQuery.createForMetrics(PROJECT, metricKeys).setIncludeTrends(true)); | |||
} | |||
} |
@@ -0,0 +1,138 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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. | |||
*/ | |||
package it.measureHistory; | |||
import com.sonar.orchestrator.Orchestrator; | |||
import com.sonar.orchestrator.build.SonarRunner; | |||
import com.sonar.orchestrator.locator.FileLocation; | |||
import it.Category1Suite; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import org.apache.commons.lang.time.DateUtils; | |||
import org.junit.AfterClass; | |||
import org.junit.BeforeClass; | |||
import org.junit.ClassRule; | |||
import org.junit.Test; | |||
import org.sonar.wsclient.services.Measure; | |||
import org.sonar.wsclient.services.Resource; | |||
import org.sonar.wsclient.services.ResourceQuery; | |||
import util.ItUtils; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static util.ItUtils.projectDir; | |||
import static util.ItUtils.setServerProperty; | |||
public class SinceXDaysHistoryTest { | |||
@ClassRule | |||
public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; | |||
private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample"; | |||
@BeforeClass | |||
public static void analyseProjectWithHistory() { | |||
initPeriods(); | |||
orchestrator.resetData(); | |||
orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/measureHistory/one-issue-per-line-profile.xml")); | |||
orchestrator.getServer().provisionProject(PROJECT, PROJECT); | |||
orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "one-issue-per-line"); | |||
// Execute a analysis in the past before since 30 days period -> 0 issue, 0 file | |||
analyzeProject("2013-01-01", "multi-modules-sample:module_b,multi-modules-sample:module_a"); | |||
// Execute a analysis 20 days ago, after since 30 days period -> 16 issues, 1 file | |||
analyzeProject(getPastDate(20), "multi-modules-sample:module_b,multi-modules-sample:module_a:module_a2"); | |||
// Execute a analysis 10 days ago, after since 30 days period -> 28 issues, 2 files | |||
analyzeProject(getPastDate(10), "multi-modules-sample:module_b"); | |||
// Execute a analysis in the present with all modules -> 52 issues, 4 files | |||
analyzeProject(); | |||
} | |||
public static void initPeriods() { | |||
setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period2", "30"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_version"); | |||
} | |||
@AfterClass | |||
public static void resetPeriods() throws Exception { | |||
ItUtils.resetPeriods(orchestrator); | |||
} | |||
@Test | |||
public void periods_are_well_defined() throws Exception { | |||
Resource project = getProject("files"); | |||
assertThat(project.getPeriod1Mode()).isEqualTo("previous_analysis"); | |||
assertThat(project.getPeriod2Mode()).isEqualTo("days"); | |||
assertThat(project.getPeriod2Param()).isEqualTo("30"); | |||
} | |||
@Test | |||
public void check_files_variation() throws Exception { | |||
checkMeasure("files", 2, 3); | |||
} | |||
@Test | |||
public void check_issues_variation() throws Exception { | |||
checkMeasure("violations", 24, 45); | |||
} | |||
@Test | |||
public void check_new_issues_measures() throws Exception { | |||
checkMeasure("new_violations", 24, 45); | |||
} | |||
private void checkMeasure(String measure, int variation1, int variation2){ | |||
Resource project = getProject(measure); | |||
Measure newTechnicalDebt = project.getMeasure(measure); | |||
assertThat(newTechnicalDebt.getVariation1().intValue()).isEqualTo(variation1); | |||
assertThat(newTechnicalDebt.getVariation2().intValue()).isEqualTo(variation2); | |||
} | |||
private Resource getProject(String... metricKeys) { | |||
return orchestrator.getServer().getWsClient().find(ResourceQuery.createForMetrics(PROJECT, metricKeys).setIncludeTrends(true)); | |||
} | |||
private static void analyzeProject() { | |||
analyzeProject(null, null); | |||
} | |||
private static void analyzeProject(String date, String skippedModules) { | |||
SonarRunner runner = SonarRunner.create(projectDir("shared/xoo-multi-modules-sample")); | |||
if (date != null) { | |||
runner.setProperty("sonar.projectDate", date); | |||
} | |||
if (skippedModules != null) { | |||
runner.setProperties("sonar.skippedModules", skippedModules); | |||
} | |||
orchestrator.executeBuild(runner); | |||
} | |||
private static String getPastDate(int nbPastDays){ | |||
return new SimpleDateFormat("yyyy-MM-dd").format(DateUtils.addDays(new Date(), nbPastDays * -1)); | |||
} | |||
} |
@@ -23,8 +23,9 @@ import com.sonar.orchestrator.Orchestrator; | |||
import com.sonar.orchestrator.build.BuildResult; | |||
import com.sonar.orchestrator.build.SonarRunner; | |||
import com.sonar.orchestrator.locator.FileLocation; | |||
import it.Category2Suite; | |||
import it.Category1Suite; | |||
import java.util.Date; | |||
import org.junit.AfterClass; | |||
import org.junit.BeforeClass; | |||
import org.junit.ClassRule; | |||
import org.junit.Test; | |||
@@ -33,20 +34,23 @@ import org.sonar.wsclient.services.ResourceQuery; | |||
import org.sonar.wsclient.services.TimeMachine; | |||
import org.sonar.wsclient.services.TimeMachineCell; | |||
import org.sonar.wsclient.services.TimeMachineQuery; | |||
import util.ItUtils; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static util.ItUtils.projectDir; | |||
import static util.ItUtils.setServerProperty; | |||
public class TimeMachineTest { | |||
private static final String PROJECT = "sample"; | |||
@ClassRule | |||
public static Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; | |||
public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; | |||
@BeforeClass | |||
public static void initialize() { | |||
orchestrator.resetData(); | |||
initPeriods(); | |||
orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/measureHistory/one-issue-per-line-profile.xml")); | |||
orchestrator.getServer().provisionProject("sample", "Sample"); | |||
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); | |||
@@ -54,6 +58,17 @@ public class TimeMachineTest { | |||
analyzeProject("measure/xoo-history-v2", "2014-11-13"); | |||
} | |||
public static void initPeriods() { | |||
setServerProperty(orchestrator, "sonar.timemachine.period1", "previous_analysis"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period2", "30"); | |||
setServerProperty(orchestrator, "sonar.timemachine.period3", "previous_version"); | |||
} | |||
@AfterClass | |||
public static void resetPeriods() throws Exception { | |||
ItUtils.resetPeriods(orchestrator); | |||
} | |||
private static BuildResult analyzeProject(String path, String date) { | |||
return orchestrator.executeBuild(SonarRunner.create(projectDir(path), "sonar.projectDate", date)); | |||
} |
@@ -0,0 +1,65 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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. | |||
*/ | |||
package it.measureHistory; | |||
import com.sonar.orchestrator.Orchestrator; | |||
import com.sonar.orchestrator.build.SonarRunner; | |||
import com.sonar.orchestrator.selenium.Selenese; | |||
import it.Category1Suite; | |||
import org.junit.Before; | |||
import org.junit.ClassRule; | |||
import org.junit.Test; | |||
import util.selenium.SeleneseTest; | |||
import static util.ItUtils.projectDir; | |||
public class TimeMachineUiTest { | |||
@ClassRule | |||
public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR; | |||
@Before | |||
public void setUp() throws Exception { | |||
orchestrator.resetData(); | |||
orchestrator.getServer().provisionProject("sample", "sample"); | |||
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "empty"); | |||
} | |||
private static void analyzeProject(String date, String version) { | |||
orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-sample")) | |||
.setProperties("sonar.projectDate", date) | |||
.setProperties("sonar.projectVersion", version) | |||
); | |||
} | |||
// SONAR-3006 | |||
@Test | |||
public void test_time_machine_dashboard() { | |||
analyzeProject("2012-09-01", "0.7"); | |||
analyzeProject("2012-10-15", "0.8"); | |||
analyzeProject("2012-11-30", "0.9"); | |||
analyzeProject("2012-12-31", "1.0-SNAPSHOT"); | |||
new SeleneseTest(Selenese.builder().setHtmlTestsInClasspath("timemachine", | |||
"/measureHistory/TimeMachineUiTest/should-display-timemachine-dashboard.html" | |||
).build()).runOn(orchestrator); | |||
} | |||
} |
@@ -164,6 +164,14 @@ public class ItUtils { | |||
} | |||
} | |||
public static void resetPeriods(Orchestrator orchestrator){ | |||
setServerProperty(orchestrator, "sonar.timemachine.period1", null); | |||
setServerProperty(orchestrator, "sonar.timemachine.period2", null); | |||
setServerProperty(orchestrator, "sonar.timemachine.period3", null); | |||
setServerProperty(orchestrator, "sonar.timemachine.period4", null); | |||
setServerProperty(orchestrator, "sonar.timemachine.period5", null); | |||
} | |||
/** | |||
* Concatenates a vararg to a String array. | |||
* | |||
@@ -196,4 +204,4 @@ public class ItUtils { | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,54 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- | |||
~ SonarQube, open source software quality management tool. | |||
~ Copyright (C) 2008-2014 SonarSource | |||
~ mailto:contact AT sonarsource DOT com | |||
~ | |||
~ SonarQube 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. | |||
~ | |||
~ SonarQube 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. | |||
--> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head profile="http://selenium-ide.openqa.org/profiles/test-case"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | |||
<title>display-added-files</title> | |||
</head> | |||
<body> | |||
<table cellpadding="1" cellspacing="1" border="1"> | |||
<thead> | |||
<tr> | |||
<td rowspan="1" colspan="3">should_display_added_files_in_differential_drilldown</td> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr> | |||
<td>open</td> | |||
<td>/sonar/dashboard/index?id=sample&name=Dashboard</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>dashboard</td> | |||
<td>*Time changes*</td> | |||
</tr> | |||
<tr> | |||
<td>assertSelectOptions</td> | |||
<td>select-comparison</td> | |||
<td>*since previous analysis*</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</body> | |||
</html> |
@@ -0,0 +1,29 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head profile="http://selenium-ide.openqa.org/profiles/test-case"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | |||
<title>display-added-files</title> | |||
</head> | |||
<body> | |||
<table cellpadding="1" cellspacing="1" border="1"> | |||
<thead> | |||
<tr> | |||
<td rowspan="1" colspan="3">should_display_added_files_in_differential_drilldown</td> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr> | |||
<td>open</td> | |||
<td>/sonar/dashboard/index?id=sample&name=Dashboard</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertNotText</td> | |||
<td>dashboard</td> | |||
<td>*Time changes*</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</body> | |||
</html> |
@@ -0,0 +1,34 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head profile="http://selenium-ide.openqa.org/profiles/test-case"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | |||
<title>should-compare-project-versions</title> | |||
</head> | |||
<body> | |||
<table cellpadding="1" cellspacing="1" border="1"> | |||
<tbody> | |||
<tr> | |||
<td>open</td> | |||
<td>/sonar/comparison/index?resource=sample&locale=en-gb</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>comparison-page</td> | |||
<td>*Sample*0.9-SNAPSHOT*19 Oct 2014*Sample*1.0-SNAPSHOT*13 Nov 2014*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>comparison-page</td> | |||
<td>*Lines of code*24*40*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>comparison-page</td> | |||
<td>*Lines of code*Complexity*Comments (%)*Duplicated lines (%)*Issues*Coverage*</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</body> | |||
</html> |
@@ -0,0 +1,35 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head profile="http://selenium-ide.openqa.org/profiles/test-case"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | |||
<title>timeline</title> | |||
</head> | |||
<body> | |||
<table cellpadding="1" cellspacing="1" border="1"> | |||
<thead> | |||
<tr><td rowspan="1" colspan="3">timeline</td></tr> | |||
</thead><tbody> | |||
<tr> | |||
<td>open</td> | |||
<td>/sonar/widget?id=timeline&resource=sample&metric1=complexity&metric2=commits</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertElementPresent</td> | |||
<td>timeline-chart-1</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>block_1</td> | |||
<td>*Complexity*</td> | |||
</tr> | |||
<tr> | |||
<td>assertTextNotPresent</td> | |||
<td>block_1</td> | |||
<td>*Commits*</td> | |||
</tr> | |||
</tbody></table> | |||
</body> | |||
</html> |
@@ -0,0 +1,40 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head profile="http://selenium-ide.openqa.org/profiles/test-case"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | |||
<title>timeline</title> | |||
</head> | |||
<body> | |||
<table cellpadding="1" cellspacing="1" border="1"> | |||
<thead> | |||
<tr><td rowspan="1" colspan="3">timeline</td></tr> | |||
</thead><tbody> | |||
<tr> | |||
<td>open</td> | |||
<td>/sonar/widget?id=timeline&resource=sample&metric1=complexity&metric2=ncloc&chartTitle=MyWidget</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertElementPresent</td> | |||
<td>timeline-chart-1</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertElementPresent</td> | |||
<td>//h3[text()='MyWidget']</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>block_1</td> | |||
<td>*Complexity*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>block_1</td> | |||
<td>*Lines of code*</td> | |||
</tr> | |||
</tbody></table> | |||
</body> | |||
</html> |
@@ -0,0 +1,32 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head profile="http://selenium-ide.openqa.org/profiles/test-case"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | |||
<title>should-display-empty-table-if-no-measure</title> | |||
</head> | |||
<body> | |||
<table cellpadding="1" cellspacing="1" border="1"> | |||
<thead> | |||
<tr><td rowspan="1" colspan="3">time_machine</td></tr> | |||
</thead><tbody> | |||
<tr> | |||
<td>open</td> | |||
<td> | |||
/sonar/widget?id=time_machine&resource=sample&metric1=coverage&metric2=line_coverage&metric3=tests&displaySparkLine=true | |||
</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>block_1</td> | |||
<td>*Coverage*Line coverage*Unit tests*</td> | |||
</tr> | |||
<tr> | |||
<td>assertElementNotPresent</td> | |||
<td>//img</td> | |||
<td></td> | |||
</tr> | |||
</tbody></table> | |||
</body> | |||
</html> |
@@ -0,0 +1,74 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head profile="http://selenium-ide.openqa.org/profiles/test-case"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | |||
<title>should-exclude-new-metrics</title> | |||
</head> | |||
<body> | |||
<table cellpadding="1" cellspacing="1" border="1"> | |||
<thead> | |||
<tr> | |||
<td rowspan="1" colspan="3">should-exclude-new-metrics</td> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr> | |||
<td>open</td> | |||
<td>/sonar/sessions/new</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>type</td> | |||
<td>login</td> | |||
<td>admin</td> | |||
</tr> | |||
<tr> | |||
<td>type</td> | |||
<td>password</td> | |||
<td>admin</td> | |||
</tr> | |||
<tr> | |||
<td>clickAndWait</td> | |||
<td>commit</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>clickAndWait</td> | |||
<td>link=Configure widgets</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>waitForTextPresent</td> | |||
<td>History Table</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>clickAndWait</td> | |||
<td>id=add-widget-time_machine</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>waitForTextPresent</td> | |||
<td>History Table</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertElementPresent</td> | |||
<td>//option[text()='Overall condition coverage']</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertElementNotPresent</td> | |||
<td>//div[@class='widget_props' and @style='']//option[text()='Overall new condition coverage']</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>click</td> | |||
<td>link=Delete</td> | |||
<td></td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</body> | |||
</html> |
@@ -0,0 +1,45 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head profile="http://selenium-ide.openqa.org/profiles/test-case"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | |||
<title>time_machine</title> | |||
</head> | |||
<body> | |||
<table cellpadding="1" cellspacing="1" border="1"> | |||
<thead> | |||
<tr><td rowspan="1" colspan="3">time_machine</td></tr> | |||
</thead><tbody> | |||
<tr> | |||
<td>open</td> | |||
<td>/sonar/widget?id=time_machine&resource=sample&metric1=complexity&metric2=ncloc&metric3=violations&displaySparkLine=true&title=ViveLeSud</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>block_1</td> | |||
<td>*ViveLeSud*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>block_1</td> | |||
<td>*Complexity*6*11*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>block_1</td> | |||
<td>*Lines of code*24*40*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>block_1</td> | |||
<td>*Issues*26*43*</td> | |||
</tr> | |||
<tr> | |||
<td>assertElementPresent</td> | |||
<td>css=img[alt="Chart?cht=sl&chdi=80x15&chv=20141019000000,6"]</td> | |||
<td></td> | |||
</tr> | |||
</tbody></table> | |||
</body> | |||
</html> |
@@ -0,0 +1,84 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- | |||
~ SonarQube, open source software quality management tool. | |||
~ Copyright (C) 2008-2014 SonarSource | |||
~ mailto:contact AT sonarsource DOT com | |||
~ | |||
~ SonarQube 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. | |||
~ | |||
~ SonarQube 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. | |||
--> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head profile="http://selenium-ide.openqa.org/profiles/test-case"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | |||
<title>should-display-timemachine-dashboard</title> | |||
</head> | |||
<body> | |||
<table cellpadding="1" cellspacing="1" border="1"> | |||
<thead> | |||
<tr> | |||
<td rowspan="1" colspan="3">should-display-timemachine-dashboard</td> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr> | |||
<td>open</td> | |||
<td>/sonar/dashboard/index/sample?name=TimeMachine</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>waitForText</td> | |||
<td>dashboard</td> | |||
<td>*Complexity: 3*Technical Debt: 0*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>dashboard</td> | |||
<td>*Sep 01 2012*0.7*Nov 30 2012*0.9*Dec 31 2012*1.0-SNAPSHOT*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>dashboard</td> | |||
<td>*Lines of code*Lines*Statements*Files*Classes*Functions*Accessors*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>dashboard</td> | |||
<td>*Comments*Comment lines*Public documented API*Public undocumented API*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>dashboard</td> | |||
<td>*Duplicated lines (%)*Duplicated lines*Duplicated blocks*Duplicated files*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>dashboard</td> | |||
<td>*Issues*Blocker issues*Critical issues*Major issues*Minor issues*Technical Debt*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>dashboard</td> | |||
<td>*Complexity*Complexity /function*Complexity /class*Complexity /file*</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>dashboard</td> | |||
<td>*Coverage*Line coverage*</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</body> | |||
</html> |