diff --git a/.github/workflows/runUiOctopusTests.yml b/.github/workflows/runUiOctopusTests.yml
index 7d7a9f23f..83bfb3bd8 100644
--- a/.github/workflows/runUiOctopusTests.yml
+++ b/.github/workflows/runUiOctopusTests.yml
@@ -11,12 +11,12 @@ jobs:
       - uses: actions/checkout@v4
       - name: Apply Patch
         run: |
-          git apply src/test/java/ui/octopus.patch
+          git apply tests/ij-ui-tests/src/test/kotlin/ui/octopus.patch
       - name: Setup Java
         uses: actions/setup-java@v4
         with:
           distribution: zulu
-          java-version: 11
+          java-version: 17
       - name: Setup FFmpeg
         uses: FedericoCarboni/setup-ffmpeg@v3
         with:
@@ -30,7 +30,7 @@ jobs:
       - name: Run Idea
         run: |
           mkdir -p build/reports
-          gradle :runIdeForUiTests > build/reports/idea.log &
+          gradle :tests:ij-ui-tests:runIdeForUiTests > build/reports/idea.log &
       - name: Wait for Idea started
         uses: jtalk/url-health-check-action@v3
         with:
@@ -38,7 +38,7 @@ jobs:
           max-attempts: 20
           retry-delay: 10s
       - name: Tests
-        run: gradle :testUi
+        run: gradle :tests:ij-ui-tests:testUi
       - name: Move video
         if: always()
         run: mv video build/reports
diff --git a/.github/workflows/runUiTests.yml b/.github/workflows/runUiTests.yml
index 3e84662ca..943a1873c 100644
--- a/.github/workflows/runUiTests.yml
+++ b/.github/workflows/runUiTests.yml
@@ -13,7 +13,7 @@ jobs:
         uses: actions/setup-java@v4
         with:
           distribution: zulu
-          java-version: 11
+          java-version: 17
       - name: Setup FFmpeg
         uses: FedericoCarboni/setup-ffmpeg@v3
         with:
@@ -27,7 +27,7 @@ jobs:
       - name: Run Idea
         run: |
           mkdir -p build/reports
-          gradle :runIdeForUiTests > build/reports/idea.log &
+          gradle :tests:ij-ui-tests:runIdeForUiTests > build/reports/idea.log &
       - name: Wait for Idea started
         uses: jtalk/url-health-check-action@v3
         with:
@@ -35,7 +35,7 @@ jobs:
           max-attempts: 20
           retry-delay: 10s
       - name: Tests
-        run: gradle :testUi
+        run: gradle :tests:ij-ui-tests:testUi
       - name: Move video
         if: always()
         run: mv video build/reports
diff --git a/build.gradle.kts b/build.gradle.kts
index 9f90984b6..39dee845f 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -101,7 +101,6 @@ val ideaVersion: String by project
 val ideaType: String by project
 val downloadIdeaSources: String by project
 val instrumentPluginCode: String by project
-val remoteRobotVersion: String by project
 val antlrVersion: String by project
 
 val publishChannels: String by project
