From f6b80cf5c3cf2062557ed48810e0fc3609151b64 Mon Sep 17 00:00:00 2001 From: Louis Vignier Date: Fri, 21 Feb 2025 18:43:28 +0100 Subject: [PATCH] [java] Fix the auto-test floating toolbar behavior Auto-test is disabled: - when another test configuration is started - when the test configuration tab is closed #IDEA-365697 Fixed #IDEA-365668 Fixed (cherry picked from commit 417cb8a692feda19ccb635c8732b52613a71b6b3) IJ-CR-155896 GitOrigin-RevId: e0d3504cf063d588ef9d79cd3f8ecc290c52e4ec --- .../JavaAutoRunFloatingToolbarProvider.kt | 93 +++++++++++++------ .../JavaAutoRunToggleFloatingToolbarAction.kt | 23 ----- .../messages/JavaUiBundle.properties | 1 - .../resources/META-INF/JavaPlugin.xml | 4 - .../messages/ExecutionBundle.properties | 2 + platform/testRunner/api-dump.txt | 1 + .../testframework/TestConsoleProperties.java | 1 + .../execution/testframework/ToolbarPanel.java | 3 + .../autotest/AbstractAutoTestManager.java | 3 +- .../autotest/AutoTestListener.kt | 1 - 10 files changed, 75 insertions(+), 57 deletions(-) delete mode 100644 java/execution/impl/src/com/intellij/execution/testDiscovery/JavaAutoRunToggleFloatingToolbarAction.kt diff --git a/java/execution/impl/src/com/intellij/execution/testDiscovery/JavaAutoRunFloatingToolbarProvider.kt b/java/execution/impl/src/com/intellij/execution/testDiscovery/JavaAutoRunFloatingToolbarProvider.kt index 372367fd7ba1..ca5484d10cd5 100644 --- a/java/execution/impl/src/com/intellij/execution/testDiscovery/JavaAutoRunFloatingToolbarProvider.kt +++ b/java/execution/impl/src/com/intellij/execution/testDiscovery/JavaAutoRunFloatingToolbarProvider.kt @@ -1,8 +1,17 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution.testDiscovery -import com.intellij.execution.testDiscovery.JavaAutoRunFloatingToolbarService.JavaAutoRunFloatingToolbarState +import com.intellij.execution.ExecutionListener +import com.intellij.execution.ExecutionManager +import com.intellij.execution.process.ProcessHandler +import com.intellij.execution.runners.ExecutionEnvironment +import com.intellij.execution.testframework.TestConsoleProperties import com.intellij.execution.testframework.autotest.AutoTestListener +import com.intellij.execution.testframework.sm.runner.ui.SMTRunnerConsoleView +import com.intellij.execution.ui.ConsoleViewWithDelegate +import com.intellij.execution.ui.ExecutionConsole +import com.intellij.execution.ui.RunContentDescriptor +import com.intellij.execution.ui.RunContentManager import com.intellij.icons.AllIcons import com.intellij.ide.IdeBundle import com.intellij.java.JavaBundle @@ -10,12 +19,13 @@ import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.* import com.intellij.openapi.actionSystem.ex.CustomComponentAction import com.intellij.openapi.actionSystem.impl.ActionButton -import com.intellij.openapi.components.* import com.intellij.openapi.editor.EditorKind import com.intellij.openapi.editor.toolbar.floating.FloatingToolbarComponent import com.intellij.openapi.editor.toolbar.floating.FloatingToolbarProvider import com.intellij.openapi.editor.toolbar.floating.isInsideMainEditor +import com.intellij.openapi.observable.util.whenDisposed import com.intellij.openapi.project.DumbAware +import com.intellij.openapi.project.Project import com.intellij.ui.components.JBLabel import com.intellij.util.application import com.intellij.util.ui.GridBag @@ -31,6 +41,8 @@ import javax.swing.JPanel @ApiStatus.Internal class JavaAutoRunFloatingToolbarProvider : FloatingToolbarProvider { + private var configuration: RunContentDescriptor? = null + override val backgroundAlpha: Float = JBUI.CurrentTheme.FloatingToolbar.TRANSLUCENT_BACKGROUND_ALPHA override val autoHideable: Boolean = false @@ -50,21 +62,47 @@ class JavaAutoRunFloatingToolbarProvider : FloatingToolbarProvider { val autoRunManager = JavaAutoRunManager.getInstance(project) application.invokeLater { - updateFloatingToolbarVisibility(component, autoRunManager) + updateFloatingToolbarVisibility(project, component, autoRunManager) } project.messageBus.connect(parentDisposable).subscribe(AutoTestListener.TOPIC, object: AutoTestListener { override fun autoTestStatusChanged() { - updateFloatingToolbarVisibility(component, autoRunManager) + updateFloatingToolbarVisibility(project, component, autoRunManager) + // Picks up the current descriptor when auto-test is enabled (auto-test is always disabled on project opening) + updateCurrentConfiguration(project, autoRunManager, component) } - override fun autoTestSettingsChanged() { - updateFloatingToolbarVisibility(component, autoRunManager) + }) + + // The descriptor is disposed and created again after each run. + project.messageBus.connect(parentDisposable).subscribe(ExecutionManager.EXECUTION_TOPIC, object : ExecutionListener { + override fun processStarted(executorId: String, env: ExecutionEnvironment, handler: ProcessHandler) { + updateCurrentConfiguration(project, autoRunManager, component) } }) } - private fun updateFloatingToolbarVisibility(component: FloatingToolbarComponent, autoRunManager: JavaAutoRunManager) { - val isToolbarEnabled = service().toolbarEnabled + /** + * Keeps track of the current auto-run test descriptor. + */ + private fun updateCurrentConfiguration(project: Project, autoRunManager: JavaAutoRunManager, component: FloatingToolbarComponent) { + val content = RunContentManager.getInstance(project).getAllDescriptors().firstOrNull { autoRunManager.isAutoTestEnabled(it) } + if (content != configuration) { configuration = content; } else { return } + if (content == null) { + updateFloatingToolbarVisibility(project, component, autoRunManager) + return + } + + content.whenDisposed { + updateFloatingToolbarVisibility(project, component, autoRunManager) + } + + getConsoleProperties(project)?.addListener(TestConsoleProperties.SHOW_AUTO_TEST_TOOLBAR) { + updateFloatingToolbarVisibility(project, component, autoRunManager) + } + } + + private fun updateFloatingToolbarVisibility(project: Project, component: FloatingToolbarComponent, autoRunManager: JavaAutoRunManager) { + val isToolbarEnabled = isAutoTestToolbarEnabled(project) val hasEnabledAutoTests = autoRunManager.hasEnabledAutoTests() if (isToolbarEnabled && hasEnabledAutoTests) { component.autoHideable = true @@ -103,7 +141,9 @@ private class DisableAction : AnAction(IdeBundle.message("button.disable"), Java private class HideAction : AnAction() { override fun actionPerformed(e: AnActionEvent) { - application.service().toolbarEnabled = false + val project = e.project ?: return + val properties = getConsoleProperties(project) ?: return + TestConsoleProperties.SHOW_AUTO_TEST_TOOLBAR.set(properties, false) } override fun getActionUpdateThread() = ActionUpdateThread.EDT @@ -113,26 +153,25 @@ private class HideAction : AnAction() { } } +private fun getContentDescriptor(project: Project): RunContentDescriptor? { + return RunContentManager.getInstanceIfCreated(project)?.selectedContent +} -@Service(Service.Level.APP) -@State(name = "JavaAutoRunFloatingToolbarSettings", storages = [Storage(StoragePathMacros.NON_ROAMABLE_FILE)]) -internal class JavaAutoRunFloatingToolbarService : SimplePersistentStateComponent( - JavaAutoRunFloatingToolbarState() -) { - private val messageBusPublisher by lazy { - application.messageBus.syncPublisher(AutoTestListener.TOPIC) - } +private fun getConsoleProperties(project: Project): TestConsoleProperties? { + val content = getContentDescriptor(project) ?: return null + val console = getSMTRunnerConsoleView(content.executionConsole) ?: return null + return console.properties +} - var toolbarEnabled: Boolean - get() = state.toolbarEnabled - set(value) { - if (value != state.toolbarEnabled) { - state.toolbarEnabled = value - messageBusPublisher.autoTestSettingsChanged() - } - } +private fun isAutoTestToolbarEnabled(project: Project): Boolean { + val properties = getConsoleProperties(project) ?: return false + return TestConsoleProperties.SHOW_AUTO_TEST_TOOLBAR.get(properties) +} - class JavaAutoRunFloatingToolbarState() : BaseState() { - var toolbarEnabled by property(true) +private fun getSMTRunnerConsoleView(console: ExecutionConsole): SMTRunnerConsoleView? { + return when (console) { + is SMTRunnerConsoleView -> console + is ConsoleViewWithDelegate -> getSMTRunnerConsoleView(console.delegate) + else -> null } } \ No newline at end of file diff --git a/java/execution/impl/src/com/intellij/execution/testDiscovery/JavaAutoRunToggleFloatingToolbarAction.kt b/java/execution/impl/src/com/intellij/execution/testDiscovery/JavaAutoRunToggleFloatingToolbarAction.kt deleted file mode 100644 index f0da3f2773bd..000000000000 --- a/java/execution/impl/src/com/intellij/execution/testDiscovery/JavaAutoRunToggleFloatingToolbarAction.kt +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.execution.testDiscovery - -import com.intellij.openapi.actionSystem.ActionUpdateThread -import com.intellij.openapi.actionSystem.AnActionEvent -import com.intellij.openapi.actionSystem.ToggleAction -import com.intellij.openapi.components.service -import com.intellij.openapi.project.DumbAware - -class JavaAutoRunToggleFloatingToolbarAction: ToggleAction(), DumbAware { - override fun getActionUpdateThread(): ActionUpdateThread { - return ActionUpdateThread.BGT - } - - override fun isSelected(e: AnActionEvent): Boolean { - return service().toolbarEnabled - } - - override fun setSelected(e: AnActionEvent, state: Boolean) { - val service = service() - service.toolbarEnabled = state - } -} \ No newline at end of file diff --git a/java/idea-ui/resources/messages/JavaUiBundle.properties b/java/idea-ui/resources/messages/JavaUiBundle.properties index 1752bcf8dc33..7669df2c4794 100644 --- a/java/idea-ui/resources/messages/JavaUiBundle.properties +++ b/java/idea-ui/resources/messages/JavaUiBundle.properties @@ -710,7 +710,6 @@ action.ResolveAllRepositoryLibraries.text=Resolve All Maven Libraries action.ParseSdkmanrcAction.text=Update Project JDK action.DownloadJdkAction.text=Download JDK\u2026 action.AddJdkAction.text=Add JDK from Disk\u2026 -action.JavaAutoRunToggleFloatingToolbarAction.text=Show Auto Run Status in the Editor library.depends.on.ide.title=Dependency on JARs from the IDE installation library.depends.on.ide.message=Library {0} uses JARs from the IDE installation. It might break if JAR is removed from a future version of the IDE. {1} diff --git a/java/java-impl/resources/META-INF/JavaPlugin.xml b/java/java-impl/resources/META-INF/JavaPlugin.xml index 5929746cde83..abb03c75f34a 100644 --- a/java/java-impl/resources/META-INF/JavaPlugin.xml +++ b/java/java-impl/resources/META-INF/JavaPlugin.xml @@ -2819,10 +2819,6 @@ - - - - diff --git a/platform/execution/resources/messages/ExecutionBundle.properties b/platform/execution/resources/messages/ExecutionBundle.properties index 4274ce37c15a..fd6b535110a3 100644 --- a/platform/execution/resources/messages/ExecutionBundle.properties +++ b/platform/execution/resources/messages/ExecutionBundle.properties @@ -131,6 +131,8 @@ junit.running.info.tests.failed.label=Tests Failed junit.running.info.tests.failed.with.test.name.label=Tests Failed {0} junit.running.info.tests.passed.label=Tests Passed junit.running.info.tests.passed.with.test.name.label=Tests Passed {0} +junit.running.info.show.auto.test.status.text=Show Auto-Test Status in the Editor +junit.running.info.show.auto.test.status.description=Enables the auto-test status floating toolbar in the editor junit.run.hide.passed.action.name=Show Passed junit.run.hide.passed.action.description=Show passed tests junit.runing.info.track.test.action.name=Track Running Test diff --git a/platform/testRunner/api-dump.txt b/platform/testRunner/api-dump.txt index 92db16357104..d829cd454113 100644 --- a/platform/testRunner/api-dump.txt +++ b/platform/testRunner/api-dump.txt @@ -125,6 +125,7 @@ a:com.intellij.execution.testframework.TestConsoleProperties - 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 +- sf:SHOW_AUTO_TEST_TOOLBAR:com.intellij.util.config.BooleanProperty - sf:SHOW_INLINE_STATISTICS:com.intellij.util.config.BooleanProperty - sf:SHOW_STATISTICS:com.intellij.util.config.BooleanProperty - sf:SORT_ALPHABETICALLY:com.intellij.util.config.BooleanProperty diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java b/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java index 156e4b951a80..0c85c0af1209 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java @@ -54,6 +54,7 @@ public abstract class TestConsoleProperties extends StoringPropertyContainer imp public static final BooleanProperty SHOW_INLINE_STATISTICS = new BooleanProperty("showInlineStatistics", true); public static final BooleanProperty INCLUDE_NON_STARTED_IN_RERUN_FAILED = new BooleanProperty("includeNonStarted", true); public static final BooleanProperty HIDE_SUCCESSFUL_CONFIG = new BooleanProperty("hideConfig", false); + public static final BooleanProperty SHOW_AUTO_TEST_TOOLBAR = new BooleanProperty("autoTestToolbar", true); private final Project myProject; private final Executor myExecutor; diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ToolbarPanel.java b/platform/testRunner/src/com/intellij/execution/testframework/ToolbarPanel.java index 6f332c098b4d..d00e3d313380 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ToolbarPanel.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ToolbarPanel.java @@ -163,6 +163,9 @@ public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposab secondaryGroup.add(myScrollToSource); secondaryGroup.add(new AdjustAutotestDelayActionGroup()); + secondaryGroup.add(new ToggleBooleanProperty(ExecutionBundle.message("junit.running.info.show.auto.test.status.text"), + ExecutionBundle.message("junit.running.info.show.auto.test.status.description"), + null, properties, TestConsoleProperties.SHOW_AUTO_TEST_TOOLBAR)); secondaryGroup.addSeparator(); secondaryGroup.add(new DumbAwareToggleBooleanProperty(ExecutionBundle.message("junit.runing.info.select.first.failed.action.name"), null, null, properties, TestConsoleProperties.SELECT_FIRST_DEFECT)); diff --git a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AbstractAutoTestManager.java b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AbstractAutoTestManager.java index 3e5e4b64a75e..6565b8893ba6 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AbstractAutoTestManager.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AbstractAutoTestManager.java @@ -155,7 +155,8 @@ public abstract class AbstractAutoTestManager implements PersistentStateComponen return ContainerUtil.exists(RunContentManager.getInstance(myProject).getAllDescriptors(), this::isAutoTestEnabled); } - boolean isAutoTestEnabled(@NotNull RunContentDescriptor descriptor) { + @ApiStatus.Internal + public boolean isAutoTestEnabled(@NotNull RunContentDescriptor descriptor) { ExecutionEnvironment environment = getCurrentEnvironment(descriptor); return environment != null && myEnabledRunProfiles.contains(environment.getRunProfile()); } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestListener.kt b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestListener.kt index 18d79722a8d1..6912b894c3a0 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestListener.kt +++ b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestListener.kt @@ -7,7 +7,6 @@ import org.jetbrains.annotations.ApiStatus @ApiStatus.Internal interface AutoTestListener { fun autoTestStatusChanged() - fun autoTestSettingsChanged() companion object { @Topic.ProjectLevel