@@ -7,12 +7,11 @@ fun environment(key: String) = providers.environmentVariable(key)
77plugins {
88 id(" java" ) // Java support
99 alias(libs.plugins.kotlin) // Kotlin support
10- alias(libs.plugins.gradleIntelliJPlugin) // Gradle IntelliJ Plugin
10+ alias(libs.plugins.gradleIntelliJPlugin) // IntelliJ Platform Gradle Plugin
1111 alias(libs.plugins.changelog) // Gradle Changelog Plugin
12- kotlin(" plugin.serialization" ) version libs.versions.kotlin.get()
13- id(" org.jetbrains.compose" )
12+ alias(libs.plugins.compose) // Gradle Compose Compiler Plugin
1413 alias(libs.plugins.spotless)
15- alias( libs.plugins.compose )
14+ kotlin( " plugin.serialization " ) version libs.versions.kotlin.get( )
1615}
1716
1817group = properties(" pluginGroup" ).get()
@@ -38,36 +37,36 @@ repositories {
3837 intellijPlatform {
3938 defaultRepositories()
4039 }
40+ maven(" https://packages.jetbrains.team/maven/p/ij/intellij-dependencies" )
4141}
4242
4343apply (
4444 from = " gradle/spotless.gradle"
4545)
4646
47+ sourceSets {
48+ create(" uiTest" ) {
49+ kotlin.srcDir(" src/uiTest/kotlin" )
50+ }
51+ }
52+
4753dependencies {
4854 implementation(libs.freemarker)
4955 implementation(libs.serialization)
50- implementation(compose.desktop.currentOs)
51- implementation(compose.materialIconsExtended)
5256 implementation(libs.segment)
5357
54- // I usually do
55- // ./gradlew dependencies | grep "skiko"
56- // to get the skiko version that compose depends on
57- val version = " 0.9.37.4"
58- val macTarget = " macos-arm64"
59- val windowsTarget = " windows-x64"
60- val linuxTarget = " linux-x64"
61-
62- implementation(" org.jetbrains.skiko:skiko-awt-runtime-$macTarget :$version " )
63- implementation(" org.jetbrains.skiko:skiko-awt-runtime-$windowsTarget :$version " )
64- implementation(" org.jetbrains.skiko:skiko-awt-runtime-$linuxTarget :$version " )
65-
6658 testImplementation(libs.junit)
6759
60+ " uiTestImplementation" (kotlin(" stdlib" ))
61+ " uiTestImplementation" (libs.remoteRobot)
62+ " uiTestImplementation" (libs.remoteRobotFixtures)
63+ " uiTestImplementation" (libs.junit)
64+ " uiTestImplementation" (" com.squareup.okhttp3:okhttp:4.12.0" )
65+ // The Compose compiler plugin applies to all source sets; uiTest needs the runtime on its classpath
66+ " uiTestImplementation" (" org.jetbrains.compose.runtime:runtime-desktop:1.7.3" )
67+
6868 // IntelliJ Platform Gradle Plugin Dependencies Extension - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html
6969 intellijPlatform {
70- javaCompiler(" 243.26053.29" ) // https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1894
7170 create(properties(" platformType" ).get(), properties(" platformVersion" ).get())
7271
7372 // Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
@@ -76,6 +75,10 @@ dependencies {
7675 // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file for plugin from JetBrains Marketplace.
7776 plugins(properties(" platformPlugins" ).map { it.split(' ,' ) })
7877
78+ // Compose support dependencies
79+ @Suppress(" UnstableApiUsage" )
80+ composeUI()
81+
7982 // instrumentationTools()
8083 pluginVerifier()
8184 zipSigner()
@@ -136,6 +139,24 @@ tasks {
136139 }
137140}
138141
142+ tasks.register<Test >(" uiTest" ) {
143+ description = " Runs UI tests against a running IDE instance"
144+ group = " verification"
145+ testClassesDirs = sourceSets[" uiTest" ].output.classesDirs
146+ classpath = sourceSets[" uiTest" ].runtimeClasspath
147+ systemProperty(" robot-server.port" , System .getProperty(" robot-server.port" , " 8082" ))
148+ doNotTrackState(" UI tests are not cacheable" )
149+ // Gson (used by the remote-robot client) reflectively accesses private fields such as
150+ // Throwable.detailMessage when deserializing error responses from the robot server.
151+ // JDK 17+ JPMS blocks this by default; --add-opens restores access.
152+ jvmArgs(" --add-opens=java.base/java.lang=ALL-UNNAMED" )
153+ // Echo test stdout/stderr directly to the Gradle console so diagnostic println calls
154+ // (accessibility tree dumps, screenshots, component class lists) are visible live.
155+ testLogging {
156+ showStandardStreams = true
157+ }
158+ }
159+
139160intellijPlatformTesting {
140161 runIde {
141162 register(" runIdeForUiTests" ) {
@@ -145,9 +166,24 @@ intellijPlatformTesting {
145166 " -Drobot-server.port=8082" ,
146167 " -Dide.mac.message.dialogs.as.sheets=false" ,
147168 " -Djb.privacy.policy.text=<!--999.999-->" ,
148- " -Djb.consents.confirmation.enabled=false"
169+ " -Djb.consents.confirmation.enabled=false" ,
170+ // Skip the "Trust Project?" dialog that blocks the IDE frame from appearing
171+ " -Didea.trust.all.projects=true" ,
172+ " -Didea.initially.ask.config=never" ,
173+ // Suppress Tip of the Day, What's New, and other first-run dialogs
174+ " -Dide.show.tips.on.startup.default.value=false" ,
175+ " -Didea.is.internal=false" ,
176+ " -Dide.no.platform.update=true" ,
177+ // Skip import settings dialog
178+ " -Didea.config.imported.in.current.session=true" ,
179+ // Force the Swing menu bar so remote-robot can find menu items.
180+ // Without this, macOS uses the native system menu bar which is
181+ // invisible to the Swing component hierarchy that remote-robot inspects.
182+ " -Dapple.laf.useScreenMenuBar=false"
149183 )
150184 }
185+ // Open the test project so settings.gradle.kts is available for module creation
186+ args(layout.projectDirectory.dir(" src/uiTest/testProject" ).asFile.absolutePath)
151187 }
152188
153189 plugins {
0 commit comments