@@ -144,11 +143,6 @@ dependencies {
   // https://mvnrepository.com/artifact/org.mockito.kotlin/mockito-kotlin
   testImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1")
 
-  testImplementation("com.intellij.remoterobot:remote-robot:$remoteRobotVersion")
-  testImplementation("com.intellij.remoterobot:remote-fixtures:$remoteRobotVersion")
-  testImplementation("com.intellij.remoterobot:ide-launcher:$remoteRobotVersion")
-  testImplementation("com.automation-remarks:video-recorder-junit5:2.0")
-
   testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.1")
   testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.1")
   testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.1")
@@ -244,10 +238,6 @@ intellij {
 }
 
 tasks {
-  downloadRobotServerPlugin {
-    version.set(remoteRobotVersion)
-  }
-
   publishPlugin {
     channels.set(publishChannels.split(","))
     token.set(publishToken)
@@ -259,14 +249,6 @@ tasks {
     password.set(providers.environmentVariable("PRIVATE_KEY_PASSWORD"))
   }
 
-  runIdeForUiTests {
-    systemProperty("robot-server.port", "8082")
-    systemProperty("ide.mac.message.dialogs.as.sheets", "false")
-    systemProperty("jb.privacy.policy.text", "<!--999.999-->")
-    systemProperty("jb.consents.confirmation.enabled", "false")
-    systemProperty("ide.show.tips.on.startup.default.value", "false")
-  }
-
   runPluginVerifier {
     downloadDir.set("${project.buildDir}/pluginVerifier/ides")
     teamCityOutputFormat.set(true)
@@ -348,12 +330,6 @@ tasks {
   }
 }
 
-tasks.register<Test>("testUi") {
-  group = "verification"
-  useJUnitPlatform()
-  include("/ui/**")
-}
-
 // --- Changelog
 
 changelog {
@@ -372,13 +348,6 @@ koverMerged {
   enable()
 }
 
-kover {
-  instrumentation {
-    // set of test tasks names to exclude from instrumentation. The results of their execution will not be presented in the report
-    excludeTasks += "testUi"
-  }
-}
-
 // --- Slack notification
 
 tasks.register("slackNotification") {
diff --git a/settings.gradle b/settings.gradle
index ccc0025f4..c09ac7231 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -15,3 +15,4 @@ include 'annotation-processors'
 include 'tests:java-tests'
 include 'tests:property-tests'
 include 'tests:long-running-tests'
+include 'tests:ij-ui-tests'
diff --git a/tests/ij-ui-tests/build.gradle.kts b/tests/ij-ui-tests/build.gradle.kts
new file mode 100644
index 000000000..ac8950e28
--- /dev/null
+++ b/tests/ij-ui-tests/build.gradle.kts
@@ -0,0 +1,74 @@
+plugins {
+  java
+  kotlin("jvm")
+  id("org.jetbrains.intellij")
+}
+
+group = "org.example"
+version = "SNAPSHOT"
+
+repositories {
+  mavenCentral()
+  maven { url = uri("https://cache-redirector.jetbrains.com/intellij-dependencies") }
+}
+
+val kotlinVersion: String by project
+val ideaVersion: String by project
+val javaVersion: String by project
+val remoteRobotVersion: String by project
+
+dependencies {
+  testImplementation("org.junit.jupiter:junit-jupiter")
+  compileOnly("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
+  testImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
+  testImplementation(testFixtures(project(":"))) // The root project
+
+  testImplementation("com.intellij.remoterobot:remote-robot:$remoteRobotVersion")
+  testImplementation("com.intellij.remoterobot:remote-fixtures:$remoteRobotVersion")
+  testImplementation("com.intellij.remoterobot:ide-launcher:$remoteRobotVersion")
+  testImplementation("com.automation-remarks:video-recorder-junit5:2.0")
+}
+
+tasks {
+  // This task is disabled because it should be excluded from `gradle test` run (because it's slow)
+  // I didn't find a better way to exclude except disabling and defining a new task with a different name
+  test {
+    useJUnitPlatform()
+    enabled = false
+  }
+
+  register<Test>("testUi") {
+    group = "verification"
+    useJUnitPlatform()
+  }
+
+  downloadRobotServerPlugin {
+    version.set(remoteRobotVersion)
+  }
+
+  runIdeForUiTests {
+    systemProperty("robot-server.port", "8082")
+    systemProperty("ide.mac.message.dialogs.as.sheets", "false")
+    systemProperty("jb.privacy.policy.text", "<!--999.999-->")
+    systemProperty("jb.consents.confirmation.enabled", "false")
+    systemProperty("ide.show.tips.on.startup.default.value", "false")
+  }
+}
+
+intellij {
+  version.set(ideaVersion)
+  type.set("IC")
+  plugins.set(listOf("java"))
+}
+
+java {
+  toolchain {
+    languageVersion.set(JavaLanguageVersion.of(javaVersion))
+  }
+}
+
+kotlin {
+  jvmToolchain {
+    languageVersion.set(JavaLanguageVersion.of(javaVersion))
+  }
+}
diff --git a/src/test/java/ManualTests.md b/tests/ij-ui-tests/src/test/kotlin/ManualTests.md
similarity index 100%
rename from src/test/java/ManualTests.md
rename to tests/ij-ui-tests/src/test/kotlin/ManualTests.md
diff --git a/src/test/java/ui/PyCharmTest.kt b/tests/ij-ui-tests/src/test/kotlin/ui/PyCharmTest.kt
similarity index 100%
rename from src/test/java/ui/PyCharmTest.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/PyCharmTest.kt
diff --git a/src/test/java/ui/UiTests.kt b/tests/ij-ui-tests/src/test/kotlin/ui/UiTests.kt
similarity index 99%
rename from src/test/java/ui/UiTests.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/UiTests.kt
index 0115c24da..b6d8583e2 100644
--- a/src/test/java/ui/UiTests.kt
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/UiTests.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/octopus.patch b/tests/ij-ui-tests/src/test/kotlin/ui/octopus.patch
similarity index 100%
rename from src/test/java/ui/octopus.patch
rename to tests/ij-ui-tests/src/test/kotlin/ui/octopus.patch
diff --git a/src/test/java/ui/pages/ActionLinkFixture.java b/tests/ij-ui-tests/src/test/kotlin/ui/pages/ActionLinkFixture.java
similarity index 100%
rename from src/test/java/ui/pages/ActionLinkFixture.java
rename to tests/ij-ui-tests/src/test/kotlin/ui/pages/ActionLinkFixture.java
diff --git a/src/test/java/ui/pages/ActionMenuFixture.kt b/tests/ij-ui-tests/src/test/kotlin/ui/pages/ActionMenuFixture.kt
similarity index 97%
rename from src/test/java/ui/pages/ActionMenuFixture.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/pages/ActionMenuFixture.kt
index ab4304748..db73d2540 100644
--- a/src/test/java/ui/pages/ActionMenuFixture.kt
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/pages/ActionMenuFixture.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/pages/DialogFixture.kt b/tests/ij-ui-tests/src/test/kotlin/ui/pages/DialogFixture.kt
similarity index 96%
rename from src/test/java/ui/pages/DialogFixture.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/pages/DialogFixture.kt
index eee2dfe83..968a8e977 100644
--- a/src/test/java/ui/pages/DialogFixture.kt
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/pages/DialogFixture.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/pages/Editor.kt b/tests/ij-ui-tests/src/test/kotlin/ui/pages/Editor.kt
similarity index 98%
rename from src/test/java/ui/pages/Editor.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/pages/Editor.kt
index f2d86d306..e590fc7ff 100644
--- a/src/test/java/ui/pages/Editor.kt
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/pages/Editor.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/pages/Gutter.kt b/tests/ij-ui-tests/src/test/kotlin/ui/pages/Gutter.kt
similarity index 95%
rename from src/test/java/ui/pages/Gutter.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/pages/Gutter.kt
index 09c85dcb6..2f012dc9a 100644
--- a/src/test/java/ui/pages/Gutter.kt
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/pages/Gutter.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/pages/IdeaFrame.kt b/tests/ij-ui-tests/src/test/kotlin/ui/pages/IdeaFrame.kt
similarity index 97%
rename from src/test/java/ui/pages/IdeaFrame.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/pages/IdeaFrame.kt
index 139709865..118ba1067 100644
--- a/src/test/java/ui/pages/IdeaFrame.kt
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/pages/IdeaFrame.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/pages/SearchEverywhere.kt b/tests/ij-ui-tests/src/test/kotlin/ui/pages/SearchEverywhere.kt
similarity index 100%
rename from src/test/java/ui/pages/SearchEverywhere.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/pages/SearchEverywhere.kt
diff --git a/src/test/java/ui/pages/WelcomeFrame.kt b/tests/ij-ui-tests/src/test/kotlin/ui/pages/WelcomeFrame.kt
similarity index 97%
rename from src/test/java/ui/pages/WelcomeFrame.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/pages/WelcomeFrame.kt
index 162a4e939..9dc1b33bb 100644
--- a/src/test/java/ui/pages/WelcomeFrame.kt
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/pages/WelcomeFrame.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/pages/WelcomeFrameFixture.java b/tests/ij-ui-tests/src/test/kotlin/ui/pages/WelcomeFrameFixture.java
similarity index 97%
rename from src/test/java/ui/pages/WelcomeFrameFixture.java
rename to tests/ij-ui-tests/src/test/kotlin/ui/pages/WelcomeFrameFixture.java
index aeedf6c2d..c4bc88021 100644
--- a/src/test/java/ui/pages/WelcomeFrameFixture.java
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/pages/WelcomeFrameFixture.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/utils/JavaExampleSteps.kt b/tests/ij-ui-tests/src/test/kotlin/ui/utils/JavaExampleSteps.kt
similarity index 97%
rename from src/test/java/ui/utils/JavaExampleSteps.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/utils/JavaExampleSteps.kt
index fb04976c6..7b79316af 100644
--- a/src/test/java/ui/utils/JavaExampleSteps.kt
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/utils/JavaExampleSteps.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/utils/StepsLogger.kt b/tests/ij-ui-tests/src/test/kotlin/ui/utils/StepsLogger.kt
similarity index 92%
rename from src/test/java/ui/utils/StepsLogger.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/utils/StepsLogger.kt
index 6f185b1a5..7077dc528 100644
--- a/src/test/java/ui/utils/StepsLogger.kt
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/utils/StepsLogger.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/utils/UiTestWrapper.kt b/tests/ij-ui-tests/src/test/kotlin/ui/utils/UiTestWrapper.kt
similarity index 97%
rename from src/test/java/ui/utils/UiTestWrapper.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/utils/UiTestWrapper.kt
index 72f96bba4..092e7d8a6 100644
--- a/src/test/java/ui/utils/UiTestWrapper.kt
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/utils/UiTestWrapper.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/utils/Utils.kt b/tests/ij-ui-tests/src/test/kotlin/ui/utils/Utils.kt
similarity index 98%
rename from src/test/java/ui/utils/Utils.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/utils/Utils.kt
index 6d002e667..8d4f3c061 100644
--- a/src/test/java/ui/utils/Utils.kt
+++ b/tests/ij-ui-tests/src/test/kotlin/ui/utils/Utils.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2023 The IdeaVim authors
+ * Copyright 2003-2024 The IdeaVim authors
  *
  * Use of this source code is governed by an MIT-style
  * license that can be found in the LICENSE.txt file or at
diff --git a/src/test/java/ui/utils/VimActions.kt b/tests/ij-ui-tests/src/test/kotlin/ui/utils/VimActions.kt
similarity index 100%
rename from src/test/java/ui/utils/VimActions.kt
rename to tests/ij-ui-tests/src/test/kotlin/ui/utils/VimActions.kt