diff --git a/.github/workflows/pr_checks.yaml b/.github/workflows/pr_checks.yaml index e5f44c03e3..c41c57f72b 100644 --- a/.github/workflows/pr_checks.yaml +++ b/.github/workflows/pr_checks.yaml @@ -96,7 +96,7 @@ jobs: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} install-gui: - needs: [install-root, install-core] + needs: [ install-root, install-core ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -157,7 +157,7 @@ jobs: npx tsc --noEmit binary-checks: - needs: [install-root, install-core] + needs: [ install-root, install-core ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -193,7 +193,7 @@ jobs: npx tsc --noEmit install-vscode: - needs: [install-root, install-core] + needs: [ install-root, install-core ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -277,7 +277,7 @@ jobs: vscode-get-test-file-matrix: runs-on: ubuntu-latest - needs: [install-root, install-vscode] + needs: [ install-root, install-vscode ] outputs: test_file_matrix: ${{ steps.vscode-get-test-file-matrix.outputs.test_file_matrix }} steps: @@ -306,7 +306,7 @@ jobs: vscode-package-extension: runs-on: ubuntu-latest - needs: [install-vscode, install-core] + needs: [ install-vscode, install-core ] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -338,7 +338,7 @@ jobs: vscode-download-e2e-dependencies: runs-on: ubuntu-latest - needs: [install-vscode, install-core] + needs: [ install-vscode, install-core ] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -445,7 +445,7 @@ jobs: path: extensions/vscode/e2e/storage/screenshots gui-tests: - needs: [install-gui, install-core] + needs: [ install-gui, install-core ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -476,7 +476,7 @@ jobs: npm test jetbrains-tests: - needs: [install-root, install-core] + needs: [ install-root, core-checks ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -573,3 +573,5 @@ jobs: name: jb-failure-report path: | ${{ github.workspace }}/extensions/intellij/build/reports + + diff --git a/core/protocol/passThrough.ts b/core/protocol/passThrough.ts index 756b3db54e..c4b999521d 100644 --- a/core/protocol/passThrough.ts +++ b/core/protocol/passThrough.ts @@ -61,6 +61,8 @@ export const WEBVIEW_TO_CORE_PASS_THROUGH: (keyof ToCoreFromWebviewProtocol)[] = ]; // Message types to pass through from core to webview +// Note: If updating these values, make a corresponding update in +// extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/constants/MessageTypes.kt export const CORE_TO_WEBVIEW_PASS_THROUGH: (keyof ToWebviewFromCoreProtocol)[] = [ "configUpdate", diff --git a/extensions/intellij/.gitignore b/extensions/intellij/.gitignore index ac787e9369..2be56cfd9e 100644 --- a/extensions/intellij/.gitignore +++ b/extensions/intellij/.gitignore @@ -3,4 +3,6 @@ src/main/resources/webview src/main/resources/bin src/main/resources/config_schema.json src/main/resources/continue_rc_schema.json -video \ No newline at end of file +video +src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/test-continue/* +!src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/test-continue/config.json \ No newline at end of file diff --git a/extensions/intellij/.run/Run IDE for UI Tests.run.xml b/extensions/intellij/.run/Run IDE for UI Tests.run.xml deleted file mode 100644 index 5f7eb46c85..0000000000 --- a/extensions/intellij/.run/Run IDE for UI Tests.run.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/extensions/intellij/.run/Run Test IDE.run.xml b/extensions/intellij/.run/Run Test IDE.run.xml new file mode 100644 index 0000000000..80a2a251f8 --- /dev/null +++ b/extensions/intellij/.run/Run Test IDE.run.xml @@ -0,0 +1,27 @@ + + + + + + + true + true + false + false + + + + \ No newline at end of file diff --git a/extensions/intellij/.run/Run Tests.run.xml b/extensions/intellij/.run/Run Tests.run.xml new file mode 100644 index 0000000000..bdff34d6dd --- /dev/null +++ b/extensions/intellij/.run/Run Tests.run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/extensions/intellij/.run/Run e2e tests.run.xml b/extensions/intellij/.run/Run e2e tests.run.xml new file mode 100644 index 0000000000..2280aece02 --- /dev/null +++ b/extensions/intellij/.run/Run e2e tests.run.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/extensions/intellij/CONTRIBUTING.md b/extensions/intellij/CONTRIBUTING.md index d37aaa2c46..836eaa7b62 100644 --- a/extensions/intellij/CONTRIBUTING.md +++ b/extensions/intellij/CONTRIBUTING.md @@ -101,7 +101,9 @@ toolbar. _Run | Debugging Actions | Reload Changed Classes`_ - This will often fail on new imports, schema changes etc. In that case, you need to stop and restart the extension - `gui`: Changes will be reloaded automatically -- `core`: Run `npm run build` from the `binary` directory (requires restarting the `Start Core Dev Server` task) +- `core`: Run `npm run build -- --os [darwin | linux | win32]` from the `binary` directory (requires + restarting the + `Start Core Dev Server` task) ### Setting breakpoints diff --git a/extensions/intellij/build.gradle.kts b/extensions/intellij/build.gradle.kts index 25d2fb361c..ee7dce8bea 100644 --- a/extensions/intellij/build.gradle.kts +++ b/extensions/intellij/build.gradle.kts @@ -130,7 +130,10 @@ tasks { // Configure UI tests plugin // Read more: https://github.com/JetBrains/intellij-ui-test-robot runIdeForUiTests { - environment("CONTINUE_GLOBAL_DIR", "src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/test-continue") + environment( + "CONTINUE_GLOBAL_DIR", + "${rootProject.projectDir}/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/test-continue" + ) systemProperty("robot-server.port", "8082") systemProperty("ide.mac.message.dialogs.as.sheets", "false") systemProperty("jb.privacy.policy.text", "") @@ -141,6 +144,7 @@ tasks { systemProperty("idea.trust.all.projects", "true") systemProperty("ide.show.tips.on.startup.default.value", "false") systemProperty("ide.browser.jcef.jsQueryPoolSize", "10000") + systemProperty("ide.browser.jcef.contextMenu.devTools.enabled", "true") // This is to ensure we load the GUI with OSR enabled. We have logic that // renders with OSR disabled below a particular IDE version. @@ -180,6 +184,5 @@ tasks { test { useJUnitPlatform() - environment("CONTINUE_GLOBAL_DIR", "src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/test-continue") } } diff --git a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/autocomplete/AutocompleteService.kt b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/autocomplete/AutocompleteService.kt index 2dc6ba021d..b6eaeacbf5 100644 --- a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/autocomplete/AutocompleteService.kt +++ b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/autocomplete/AutocompleteService.kt @@ -294,12 +294,13 @@ class AutocompleteService(private val project: Project) { } private fun isInjectedFile(editor: Editor): Boolean { - val psiFile = runReadAction { PsiDocumentManager.getInstance(project).getPsiFile(editor.document) } - if (psiFile == null) { - return false - } - val response = runReadAction { psiFile.isInjectedText() } - return response + return ApplicationManager.getApplication().executeOnPooledThread { + ApplicationManager.getApplication().runReadAction { + val psiFile = + PsiDocumentManager.getInstance(project).getPsiFile(editor.document) ?: return@runReadAction false + return@runReadAction psiFile.isInjectedText() + } + }.get() } fun hideCompletions(editor: Editor) { diff --git a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/constants/MessageTypes.kt b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/constants/MessageTypes.kt index b309cbbc68..585dd716f0 100644 --- a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/constants/MessageTypes.kt +++ b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/constants/MessageTypes.kt @@ -50,13 +50,78 @@ class MessageTypes { "showToast", ) + // Note: If updating these values, make a corresponding update in + // core/protocol/passThrough.ts val PASS_THROUGH_TO_WEBVIEW = listOf( "configUpdate", "getDefaultModelTitle", - "indexProgress", + "indexProgress", // Codebase + "indexing/statusUpdate", // Docs, etc. + "addContextItem", "refreshSubmenuItems", + "isContinueInputFocused", "didChangeAvailableProfiles", - "addContextItem" + "setTTSActive", + "getWebviewHistoryLength", + "getCurrentSessionId", + "signInToControlPlane", + "openDialogMessage", + "docs/suggestions", + ) + + // Note: If updating these values, make a corresponding update in + // core/protocol/passThrough.ts + val PASS_THROUGH_TO_CORE = listOf( + "abort", + "history/list", + "history/delete", + "history/load", + "history/save", + "devdata/log", + "config/addModel", + "config/addContextProvider", + "config/newPromptFile", + "config/ideSettingsUpdate", + "config/getSerializedProfileInfo", + "config/deleteModel", + "config/listProfiles", + "config/openProfile", + "context/getContextItems", + "context/getSymbolsForFiles", + "context/loadSubmenuItems", + "context/addDocs", + "context/removeDocs", + "context/indexDocs", + "autocomplete/complete", + "autocomplete/cancel", + "autocomplete/accept", + "command/run", + "tts/kill", + "llm/complete", + "llm/streamComplete", + "llm/streamChat", + "llm/listModels", + "streamDiffLines", + "chatDescriber/describe", + "stats/getTokensPerDay", + "stats/getTokensPerModel", + // Codebase + "index/setPaused", + "index/forceReIndex", + "index/forceReIndexFiles", + "index/indexingProgressBarInitialized", + // Docs, etc. + "indexing/reindex", + "indexing/abort", + "indexing/setPaused", + "docs/getSuggestedDocs", + "docs/initStatuses", + // + "completeOnboarding", + "addAutocompleteModel", + "profiles/switch", + "didChangeSelectedProfile", + "tools/call", ) } } \ No newline at end of file diff --git a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/toolWindow/ContinueBrowser.kt b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/toolWindow/ContinueBrowser.kt index 5523bdeffc..b43cf62c98 100644 --- a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/toolWindow/ContinueBrowser.kt +++ b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/toolWindow/ContinueBrowser.kt @@ -2,6 +2,7 @@ package com.github.continuedev.continueintellijextension.toolWindow import com.github.continuedev.continueintellijextension.activities.ContinuePluginDisposable import com.github.continuedev.continueintellijextension.constants.MessageTypes +import com.github.continuedev.continueintellijextension.constants.MessageTypes.Companion.PASS_THROUGH_TO_CORE import com.github.continuedev.continueintellijextension.factories.CustomSchemeHandlerFactory import com.github.continuedev.continueintellijextension.services.ContinueExtensionSettings import com.github.continuedev.continueintellijextension.services.ContinuePluginService @@ -18,58 +19,6 @@ import org.cef.browser.CefBrowser import org.cef.handler.CefLoadHandlerAdapter class ContinueBrowser(val project: Project, url: String) { - private val PASS_THROUGH_TO_CORE = listOf( - "abort", - "history/list", - "history/delete", - "history/load", - "history/save", - "devdata/log", - "config/addModel", - "config/addContextProvider", - "config/newPromptFile", - "config/ideSettingsUpdate", - "config/getSerializedProfileInfo", - "config/deleteModel", - "config/listProfiles", - "config/openProfile", - "context/getContextItems", - "context/getSymbolsForFiles", - "context/loadSubmenuItems", - "context/addDocs", - "context/removeDocs", - "context/indexDocs", - "autocomplete/complete", - "autocomplete/cancel", - "autocomplete/accept", - "command/run", - "tts/kill", - "llm/complete", - "llm/streamComplete", - "llm/streamChat", - "llm/listModels", - "streamDiffLines", - "chatDescriber/describe", - "stats/getTokensPerDay", - "stats/getTokensPerModel", - // Codebase - "index/setPaused", - "index/forceReIndex", - "index/indexingProgressBarInitialized", - // Docs, etc. - "indexing/reindex", - "indexing/abort", - "indexing/setPaused", - "docs/getSuggestedDocs", - "docs/initStatuses", - // - "completeOnboarding", - "addAutocompleteModel", - "profiles/switch", - "didChangeSelectedProfile", - "tools/call", - ) - private fun registerAppSchemeHandler() { CefApp.getInstance().registerSchemeHandlerFactory( "http", @@ -82,13 +31,8 @@ class ContinueBrowser(val project: Project, url: String) { init { val isOSREnabled = ServiceManager.getService(ContinueExtensionSettings::class.java).continueState.enableOSR - this.browser = JBCefBrowser.createBuilder().setOffScreenRendering(isOSREnabled).build() - - browser.jbCefClient.setProperty( - JBCefClient.Properties.JS_QUERY_POOL_SIZE, - JS_QUERY_POOL_SIZE - ) + this.browser = JBCefBrowser.createBuilder().setOffScreenRendering(isOSREnabled).build() registerAppSchemeHandler() browser.loadURL(url); diff --git a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/Autocomplete.kt b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/Autocomplete.kt new file mode 100644 index 0000000000..fdb271639f --- /dev/null +++ b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/Autocomplete.kt @@ -0,0 +1,73 @@ +package com.github.continuedev.continueintellijextension.e2e + +import com.automation.remarks.junit5.Video +import com.github.continuedev.continueintellijextension.fixtures.dialog +import com.github.continuedev.continueintellijextension.fixtures.idea +import com.github.continuedev.continueintellijextension.fixtures.welcomeFrame +import com.github.continuedev.continueintellijextension.utils.RemoteRobotExtension +import com.github.continuedev.continueintellijextension.utils.StepsLogger +import com.intellij.remoterobot.RemoteRobot +import com.intellij.remoterobot.fixtures.ComponentFixture +import com.intellij.remoterobot.search.locators.byXpath +import com.intellij.remoterobot.steps.CommonSteps +import com.intellij.remoterobot.utils.keyboard +import com.intellij.remoterobot.utils.waitFor +import com.intellij.remoterobot.utils.waitForIgnoringError +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import java.time.Duration.ofMinutes +import java.time.Duration.ofSeconds + +@ExtendWith(RemoteRobotExtension::class) +class Autocomplete { + init { + StepsLogger.init() + } + + @BeforeEach + fun waitForIde(remoteRobot: RemoteRobot) { + waitForIgnoringError(ofMinutes(3)) { remoteRobot.callJs("true") } + } + + @AfterEach + fun closeProject(remoteRobot: RemoteRobot) = CommonSteps(remoteRobot).closeProject() + + // @Test + @Video + fun displayCompletion(remoteRobot: RemoteRobot): Unit = with(remoteRobot) { + welcomeFrame { + createNewProjectLink.click() + dialog("New Project") { + findText("Java").click() + checkBox("Add sample code").select() + button("Create").click() + } + } + + // Wait for the default "Main.java" tab to load + // Our "continue_tutorial.java.ft" tab loads first, but then "Main.java" takes focus. + waitFor(ofSeconds(20)) { + findAll( + byXpath("//div[@accessiblename='Main.java' and @class='EditorTabLabel']") + ).isNotEmpty() + } + + idea { + with(textEditor()) { + val userMsg = "TEST_USER_MESSAGE_0" + editor.insertTextAtLine(0, 0, userMsg) + editor.clickOnOffset(userMsg.length) + + keyboard { + enterText(" ") + } + + waitFor(ofSeconds(10)) { + editor.hasText("TEST_LLM_RESPONSE_0") + } + } + } + } +} \ No newline at end of file diff --git a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/GUI.kt b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/GUI.kt new file mode 100644 index 0000000000..5672debba5 --- /dev/null +++ b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/GUI.kt @@ -0,0 +1,96 @@ +/** + * Currently we can't test any actions in the GUI that involve clicks. + * See this open issue for details: https://github.com/JetBrains/intellij-ui-test-robot/issues/491 + */ +package com.github.continuedev.continueintellijextension.e2e + +import com.automation.remarks.junit5.Video +import com.github.continuedev.continueintellijextension.fixtures.* +import com.github.continuedev.continueintellijextension.utils.RemoteRobotExtension +import com.github.continuedev.continueintellijextension.utils.StepsLogger +import com.github.continuedev.continueintellijextension.utils.getMetaKey +import com.intellij.remoterobot.RemoteRobot +import com.intellij.remoterobot.fixtures.ComponentFixture +import com.intellij.remoterobot.search.locators.byXpath +import com.intellij.remoterobot.steps.CommonSteps +import com.intellij.remoterobot.stepsProcessing.step +import com.intellij.remoterobot.utils.keyboard +import com.intellij.remoterobot.utils.waitFor +import com.intellij.remoterobot.utils.waitForIgnoringError +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import java.awt.event.KeyEvent.* +import java.time.Duration.ofMinutes +import java.time.Duration.ofSeconds + +@ExtendWith(RemoteRobotExtension::class) +class GUI { + init { + StepsLogger.init() + } + + @BeforeEach + fun waitForIde(remoteRobot: RemoteRobot) { + waitForIgnoringError(ofMinutes(3)) { remoteRobot.callJs("true") } + } + + @AfterEach + fun closeProject(remoteRobot: RemoteRobot) = CommonSteps(remoteRobot).closeProject() + + // @Test + @Video + fun highlightCode(remoteRobot: RemoteRobot): Unit = with(remoteRobot) { + welcomeFrame { + createNewProjectLink.click() + dialog("New Project") { + findText("Java").click() + checkBox("Add sample code").select() + button("Create").click() + } + } + + // Wait for the default "Main.java" tab to load + // Our "continue_tutorial.java.ft" tab loads first, but then "Main.java" takes focus. + // If we don't wait for this, clicking on the GUI may fail because a popup displays + // while the `continue_tutorial.java` is loading. + waitFor(ofSeconds(20)) { + findAll( + byXpath("//div[@accessiblename='Main.java' and @class='EditorTabLabel']") + ).isNotEmpty() + } + + idea { + step("Manually open the webview") { + // Manually open the webview + find(byXpath("//div[@text='Continue']"), ofSeconds((10))).click() + + waitFor(ofSeconds(10)) { + browser().isShowing + } + + // Arbitrary timeout due to a bug where the webview will refresh + // and clear the editor state on first load + Thread.sleep(5000) + } + + step("Verify we can highlight code and add to webview") { + val textToInsert = "Hello world!" + + with(textEditor()) { + editor.insertTextAtLine(0, 0, textToInsert) + editor.selectText(textToInsert) + + keyboard { + hotKey(getMetaKey(), VK_J) + } + } + + waitFor(ofSeconds(10)) { + browser().findElementByContainsText(textToInsert).html.isNotEmpty() + } + } + } + } +} diff --git a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/Onboarding.kt b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/Onboarding.kt new file mode 100644 index 0000000000..3f667559d1 --- /dev/null +++ b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/Onboarding.kt @@ -0,0 +1,85 @@ +package com.github.continuedev.continueintellijextension.e2e + +import com.automation.remarks.junit5.Video +import com.github.continuedev.continueintellijextension.fixtures.dialog +import com.github.continuedev.continueintellijextension.fixtures.idea +import com.github.continuedev.continueintellijextension.fixtures.welcomeFrame +import com.github.continuedev.continueintellijextension.utils.RemoteRobotExtension +import com.github.continuedev.continueintellijextension.utils.StepsLogger +import com.intellij.remoterobot.RemoteRobot +import com.intellij.remoterobot.fixtures.ComponentFixture +import com.intellij.remoterobot.search.locators.byXpath +import com.intellij.remoterobot.steps.CommonSteps +import com.intellij.remoterobot.stepsProcessing.step +import com.intellij.remoterobot.utils.waitFor +import com.intellij.remoterobot.utils.waitForIgnoringError +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import java.time.Duration.ofMinutes +import java.time.Duration.ofSeconds + +@ExtendWith(RemoteRobotExtension::class) +class Onboarding { + init { + StepsLogger.init() + } + + @BeforeEach + fun waitForIde(remoteRobot: RemoteRobot) { + waitForIgnoringError(ofMinutes(3)) { remoteRobot.callJs("true") } + } + + @AfterEach + fun closeProject(remoteRobot: RemoteRobot) = CommonSteps(remoteRobot).closeProject() + + + // @Test + @Video + fun onboarding(remoteRobot: RemoteRobot): Unit = with(remoteRobot) { + welcomeFrame { + createNewProjectLink.click() + dialog("New Project") { + findText("Java").click() + checkBox("Add sample code").select() + button("Create").click() + } + } + + idea { + // Wait for the default "Main.java" tab to load + // Our "continue_tutorial.java.ft" tab loads first, but then "Main.java" takes focus. + // So we need to wait for that to occur, and then focus on "continue_tutorial.java.ft" + waitFor(ofSeconds(20)) { + findAll( + byXpath("//div[@accessiblename='Main.java' and @class='EditorTabLabel']") + ).isNotEmpty() + } + + // TODO: Need a good way to ensure this is the first test ran in the entire suite +// step("Verify Continue tutorial file is loaded") { +// find(byXpath("//div[@visible_text='continue_tutorial.java']")) +// } + + step("Manually open the webview") { + // Manually open the webview + find(byXpath("//div[@text='Continue']"), ofSeconds((10))).click() + + waitFor(ofSeconds(10)) { + browser().isShowing + } + } + + step("Verify the onboarding card is present") { + waitFor(ofSeconds(30)) { + try { + browser().findElement("//*[@data-testid='onboarding-card']").html.isNotEmpty() + } catch (e: Exception) { + false + } + } + } + } + } +} diff --git a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/TutorialTest.kt b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/TutorialTest.kt deleted file mode 100644 index 8e43def29a..0000000000 --- a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/TutorialTest.kt +++ /dev/null @@ -1,94 +0,0 @@ -package com.github.continuedev.continueintellijextension.e2e - -import com.automation.remarks.junit5.Video -import com.github.continuedev.continueintellijextension.pages.dialog -import com.github.continuedev.continueintellijextension.pages.idea -import com.github.continuedev.continueintellijextension.pages.welcomeFrame -import com.github.continuedev.continueintellijextension.utils.RemoteRobotExtension -import com.github.continuedev.continueintellijextension.utils.StepsLogger -import com.github.continuedev.continueintellijextension.utils.getMetaKey -import com.intellij.remoterobot.RemoteRobot -import com.intellij.remoterobot.fixtures.ComponentFixture -import com.intellij.remoterobot.fixtures.JCefBrowserFixture -import com.intellij.remoterobot.search.locators.Locator -import com.intellij.remoterobot.search.locators.byXpath -import com.intellij.remoterobot.steps.CommonSteps -import com.intellij.remoterobot.utils.keyboard -import com.intellij.remoterobot.utils.waitFor -import com.intellij.remoterobot.utils.waitForIgnoringError -import org.junit.jupiter.api.AfterEach -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -import java.awt.event.KeyEvent.* -import java.time.Duration.ofMinutes -import java.time.Duration.ofSeconds - -@ExtendWith(RemoteRobotExtension::class) -class TutorialTest { - init { - StepsLogger.init() - } - - @BeforeEach - fun waitForIde(remoteRobot: RemoteRobot) { - waitForIgnoringError(ofMinutes(3)) { remoteRobot.callJs("true") } - } - - @AfterEach - fun closeProject(remoteRobot: RemoteRobot) = CommonSteps(remoteRobot).closeProject() - - @Test - @Video - fun completeTutorial(remoteRobot: RemoteRobot) = with(remoteRobot) { - welcomeFrame { - createNewProjectLink.click() - dialog("New Project") { - findText("Java").click() - checkBox("Add sample code").select() - button("Create").click() - } - } - - // Wait for the default "Main.java" tab to load - // Our "continue_tutorial.java" tab loads first, but then "Main.java" takes focus. - // So we need to wait for that to occur, and then focus on "continue_tutorial.java" - waitFor(ofSeconds(20)) { - findAll( - byXpath("//div[@accessiblename='Main.java' and @class='EditorTabLabel']") - ).isNotEmpty() - } - - val tutorialEditorTabLocator: Locator = - byXpath("//div[@accessiblename='continue_tutorial.java' and @class='EditorTabLabel']") - val tutorialEditorTab: ComponentFixture = - remoteRobot.find(ComponentFixture::class.java, tutorialEditorTabLocator) - tutorialEditorTab.click() - - // Manually open the webview - find(byXpath("//div[@text='Continue']")).click() - - // Arbitrary sleep while we wait for the webview to load - Thread.sleep(10000) - - val textToInsert = "Hello world!" - - idea { - with(textEditor()) { - editor.insertTextAtLine(0, 0, textToInsert) - editor.selectText(textToInsert) - keyboard { - hotKey(getMetaKey(), VK_J) - } - } - } - - // TODO: locator needs to be OS aware - // https://github.com/JetBrains/intellij-ui-test-robot/blob/139a05eb99e9a49f13605626b81ad9864be23c96/remote-fixtures/src/main/kotlin/com/intellij/remoterobot/fixtures/CommonContainerFixture.kt#L203 - val jcefBrowser = find(JCefBrowserFixture.macLocator) - assert(jcefBrowser.getDom().isNotEmpty()) { "JCEF browser not found or empty" } - - val codeSnippetText = jcefBrowser.findElementByContainsText(textToInsert) - assert(codeSnippetText.html.isNotEmpty()) { "Failed to find code snippet in webview" } - } -} \ No newline at end of file diff --git a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/test-continue/config.json b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/test-continue/config.json new file mode 100644 index 0000000000..0160335f51 --- /dev/null +++ b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/e2e/test-continue/config.json @@ -0,0 +1,43 @@ +{ + "ui": { + "displayRawMarkdown": false + }, + "models": [ + { + "title": "TEST LLM", + "provider": "test", + "model": "this field is not used" + }, + { + "title": "Mock", + "provider": "mock", + "model": "this field is not used" + } + ], + "analytics": { + "provider": "continue-proxy" + }, + "tabAutocompleteModel": { + "title": "TEST LLM", + "provider": "test", + "model": "this field is not used" + }, + "tabAutocompleteOptions": { + "useCache": false + }, + "contextProviders": [ + { + "name": "docs" + }, + { + "name": "diff" + }, + { + "name": "url" + }, + { + "name": "folder" + } + ], + "docs": [] +} diff --git a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/pages/DialogFixture.kt b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/fixtures/DialogFixture.kt similarity index 95% rename from extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/pages/DialogFixture.kt rename to extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/fixtures/DialogFixture.kt index 8bb5798e34..d9643a96b9 100644 --- a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/pages/DialogFixture.kt +++ b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/fixtures/DialogFixture.kt @@ -1,4 +1,4 @@ -package com.github.continuedev.continueintellijextension.pages +package com.github.continuedev.continueintellijextension.fixtures /* * Source: https://github.com/JetBrains/intellij-ui-test-robot/blob/139a05eb99e9a49f13605626b81ad9864be23c96/ui-test-example/src/test/kotlin/org/intellij/examples/simple/plugin/pages/DialogFixture.kt diff --git a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/pages/IdeaFrame.kt b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/fixtures/IdeaFrame.kt similarity index 98% rename from extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/pages/IdeaFrame.kt rename to extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/fixtures/IdeaFrame.kt index b554325853..141677c153 100644 --- a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/pages/IdeaFrame.kt +++ b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/fixtures/IdeaFrame.kt @@ -1,4 +1,4 @@ -package com.github.continuedev.continueintellijextension.pages +package com.github.continuedev.continueintellijextension.fixtures /* * Source: https://github.com/JetBrains/intellij-ui-test-robot/blob/139a05eb99e9a49f13605626b81ad9864be23c96/ui-test-example/src/test/kotlin/org/intellij/examples/simple/plugin/pages/IdeaFrame.kt diff --git a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/pages/WelcomeFrame.kt b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/fixtures/WelcomeFrame.kt similarity index 94% rename from extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/pages/WelcomeFrame.kt rename to extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/fixtures/WelcomeFrame.kt index ab59f72ab7..70029fdaf9 100644 --- a/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/pages/WelcomeFrame.kt +++ b/extensions/intellij/src/test/kotlin/com/github/continuedev/continueintellijextension/fixtures/WelcomeFrame.kt @@ -1,4 +1,4 @@ -package com.github.continuedev.continueintellijextension.pages +package com.github.continuedev.continueintellijextension.fixtures /* * Source: https://github.com/JetBrains/intellij-ui-test-robot/blob/139a05eb99e9a49f13605626b81ad9864be23c96/ui-test-example/src/test/kotlin/org/intellij/examples/simple/plugin/pages/WelcomeFrame.kt diff --git a/gui/src/components/OnboardingCard/OnboardingCard.tsx b/gui/src/components/OnboardingCard/OnboardingCard.tsx index bce9c5a98e..78caa4b5b2 100644 --- a/gui/src/components/OnboardingCard/OnboardingCard.tsx +++ b/gui/src/components/OnboardingCard/OnboardingCard.tsx @@ -41,7 +41,10 @@ export function OnboardingCard() { } return ( - + -

+

{props.title ?? "Confirmation"}