IDEA-136824 [testRunner]: option to keep test console scrolled to the end

GitOrigin-RevId: 7af75752a301691d31da3cfe5d895692032882d8
This commit is contained in:
Bas Leijdekkers
2025-12-11 00:23:23 +00:00
committed by intellij-monorepo-bot
parent a87bab0753
commit a38401d202
5 changed files with 36 additions and 14 deletions
@@ -150,8 +150,13 @@ junit.running.info.expand.test.action.name=Expand all test suites
junit.running.info.select.first.failed.action.name=Select First Failed Test When Finished
junit.running.info.include.non.started.in.rerun.failed.action.name=Include Non-Started Tests in Rerun Failed
junit.running.info.hide.successful.config.action.name=Hide Successful setUp/tearDown
junit.running.info.scroll.to.stacktrace.action.name=Scroll to Stack Trace
junit.running.info.scroll.to.group.name=Scroll To
junit.running.info.scroll.to.stacktrace.action.name=Stack Trace
junit.running.info.scroll.to.stacktrace.action.description=Scroll console to the beginning of assertion or exception stack trace
junit.running.info.scroll.to.top.action.name=Top
junit.running.info.scroll.to.top.action.description=Scroll console to the top after the test ends
junit.running.info.scroll.to.bottom.action.name=Bottom
junit.running.info.scroll.to.bottom.action.description=Scroll console to the bottom after the test ends
junit.running.info.open.source.at.exception.action.name=Open Source at Exception
junit.running.info.open.source.at.exception.action.description=Go to the line which caused an exception when opening a test source
junit.running.info.test.runner.options.group.name=Test Runner Settings
+1
View File
@@ -122,6 +122,7 @@ a:com.intellij.execution.testframework.TestConsoleProperties
- sf:HIDE_SUCCESSFUL_CONFIG:com.intellij.util.config.BooleanProperty
- sf:INCLUDE_NON_STARTED_IN_RERUN_FAILED:com.intellij.util.config.BooleanProperty
- sf:OPEN_FAILURE_LINE:com.intellij.util.config.BooleanProperty
- sf:SCROLL_TO_BOTTOM:com.intellij.util.config.BooleanProperty
- sf:SCROLL_TO_SOURCE:com.intellij.util.config.BooleanProperty
- sf:SCROLL_TO_STACK_TRACE:com.intellij.util.config.BooleanProperty
- sf:SELECT_FIRST_DEFECT:com.intellij.util.config.BooleanProperty
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.execution.testframework;
import com.intellij.execution.DefaultExecutionTarget;
@@ -39,6 +39,7 @@ import java.util.Map;
*/
public abstract class TestConsoleProperties extends StoringPropertyContainer implements Disposable {
public static final BooleanProperty SCROLL_TO_STACK_TRACE = new BooleanProperty("scrollToStackTrace", false);
public static final BooleanProperty SCROLL_TO_BOTTOM = new BooleanProperty("scrollToBottom", false);
public static final BooleanProperty SORT_ALPHABETICALLY = new BooleanProperty("sortTestsAlphabetically", false);
public static final BooleanProperty SORT_BY_DURATION = new BooleanProperty("sortTestsByDuration", false);
public static final BooleanProperty SORT_BY_DECLARATION_ORDER = new BooleanProperty("sortTestsByDeclarationOrder", false);
@@ -1,5 +1,4 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.execution.testframework;
import com.intellij.execution.ExecutionBundle;
@@ -44,15 +43,16 @@ public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposab
private final AnAction[] actionsToMerge;
private final AnAction[] additionalActionsToMerge;
public ToolbarPanel(final TestConsoleProperties properties,
final JComponent parent) {
public ToolbarPanel(TestConsoleProperties properties, JComponent parent) {
super(new BorderLayout());
DefaultActionGroup actionGroup = new DefaultActionGroup();
actionGroup.addAction(new DumbAwareToggleInvertedBooleanProperty(ExecutionBundle.message("junit.run.hide.passed.action.name"), ExecutionBundle.message("junit.run.hide.passed.action.description"),
actionGroup.addAction(new DumbAwareToggleInvertedBooleanProperty(ExecutionBundle.message("junit.run.hide.passed.action.name"),
ExecutionBundle.message("junit.run.hide.passed.action.description"),
AllIcons.RunConfigurations.ShowPassed,
properties, TestConsoleProperties.HIDE_PASSED_TESTS));
actionGroup.add(new DumbAwareToggleInvertedBooleanProperty(TestRunnerBundle.message("action.show.ignored.text"),
TestRunnerBundle.message("action.show.ignored.description"), AllIcons.RunConfigurations.ShowIgnored,
TestRunnerBundle.message("action.show.ignored.description"),
AllIcons.RunConfigurations.ShowIgnored,
properties, TestConsoleProperties.HIDE_IGNORED_TEST));
actionGroup.addSeparator();
@@ -137,8 +137,8 @@ public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposab
}
final RunProfile configuration = properties.getConfiguration();
if (configuration instanceof RunConfiguration) {
myExportAction = ExportTestResultsAction.create(properties.getExecutor().getToolWindowId(), (RunConfiguration)configuration, parent);
if (configuration instanceof RunConfiguration runConfiguration) {
myExportAction = ExportTestResultsAction.create(properties.getExecutor().getToolWindowId(), runConfiguration, parent);
moreGroup.addAction(myExportAction);
}
@@ -157,9 +157,20 @@ public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposab
}
secondaryGroup.addSeparator();
secondaryGroup.add(new DumbAwareToggleBooleanProperty(ExecutionBundle.message("junit.running.info.scroll.to.stacktrace.action.name"),
ExecutionBundle.message("junit.running.info.scroll.to.stacktrace.action.description"),
null, properties, TestConsoleProperties.SCROLL_TO_STACK_TRACE));
DefaultActionGroup scrollToGroup = new DefaultActionGroup();
scrollToGroup.getTemplatePresentation().setText(ExecutionBundle.message("junit.running.info.scroll.to.group.name"));
scrollToGroup.setPopup(true);
scrollToGroup.add(new DumbAwareToggleBooleanProperty(ExecutionBundle.message("junit.running.info.scroll.to.stacktrace.action.name"),
ExecutionBundle.message("junit.running.info.scroll.to.stacktrace.action.description"),
null, properties, TestConsoleProperties.SCROLL_TO_STACK_TRACE));
scrollToGroup.addSeparator();
scrollToGroup.add(new DumbAwareToggleInvertedBooleanProperty(ExecutionBundle.message("junit.running.info.scroll.to.top.action.name"),
ExecutionBundle.message("junit.running.info.scroll.to.top.action.description"),
null, properties, TestConsoleProperties.SCROLL_TO_BOTTOM));
scrollToGroup.add(new DumbAwareToggleBooleanProperty(ExecutionBundle.message("junit.running.info.scroll.to.bottom.action.name"),
ExecutionBundle.message("junit.running.info.scroll.to.bottom.action.description"),
null, properties, TestConsoleProperties.SCROLL_TO_BOTTOM));
secondaryGroup.add(scrollToGroup);
secondaryGroup.add(new ToggleBooleanProperty(ExecutionBundle.message("junit.running.info.open.source.at.exception.action.name"),
ExecutionBundle.message("junit.running.info.open.source.at.exception.action.description"),
null, properties, TestConsoleProperties.OPEN_FAILURE_LINE));
@@ -195,7 +206,7 @@ public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposab
return myOccurenceNavigator.getActionUpdateThread();
}
public void setModel(final TestFrameworkRunningModel model) {
public void setModel(TestFrameworkRunningModel model) {
TestFrameworkActions.installFilterAction(model);
myScrollToSource.setModel(model);
myTreeExpander.setModel(model);
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.execution.testframework.ui;
import com.intellij.execution.filters.HyperlinkInfo;
@@ -137,6 +137,10 @@ public class TestsOutputConsolePrinter implements Printer, Disposable {
}
private void scrollToBeginning() {
if (TestConsoleProperties.SCROLL_TO_BOTTOM.value(myProperties) &&
(!TestConsoleProperties.SCROLL_TO_STACK_TRACE.value(myProperties) || myMarkOffset == 0)) {
return;
}
EdtInvocationManager.invokeLaterIfNeeded(() -> {
if (!myDisposed) {
myConsole.performWhenNoDeferredOutput(() -> {