Skip to content

Commit 3ef2c12

Browse files
committed
Bootstrap the Flutter IJ with integrations tests
The additional STARTER test framework is added, see https://github.com/JetBrains/intellij-ide-starter Thanks to others here who trailblazed, @jonathan1983, JetBrains/intellij-platform-plugin-template#537 and @helinx, flutter#8338
1 parent 25f8e08 commit 3ef2c12

File tree

6 files changed

+571
-37
lines changed

6 files changed

+571
-37
lines changed

.github/workflows/presubmit.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
strategy:
2929
fail-fast: true
3030
matrix:
31-
bot: [CHECK_BOT, DART_BOT, UNIT_TEST_BOT, VERIFY_BOT]
31+
bot: [CHECK_BOT, DART_BOT, UNIT_TEST_BOT, VERIFY_BOT, INTEGRATION_BOT]
3232
steps:
3333
- name: checkout
3434
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8

build.gradle.kts

Lines changed: 112 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ allprojects {
2828

2929
repositories {
3030
mavenCentral()
31+
maven("https://cache-redirector.jetbrains.com/packages.jetbrains.team/maven/p/ij/intellij-ide-starter")
32+
maven("https://mvnrepository.com/artifact/com.jetbrains.intellij.tools/ide-starter-driver")
3133
intellijPlatform {
3234
defaultRepositories()
3335
}
@@ -41,6 +43,7 @@ plugins {
4143
id("org.jetbrains.intellij.platform") version "2.7.0" // IntelliJ Platform Gradle Plugin
4244
id("org.jetbrains.kotlin.jvm") version "2.2.0" // Kotlin support
4345
id("org.jetbrains.changelog") version "2.2.0" // Gradle Changelog Plugin
46+
idea // IntelliJ IDEA support
4447
}
4548

4649
// By default (e.g. when we call `runIde` during development), the plugin version is SNAPSHOT
@@ -90,11 +93,17 @@ jvmVersion = when (javaVersion) {
9093
throw IllegalArgumentException("javaVersion must be defined in the product matrix as either \"17\" or \"21\", but is not for $ideaVersion")
9194
}
9295
}
96+
9397
kotlin {
9498
compilerOptions {
9599
apiVersion.set(KotlinVersion.KOTLIN_2_1)
96100
jvmTarget = jvmVersion
97101
}
102+
jvmToolchain {
103+
languageVersion = JavaLanguageVersion.of(21)
104+
@Suppress("UnstableApiUsage")
105+
vendor = JvmVendorSpec.JETBRAINS
106+
}
98107
}
99108

100109
var javaCompatibilityVersion: JavaVersion
@@ -111,18 +120,79 @@ javaCompatibilityVersion = when (javaVersion) {
111120
throw IllegalArgumentException("javaVersion must be defined in the product matrix as either \"17\" or \"21\", but is not for $ideaVersion")
112121
}
113122
}
123+
114124
java {
115125
sourceCompatibility = javaCompatibilityVersion
116126
targetCompatibility = javaCompatibilityVersion
117127
}
118128

129+
sourceSets {
130+
main {
131+
java.srcDirs(
132+
listOf(
133+
"src",
134+
"third_party/vmServiceDrivers"
135+
)
136+
)
137+
// Add kotlin.srcDirs if we start using Kotlin in the main plugin.
138+
resources.srcDirs(
139+
listOf(
140+
"src",
141+
"resources"
142+
)
143+
)
144+
}
145+
test {
146+
java.srcDirs(
147+
listOf(
148+
"src",
149+
"testSrc/unit",
150+
"third_party/vmServiceDrivers"
151+
)
152+
)
153+
resources.srcDirs(
154+
listOf(
155+
"resources",
156+
"testData",
157+
"testSrc/unit"
158+
)
159+
)
160+
}
161+
162+
create("integration", Action<SourceSet> {
163+
java.srcDirs("testSrc/integration")
164+
kotlin.srcDirs("testSrc/integration")
165+
resources.srcDirs("testSrc/integration")
166+
compileClasspath += sourceSets["main"].output + sourceSets["test"].output
167+
runtimeClasspath += sourceSets["main"].output + sourceSets["test"].output
168+
})
169+
}
170+
171+
// Configure IntelliJ IDEA to recognize integration as test sources
172+
idea {
173+
module {
174+
testSources.from(sourceSets["integration"].kotlin.srcDirs)
175+
testResources.from(sourceSets["integration"].resources.srcDirs)
176+
}
177+
}
178+
179+
val integrationImplementation: Configuration by configurations.getting {
180+
extendsFrom(configurations.testImplementation.get())
181+
}
182+
183+
val integrationRuntimeOnly: Configuration by configurations.getting {
184+
extendsFrom(configurations.testRuntimeOnly.get())
185+
}
186+
119187
dependencies {
120188
intellijPlatform {
121189
// Documentation on the default target platform methods:
122190
// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html#default-target-platforms
123191
// Android Studio versions can be found at: https://plugins.jetbrains.com/docs/intellij/android-studio-releases-list.html
124192
androidStudio(ideaVersion)
125193
testFramework(TestFrameworkType.Platform)
194+
testFramework(TestFrameworkType.Starter, configurationName = "integrationImplementation")
195+
testFramework(TestFrameworkType.JUnit5, configurationName = "integrationImplementation")
126196

127197
// Plugin dependency documentation:
128198
// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html#plugins
@@ -166,6 +236,14 @@ dependencies {
166236
)
167237
)
168238
)
239+
240+
// UI Test dependencies
241+
integrationImplementation("org.kodein.di:kodein-di-jvm:7.26.1")
242+
integrationImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
243+
244+
// JUnit 5 is required for UI tests
245+
integrationImplementation("org.junit.jupiter:junit-jupiter:5.11.4")
246+
integrationRuntimeOnly("org.junit.platform:junit-platform-launcher")
169247
}
170248

171249
intellijPlatform {
@@ -213,37 +291,42 @@ intellijPlatform {
213291
}
214292
}
215293

216-
sourceSets {
217-
main {
218-
java.srcDirs(
219-
listOf(
220-
"src",
221-
"third_party/vmServiceDrivers"
222-
)
223-
)
224-
// Add kotlin.srcDirs if we start using Kotlin in the main plugin.
225-
resources.srcDirs(
226-
listOf(
227-
"src",
228-
"resources"
229-
)
230-
)
231-
}
232-
test {
233-
java.srcDirs(
234-
listOf(
235-
"src",
236-
"testSrc/unit",
237-
"third_party/vmServiceDrivers"
238-
)
294+
tasks {
295+
register<Test>("integration") {
296+
description = "Runs only the UI integration tests that start the IDE"
297+
group = "verification"
298+
testClassesDirs = sourceSets["integration"].output.classesDirs
299+
classpath = sourceSets["integration"].runtimeClasspath
300+
useJUnitPlatform {
301+
includeTags("ui")
302+
}
303+
304+
// UI tests should run sequentially (not in parallel) to avoid conflicts
305+
maxParallelForks = 1
306+
307+
// Increase memory for UI tests
308+
minHeapSize = "1g"
309+
maxHeapSize = "4g"
310+
311+
systemProperty("path.to.build.plugin", buildPlugin.get().archiveFile.get().asFile.absolutePath)
312+
systemProperty("idea.home.path", prepareTestSandbox.get().getDestinationDir().parentFile.absolutePath)
313+
systemProperty(
314+
"allure.results.directory", project.layout.buildDirectory.get().asFile.absolutePath + "/allure-results"
239315
)
240-
resources.srcDirs(
241-
listOf(
242-
"resources",
243-
"testData",
244-
"testSrc/unit"
316+
// systemProperty("uiPlatformBuildVersion", providers.gradleProperty("uiPlatformBuildVersion").get())
317+
318+
// Disable IntelliJ test listener that conflicts with standard JUnit
319+
systemProperty("idea.test.cyclic.buffer.size", "0")
320+
321+
// Add required JVM arguments
322+
jvmArgumentProviders += CommandLineArgumentProvider {
323+
mutableListOf(
324+
"--add-opens=java.base/java.lang=ALL-UNNAMED",
325+
"--add-opens=java.desktop/javax.swing=ALL-UNNAMED"
245326
)
246-
)
327+
}
328+
329+
dependsOn(buildPlugin)
247330
}
248331
}
249332

src/io/flutter/module/FlutterGeneratorPeer.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,7 @@
2424
import io.flutter.sdk.FlutterSdk;
2525
import io.flutter.sdk.FlutterSdkUtil;
2626

27-
import javax.swing.ComboBoxEditor;
28-
import javax.swing.JComponent;
29-
import javax.swing.JLabel;
30-
import javax.swing.JPanel;
31-
import javax.swing.JScrollPane;
32-
import javax.swing.JTextPane;
27+
import javax.swing.*;
3328
import javax.swing.event.DocumentEvent;
3429
import javax.swing.text.JTextComponent;
3530

@@ -65,6 +60,16 @@ public FlutterGeneratorPeer(WizardContext context) {
6560
private void init() {
6661
mySdkPathComboWithBrowse.getComboBox().setEditable(true);
6762
FlutterSdkUtil.addKnownSDKPathsToCombo(mySdkPathComboWithBrowse.getComboBox());
63+
if (mySdkPathComboWithBrowse.getComboBox().getModel().getSize() == 0) {
64+
// If no SDKs are found, try to use the one from the FLUTTER_SDK environment variable.
65+
// This ensures the SDK path is pre-filled when the combo box is empty, not requiring
66+
// a running Application which is the case for users and bots on the initial startup
67+
// experience.
68+
final String flutterSDKPath = System.getenv("FLUTTER_SDK");
69+
if (flutterSDKPath != null && !flutterSDKPath.isEmpty()) {
70+
mySdkPathComboWithBrowse.getComboBox().setSelectedItem(flutterSDKPath);
71+
}
72+
}
6873

6974
mySdkPathComboWithBrowse.addBrowseFolderListener(null, FileChooserDescriptorFactory.createSingleFolderDescriptor()
7075
.withTitle(FlutterBundle.message("flutter.sdk.browse.path.label")), TextComponentAccessor.STRING_COMBOBOX_WHOLE_TEXT);

0 commit comments

Comments
 (0)