Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e5d908a

Browse files
committed
Starting to add a new test
Removed the jvmToolchain requirement in build.gradle.kts
1 parent 5a6a42a commit e5d908a

File tree

6 files changed

+198
-111
lines changed

6 files changed

+198
-111
lines changed

‎.github/workflows/presubmit.yaml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
steps:
2222
- name: checkout
2323
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
24-
# Allows the specification of a specific Java SDK
24+
# Allows the specification of a specific Java SDK, this may be required for the Starter test framework
2525
# - name: Set up JDK 21
2626
# uses: actions/setup-java@v4
2727
# with:
@@ -34,7 +34,7 @@ jobs:
3434
strategy:
3535
fail-fast: true
3636
matrix:
37-
bot: [CHECK_BOT, DART_BOT, UNIT_TEST_BOT, VERIFY_BOT] #, INTEGRATION_BOT]
37+
bot: [CHECK_BOT, DART_BOT, UNIT_TEST_BOT, VERIFY_BOT, INTEGRATION_BOT]
3838
steps:
3939
- name: checkout
4040
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8

‎build.gradle.kts‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,12 @@ kotlin {
9999
apiVersion.set(KotlinVersion.KOTLIN_2_1)
100100
jvmTarget = jvmVersion
101101
}
102-
jvmToolchain {
103-
languageVersion = JavaLanguageVersion.of(21)
104-
@Suppress("UnstableApiUsage")
105-
vendor = JvmVendorSpec.JETBRAINS
106-
}
102+
// This is how you specify the specific JVM requirements, this may be a requirement for the Starter test framework
103+
// jvmToolchain {
104+
// languageVersion = JavaLanguageVersion.of(21)
105+
// @Suppress("UnstableApiUsage")
106+
// vendor = JvmVendorSpec.JETBRAINS
107+
// }
107108
}
108109

109110
var javaCompatibilityVersion: JavaVersion

‎gradle.properties‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,3 @@ javaVersion=21
1212
kotlin.stdlib.default.dependency=false
1313
org.gradle.parallel=true
1414
org.gradle.jvmargs=-Xms1024m -Xmx4048m
15-
16-
org.gradle.java.installations.auto-detect=false
17-
org.gradle.java.installations.dirs=/opt/jdk-21 # Replace with the actual path where JDK 21 is installed by the GitHub Actions runner

‎testSrc/integration/io/flutter/integrationTest/NewProjectUITest.kt‎

Lines changed: 4 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,18 @@
66

77
package io.flutter.integrationTest
88

9-
import com.intellij.driver.sdk.ui.Finder
10-
import com.intellij.driver.sdk.ui.components.ComponentData
11-
import com.intellij.driver.sdk.ui.components.UiComponent
129
import com.intellij.driver.sdk.ui.components.UiComponent.Companion.waitFound
1310
import com.intellij.driver.sdk.ui.components.common.ideFrame
1411
import com.intellij.driver.sdk.ui.components.common.toolwindows.projectView
15-
import com.intellij.driver.sdk.ui.components.common.welcomeScreen
16-
import com.intellij.driver.sdk.wait
1712
import com.intellij.driver.sdk.waitForIndicators
1813
import com.intellij.ide.starter.driver.engine.BackgroundRun
1914
import com.intellij.ide.starter.driver.engine.runIdeWithDriver
2015
import com.intellij.ide.starter.junit5.config.UseLatestDownloadedIdeBuild
16+
import io.flutter.integrationTest.utils.newProjectWelcomeScreen
2117
import org.junit.jupiter.api.*
2218
import org.junit.jupiter.api.extension.ExtendWith
2319
import java.nio.file.Paths
2420
import kotlin.time.Duration.Companion.minutes
25-
import kotlin.time.Duration.Companion.seconds
2621

2722
@Tag("ui")
2823
@TestInstance(TestInstance.Lifecycle.PER_METHOD)
@@ -87,7 +82,7 @@ class MyProjectUITest {
8782
println("Test project will be created as: $testProjectName")
8883
run = Setup.setupTestContextIC("MyProjectUITest").runIdeWithDriver()
8984

90-
newProjectWelcomeScreen()
85+
newProjectWelcomeScreen(run, testProjectName)
9186
newProjectInProjectView()
9287
}
9388

@@ -98,7 +93,7 @@ class MyProjectUITest {
9893
println("Test project will be created as: $testProjectName")
9994
run = Setup.setupTestContextUE("MyProjectUITest").runIdeWithDriver()
10095

101-
newProjectWelcomeScreen()
96+
newProjectWelcomeScreen(run, testProjectName)
10297
run.driver.withContext {
10398
ideFrame {
10499
// Wait for the ideFrame to appear before attempting to interact with it.
@@ -115,58 +110,10 @@ class MyProjectUITest {
115110
println("Test project will be created as: $testProjectName")
116111
run = Setup.setupTestContextWS("MyProjectUITest").runIdeWithDriver()
117112

118-
newProjectWelcomeScreen()
113+
newProjectWelcomeScreen(run, testProjectName)
119114
newProjectInProjectView()
120115
}
121116

122-
123-
/**
124-
* Automates the process of creating a new Flutter project from the welcome screen.
125-
* <p>
126-
* This function navigates the "New Project" dialog, selects the Flutter project type,
127-
* and enters a unique project name. It relies on the {@code FLUTTER_SDK} environment
128-
* variable to be set for the test to proceed.
129-
*/
130-
fun newProjectWelcomeScreen() {
131-
run.driver.withContext {
132-
// Assert that the welcome screen is visible before interacting with it.
133-
welcomeScreen {
134-
assert(isVisible())
135-
println("Creating the new project from Welcome Screen")
136-
createNewProjectButton.click()
137-
138-
// The test expects the `FlutterGeneratorPeer` to automatically populate the
139-
// Flutter SDK path. This behavior relies on the FLUTTER_SDK environment
140-
// variable being set.
141-
//
142-
// If the FLUTTER_SDK variable is not present, the UI will not find the SDK,
143-
// and the 'Next' button will remain disabled, causing the test to fail.
144-
// A common reason for this failure is an unconfigured test environment.
145-
146-
newProjectDialog {
147-
// Wait for the dialog to fully load
148-
wait(1.seconds)
149-
150-
// Select project type - adjust based on your needs
151-
chooseProjectType("Flutter")
152-
wait(1.seconds)
153-
154-
// Expect setup to take care of setting the correct Flutter SDK
155-
if (!nextButton.isEnabled()) {
156-
fail { "The FLUTTER_SDK environment variable was not set." }
157-
}
158-
nextButton.click()
159-
wait(1.seconds)
160-
161-
keyboard {
162-
typeText(testProjectName)
163-
}
164-
createButton.click()
165-
}
166-
}
167-
}
168-
}
169-
170117
/**
171118
* Verifies the successful creation of a new project by asserting the presence
172119
* and structure of files in the project view.
@@ -226,47 +173,3 @@ class MyProjectUITest {
226173
}
227174
}
228175
}
229-
230-
//
231-
// TODO(jwren) move this into a utility for project creation tasks
232-
//
233-
234-
// A Kotlin extension function for the `Finder` class.
235-
// This function adds a new method, `newProjectDialog`, that can be
236-
// called on any `Finder` object.
237-
fun Finder.newProjectDialog(action: NewProjectDialogUI.() -> Unit) {
238-
// Locates the "New Project" dialog.
239-
// - `x(...)` creates an XPath-like query to find the UI component.
240-
// - The query targets a `div` with a `title` of "New Project".
241-
// - `NewProjectDialogUI::class.java` specifies that the found component
242-
// should be treated as an instance of the `NewProjectDialogUI` class,
243-
// allowing access to its properties and functions.
244-
//
245-
// The found dialog component is then passed to the `action` lambda,
246-
// which contains the test steps to perform within the dialog.
247-
x("//div[@title='New Project']", NewProjectDialogUI::class.java).action()
248-
}
249-
250-
// A UI component representing the "New Project" dialog.
251-
// This class provides a structured way to interact with the dialog's elements
252-
// using the IntelliJ Driver SDK.
253-
open class NewProjectDialogUI(data: ComponentData) : UiComponent(data) {
254-
255-
// Clicks on the specified project type from the list.
256-
// The function waits until the text is found before performing the click action.
257-
fun chooseProjectType(projectType: String) {
258-
projectTypeList.waitOneText(projectType).click()
259-
}
260-
261-
// Locates the list of project types within the dialog.
262-
// The xQuery targets a component with the specific class "JBList".
263-
private val projectTypeList = x("//div[@class='JBList']")
264-
265-
// Locates the "Next" button in the dialog.
266-
// The xQuery finds a button component with the visible text "Next".
267-
val nextButton = x("//div[@text='Next']")
268-
269-
// Locates the "Create" button in the dialog.
270-
// The xQuery finds a button component with the visible text "Create".
271-
val createButton = x("//div[@text='Create']")
272-
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2025 The Chromium Authors. All rights reserved.
3+
* Use of this source code is governed by a BSD-style license that can be
4+
* found in the LICENSE file.
5+
*/
6+
7+
package io.flutter.integrationTest
8+
9+
import com.intellij.ide.starter.driver.engine.BackgroundRun
10+
import com.intellij.ide.starter.driver.engine.runIdeWithDriver
11+
import com.intellij.ide.starter.junit5.config.UseLatestDownloadedIdeBuild
12+
import io.flutter.integrationTest.utils.newProjectWelcomeScreen
13+
import org.junit.jupiter.api.*
14+
import org.junit.jupiter.api.extension.ExtendWith
15+
import java.nio.file.Paths
16+
17+
@Tag("ui")
18+
@TestInstance(TestInstance.Lifecycle.PER_METHOD)
19+
@ExtendWith(UseLatestDownloadedIdeBuild::class)
20+
class PreferencePagesUITest {
21+
22+
companion object {
23+
// Generate a unique folder name for the test project to avoid conflicts
24+
var testProjectName = "my_test_project_${System.currentTimeMillis()}"
25+
26+
/**
27+
* Cleanup method that runs after all tests in this class.
28+
* Removes the test project folder created during testing to keep the system clean.
29+
*/
30+
@JvmStatic
31+
@AfterAll
32+
fun cleanUpTestFolder() {
33+
val projectPath = Paths.get(System.getProperty("user.home"), "IdeaProjects", testProjectName)
34+
val projectFile = projectPath.toFile()
35+
if (projectFile.exists()) {
36+
projectFile.deleteRecursively()
37+
println("Successfully deleted test folder: $projectPath")
38+
} else {
39+
println("Test folder does not exist, skipping cleanup: $projectPath")
40+
}
41+
}
42+
}
43+
44+
/**
45+
* The IDE instance running in the background.
46+
* Initialized in @BeforeEach and closed in @AfterEach.
47+
*/
48+
private lateinit var run: BackgroundRun
49+
50+
/**
51+
* TODO document
52+
*/
53+
@BeforeEach
54+
fun initContext() {
55+
println("Initializing IDE test context")
56+
println("Test project will be created as: $testProjectName")
57+
// TODO consider creating from github as a source instead: GitHubProject.fromGithub()
58+
run = Setup.setupTestContextIC("MyProjectUITest").runIdeWithDriver()
59+
newProjectWelcomeScreen(run, testProjectName)
60+
}
61+
62+
/**
63+
* Tears down the test environment after each test method.
64+
*
65+
* Safely closes the IDE instance if it was successfully started.
66+
* The initialization check prevents errors if the setup failed.
67+
*/
68+
@AfterEach
69+
fun closeIde() {
70+
if (::run.isInitialized) {
71+
println("Closing IDE")
72+
run.closeIdeAndWait()
73+
} else {
74+
println("IDE was not started, skipping close")
75+
}
76+
}
77+
78+
@Test
79+
fun newProjectIC() {
80+
// TODO work in progress here
81+
}
82+
}
83+
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright 2025 The Chromium Authors. All rights reserved.
3+
* Use of this source code is governed by a BSD-style license that can be
4+
* found in the LICENSE file.
5+
*/
6+
7+
package io.flutter.integrationTest.utils
8+
9+
import com.intellij.driver.sdk.ui.Finder
10+
import com.intellij.driver.sdk.ui.components.ComponentData
11+
import com.intellij.driver.sdk.ui.components.UiComponent
12+
import com.intellij.driver.sdk.ui.components.common.welcomeScreen
13+
import com.intellij.driver.sdk.wait
14+
import com.intellij.ide.starter.driver.engine.BackgroundRun
15+
import org.junit.jupiter.api.fail
16+
import kotlin.time.Duration.Companion.seconds
17+
18+
// A Kotlin extension function for the `Finder` class.
19+
// This function adds a new method, `newProjectDialog`, that can be
20+
// called on any `Finder` object.
21+
fun Finder.newProjectDialog(action: NewProjectDialogUI.() -> Unit) {
22+
// Locates the "New Project" dialog.
23+
// - `x(...)` creates an XPath-like query to find the UI component.
24+
// - The query targets a `div` with a `title` of "New Project".
25+
// - `NewProjectDialogUI::class.java` specifies that the found component
26+
// should be treated as an instance of the `NewProjectDialogUI` class,
27+
// allowing access to its properties and functions.
28+
//
29+
// The found dialog component is then passed to the `action` lambda,
30+
// which contains the test steps to perform within the dialog.
31+
x("//div[@title='New Project']", NewProjectDialogUI::class.java).action()
32+
}
33+
34+
// A UI component representing the "New Project" dialog.
35+
// This class provides a structured way to interact with the dialog's elements
36+
// using the IntelliJ Driver SDK.
37+
open class NewProjectDialogUI(data: ComponentData) : UiComponent(data) {
38+
39+
// Clicks on the specified project type from the list.
40+
// The function waits until the text is found before performing the click action.
41+
fun chooseProjectType(projectType: String) {
42+
projectTypeList.waitOneText(projectType).click()
43+
}
44+
45+
// Locates the list of project types within the dialog.
46+
// The xQuery targets a component with the specific class "JBList".
47+
private val projectTypeList = x("//div[@class='JBList']")
48+
49+
// Locates the "Next" button in the dialog.
50+
// The xQuery finds a button component with the visible text "Next".
51+
val nextButton = x("//div[@text='Next']")
52+
53+
// Locates the "Create" button in the dialog.
54+
// The xQuery finds a button component with the visible text "Create".
55+
val createButton = x("//div[@text='Create']")
56+
}
57+
58+
/**
59+
* Automates the process of creating a new Flutter project from the welcome screen.
60+
* <p>
61+
* This function navigates the "New Project" dialog, selects the Flutter project type,
62+
* and enters a unique project name. It relies on the {@code FLUTTER_SDK} environment
63+
* variable to be set for the test to proceed.
64+
*/
65+
fun newProjectWelcomeScreen(run: BackgroundRun, testProjectName: String) {
66+
run.driver.withContext {
67+
// Assert that the welcome screen is visible before interacting with it.
68+
welcomeScreen {
69+
assert(isVisible())
70+
println("Creating the new project from Welcome Screen")
71+
createNewProjectButton.click()
72+
73+
// The test expects the `FlutterGeneratorPeer` to automatically populate the
74+
// Flutter SDK path. This behavior relies on the FLUTTER_SDK environment
75+
// variable being set.
76+
//
77+
// If the FLUTTER_SDK variable is not present, the UI will not find the SDK,
78+
// and the 'Next' button will remain disabled, causing the test to fail.
79+
// A common reason for this failure is an unconfigured test environment.
80+
81+
newProjectDialog {
82+
// Wait for the dialog to fully load
83+
wait(1.seconds)
84+
85+
// Select project type - adjust based on your needs
86+
chooseProjectType("Flutter")
87+
wait(1.seconds)
88+
89+
// Expect setup to take care of setting the correct Flutter SDK
90+
if (!nextButton.isEnabled()) {
91+
fail { "The FLUTTER_SDK environment variable was not set." }
92+
}
93+
nextButton.click()
94+
wait(1.seconds)
95+
96+
keyboard {
97+
typeText(testProjectName)
98+
}
99+
createButton.click()
100+
}
101+
}
102+
}
103+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /