From 4c095871751b3e3a690a41ee24ba9a7848e11e98 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 13 Feb 2025 10:02:52 -0800 Subject: [PATCH 01/21] Using puppeteer for basic tests --- gradle.properties | 2 +- ui-tests-starter/build.gradle.kts | 16 +- .../jetbrains/uitests/AmazonQChatTest.kt | 173 ++++++++++++++++++ .../tstData/config/options/ide.general.xml | 1 + 4 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt diff --git a/gradle.properties b/gradle.properties index 827b7b493ba..846f75541b3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ toolkitVersion=3.52-SNAPSHOT publishToken= publishChannel= -ideProfileName=2024.2 +ideProfileName=2024.3 remoteRobotPort=8080 diff --git a/ui-tests-starter/build.gradle.kts b/ui-tests-starter/build.gradle.kts index c6a4959b766..4c1d0c7ca73 100644 --- a/ui-tests-starter/build.gradle.kts +++ b/ui-tests-starter/build.gradle.kts @@ -30,13 +30,27 @@ intellijPlatform { val testPlugins by configurations.registering dependencies { - testImplementation(platform("com.jetbrains.intellij.tools:ide-starter-squashed")) + //testImplementation(platform("com.jetbrains.intellij.tools:ide-starter")) // should really be set by the BOM, but too much work to figure out right now testImplementation("org.kodein.di:kodein-di-jvm:7.20.2") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.0") + + testImplementation(project(":plugin-core:jetbrains-community")) + testImplementation(project(":plugin-core:core")) + testImplementation(testFixtures(project(":plugin-core:jetbrains-community"))) + + + + + intellijPlatform { intellijIdeaCommunity(IdeVersions.ideProfile(providers).map { it.name }) + intellijIdeaCommunity(ideProfile.community.sdkVersion) + testFramework(TestFrameworkType.JUnit5) testFramework(TestFrameworkType.Starter) + testFramework(TestFrameworkType.Bundled) } testPlugins(project(":plugin-amazonq", "pluginZip")) diff --git a/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt b/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt new file mode 100644 index 00000000000..2cd34e327e8 --- /dev/null +++ b/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt @@ -0,0 +1,173 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.uitests + +import com.intellij.driver.sdk.waitForProjectOpen +import com.intellij.ide.starter.ci.CIServer +import com.intellij.ide.starter.di.di +import com.intellij.ide.starter.driver.engine.runIdeWithDriver +import com.intellij.ide.starter.ide.IdeProductProvider +import com.intellij.ide.starter.junit5.hyphenateWithClass +import com.intellij.ide.starter.models.TestCase +import com.intellij.ide.starter.project.LocalProjectInfo +import com.intellij.ide.starter.runner.CurrentTestMethod +import com.intellij.ide.starter.runner.Starter +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.kodein.di.DI +import org.kodein.di.bindSingleton +import java.io.File +import java.nio.file.Path +import java.nio.file.Paths +import kotlin.io.path.createParentDirectories +import kotlin.io.path.writeText + +class AmazonQChatTest { + + init { + di = DI { + extend(di) + bindSingleton(overrides = true) { TestCIServer } + } + } + + private val testResourcesPath = "src/test/tstData" + + @BeforeEach + fun setUp() { + // Setup test environment + setupTestEnvironment() + } + private fun setupTestEnvironment() { + // Ensure Puppeteer is installed + val npmInstall = ProcessBuilder() + .command("npm", "install", "puppeteer") + .inheritIO() + .start() + .waitFor() + + assertEquals(0, npmInstall, "Failed to install Puppeteer") + + } + + @Test + fun `can open up IDE`() { + val testCase = TestCase( + IdeProductProvider.IC, + LocalProjectInfo( + Paths.get("tstData", "Hello") + ) + ).useRelease("2024.3") + + + + Paths.get(System.getProperty("user.home"), ".aws", "sso", "cache", "ee1d2538cb8d358377d7661466c866af747a8a3f.json") + .createParentDirectories() + .writeText( + """ + paste your client reg here + """.trimIndent() + ) + + Paths.get(System.getProperty("user.home"), ".aws", "sso", "cache", "d3b447f809607422aac1470dd17fbb32e358cdb3.json") + .writeText( + """ + paste your access token here + """.trimIndent() + ) + + Starter.newContext(CurrentTestMethod.hyphenateWithClass(), testCase).apply { + System.getProperty("ui.test.plugins").split(File.pathSeparator).forEach { path -> + pluginConfigurator.installPluginFromPath( + Path.of(path) + ) + } + + copyExistingConfig(Paths.get("tstData", "config")) + updateGeneralSettings() + }.runIdeWithDriver() + .useDriverAndCloseIde { + waitForProjectOpen() + Thread.sleep(20000) + + + val result = executeScript(scr) + assertTrue(result.contains("/doc")) + assertTrue(result.contains("/dev")) + assertTrue(result.contains("/transform")) + assertTrue(result.contains("/help")) + assertTrue(result.contains("/clear")) + assertTrue(result.contains("/review")) + assertTrue(result.contains("/test")) + } + } + + private fun executeScript(scriptContent: String): String { + val scriptFile = File("$testResourcesPath/temp-script.js") + scriptFile.parentFile.mkdirs() + scriptFile.writeText(scriptContent) + + val process = ProcessBuilder() + .command("node", scriptFile.absolutePath) + .redirectErrorStream(true) + .start() + + val output = process.inputStream.bufferedReader().use { it.readText() } + val exitCode = process.waitFor() + + scriptFile.delete() + + assertEquals(0, exitCode, "Script execution failed with output: $output") + return output + } + + +} + +private val scr = """ +import puppeteer from "puppeteer"; + +async function testNavigation() { + const browser = await puppeteer.connect({ + browserURL: "http://localhost:9222" + }) + + try { + + const pages = await browser.pages() + //console.log(pages) + for(const page of pages) { + const contents = await page.evaluate(el => el.innerHTML, await page.${'$'}(':root')); + //console.log(contents) + const element = await page.$('.mynah-chat-prompt-input') + if(element) { + console.log("found") + + await page.type('.mynah-chat-prompt-input', '/') + const elements = await page.$$(".mynah-chat-command-selector-command"); + const attr = await Promise.all( + elements.map(async element => { + return element.evaluate(el => el.getAttribute("command")); + }) + ); + + + + console.log("found commands") + console.log(JSON.stringify(attr, null, 2)) + + } + } + + + } finally { + await browser.close(); + } +} + +testNavigation().catch(console.error); + +""".trimIndent() diff --git a/ui-tests-starter/tstData/config/options/ide.general.xml b/ui-tests-starter/tstData/config/options/ide.general.xml index 28da7b923dd..613e5f081fc 100644 --- a/ui-tests-starter/tstData/config/options/ide.general.xml +++ b/ui-tests-starter/tstData/config/options/ide.general.xml @@ -1,5 +1,6 @@ + From a9b2f15d95b024cb3864cf208c5ca800346db067 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 13 Feb 2025 10:41:31 -0800 Subject: [PATCH 02/21] test with auth --- .../tstFixtures/abc/AbcTest.kt | 64 +++++++++++++++++++ ui-tests-starter/build.gradle.kts | 31 +++++++-- .../jetbrains/uitests/AmazonQChatTest.kt | 28 ++++---- 3 files changed, 104 insertions(+), 19 deletions(-) create mode 100644 plugins/core/jetbrains-community/tstFixtures/abc/AbcTest.kt diff --git a/plugins/core/jetbrains-community/tstFixtures/abc/AbcTest.kt b/plugins/core/jetbrains-community/tstFixtures/abc/AbcTest.kt new file mode 100644 index 00000000000..5a6b39e2278 --- /dev/null +++ b/plugins/core/jetbrains-community/tstFixtures/abc/AbcTest.kt @@ -0,0 +1,64 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package abc + +import com.intellij.openapi.Disposable +import com.intellij.openapi.util.Disposer +import com.intellij.testFramework.ApplicationExtension +import com.intellij.testFramework.junit5.TestDisposable +import org.junit.Rule +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 software.aws.toolkits.core.rules.SystemPropertyHelper +import software.aws.toolkits.jetbrains.core.credentials.LegacyManagedBearerSsoConnection +import software.aws.toolkits.jetbrains.core.credentials.ManagedBearerSsoConnection +import software.aws.toolkits.jetbrains.core.credentials.sono.Q_SCOPES +import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.BearerTokenProvider +import software.aws.toolkits.jetbrains.utils.extensions.SsoLogin +import software.aws.toolkits.jetbrains.utils.extensions.SsoLoginExtension + + +@ExtendWith(ApplicationExtension::class, SsoLoginExtension::class) +@SsoLogin("amazonq-test-account") +//@DisabledIfEnvironmentVariable(named = "IS_PROD", matches = "false") +class AbcTest { + + + @TestDisposable + private lateinit var disposable: Disposable + + + @Rule + @JvmField + val systemPropertyHelper = SystemPropertyHelper() + + private lateinit var connection: ManagedBearerSsoConnection + + + + @BeforeEach + fun setUp() { + // Setup test environment + System.setProperty("AWS_PROFILE","act_cred") + + } + + + @Test + fun `can set up Connection`() { + println("This ran") + connection = LegacyManagedBearerSsoConnection("start_url", "us-east-1", Q_SCOPES) + //ConnectionPinningManager.getInstance().setPinnedConnection(QConnection.getInstance(), connection) + (connection.getConnectionSettings().tokenProvider.delegate as BearerTokenProvider).reauthenticate() + + //Disposer.register(disposable, connection) + // MockClientManager.useRealImplementations(disposableExtension.disposable) + + } + + + +} diff --git a/ui-tests-starter/build.gradle.kts b/ui-tests-starter/build.gradle.kts index 4c1d0c7ca73..34bed52c68e 100644 --- a/ui-tests-starter/build.gradle.kts +++ b/ui-tests-starter/build.gradle.kts @@ -13,6 +13,11 @@ plugins { } val ideProfile = IdeVersions.ideProfile(project) +val testPlugins by configurations.registering +val testPrep by sourceSets.creating { + java.srcDirs(findFolders(project, "tst-prep", ideProfile)) +} + // Add our source sets per IDE profile version (i.e. src-211) sourceSets { @@ -27,7 +32,7 @@ intellijPlatform { instrumentCode = false } -val testPlugins by configurations.registering + dependencies { //testImplementation(platform("com.jetbrains.intellij.tools:ide-starter")) @@ -39,15 +44,18 @@ dependencies { testImplementation(project(":plugin-core:jetbrains-community")) testImplementation(project(":plugin-core:core")) testImplementation(testFixtures(project(":plugin-core:jetbrains-community"))) + val testPrepImplementation by configurations.getting + testPrepImplementation(testFixtures(project(":plugin-core:jetbrains-community"))) intellijPlatform { - intellijIdeaCommunity(IdeVersions.ideProfile(providers).map { it.name }) - intellijIdeaCommunity(ideProfile.community.sdkVersion) - + //intellijIdeaCommunity(IdeVersions.ideProfile(providers).map { it.name }) + //intellijIdeaCommunity(ideProfile.community.sdkVersion) + val version = ideProfile.community.sdkVersion + intellijIdeaCommunity(version, !version.contains("SNAPSHOT")) testFramework(TestFrameworkType.JUnit5) testFramework(TestFrameworkType.Starter) testFramework(TestFrameworkType.Bundled) @@ -57,9 +65,22 @@ dependencies { testPlugins(project(":plugin-core", "pluginZip")) } +val prepareAmazonQTest = tasks.register("prepareAmazonQTest") { +// dependsOn(":plugin-core:jetbrains-community:test:abc") +// filter { +// setIncludePatterns("abc.*") +// //includeTestsMatching("abc.AbcTest") +// //excludeTestsMatching("software.aws.toolkits.jetbrains.*") +// } + testClassesDirs = testPrep.output.classesDirs + classpath = testPrep.runtimeClasspath + + useJUnitPlatform()// Assuming your test task is named amazonQTest +} + tasks.test { dependsOn(testPlugins) - + dependsOn(prepareAmazonQTest) useJUnitPlatform() systemProperty("ui.test.plugins", testPlugins.get().asPath) diff --git a/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt b/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt index 2cd34e327e8..77612180063 100644 --- a/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt +++ b/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt @@ -64,20 +64,20 @@ class AmazonQChatTest { - Paths.get(System.getProperty("user.home"), ".aws", "sso", "cache", "ee1d2538cb8d358377d7661466c866af747a8a3f.json") - .createParentDirectories() - .writeText( - """ - paste your client reg here - """.trimIndent() - ) - - Paths.get(System.getProperty("user.home"), ".aws", "sso", "cache", "d3b447f809607422aac1470dd17fbb32e358cdb3.json") - .writeText( - """ - paste your access token here - """.trimIndent() - ) +// Paths.get(System.getProperty("user.home"), ".aws", "sso", "cache", "ee1d2538cb8d358377d7661466c866af747a8a3f.json") +// .createParentDirectories() +// .writeText( +// """ +// paste your client reg here +// """.trimIndent() +// ) +// +// Paths.get(System.getProperty("user.home"), ".aws", "sso", "cache", "d3b447f809607422aac1470dd17fbb32e358cdb3.json") +// .writeText( +// """ +// paste your access token here +// """.trimIndent() +// ) Starter.newContext(CurrentTestMethod.hyphenateWithClass(), testCase).apply { System.getProperty("ui.test.plugins").split(File.pathSeparator).forEach { path -> From f1583b10796b9ca97a216b26975caf99b529f4d3 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Tue, 18 Feb 2025 14:05:32 -0800 Subject: [PATCH 03/21] UI tests with Auth --- ui-tests-starter/build.gradle.kts | 86 +++++---- .../tst-prep/PreAmazonQUiTest.kt | 42 ++--- .../jetbrains/uitests/AmazonQChatTest.kt | 173 ------------------ .../toolkits/jetbrains/uitests/TestUtils.kt | 104 +++++++++++ .../uitests/chatTests/AmazonQChatTest.kt | 93 ++++++++++ .../uitests/chatTests/TestCaseScripts.kt | 35 ++++ .../tstData/config/options/ide.general.xml | 1 - .../configAmazonQTests/options/aws.xml | 3 + .../options/ide.general.xml | 6 + 9 files changed, 302 insertions(+), 241 deletions(-) rename plugins/core/jetbrains-community/tstFixtures/abc/AbcTest.kt => ui-tests-starter/tst-prep/PreAmazonQUiTest.kt (59%) delete mode 100644 ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt create mode 100644 ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/TestUtils.kt create mode 100644 ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt create mode 100644 ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt create mode 100644 ui-tests-starter/tstData/configAmazonQTests/options/aws.xml create mode 100644 ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml diff --git a/ui-tests-starter/build.gradle.kts b/ui-tests-starter/build.gradle.kts index 34bed52c68e..eb1f477ef31 100644 --- a/ui-tests-starter/build.gradle.kts +++ b/ui-tests-starter/build.gradle.kts @@ -9,21 +9,26 @@ plugins { id("toolkit-kotlin-conventions") id("toolkit-intellij-plugin") - id("org.jetbrains.intellij.platform") + id("org.jetbrains.intellij.platform.module") } val ideProfile = IdeVersions.ideProfile(project) val testPlugins by configurations.registering -val testPrep by sourceSets.creating { - java.srcDirs(findFolders(project, "tst-prep", ideProfile)) -} - -// Add our source sets per IDE profile version (i.e. src-211) sourceSets { test { - java.srcDirs(findFolders(project, "tst", ideProfile)) - resources.srcDirs(findFolders(project, "tst-resources", ideProfile)) + java.setSrcDirs(findFolders(project, "tst-prep", ideProfile)) + resources.setSrcDirs(findFolders(project, "tst-resources", ideProfile)) + } +} + +val uiTestSource = sourceSets.create("uiTest") { + java.setSrcDirs(findFolders(project, "tst", ideProfile)) +} + +idea { + module { + testSources.from(uiTestSource.allSource.srcDirs) } } @@ -32,56 +37,57 @@ intellijPlatform { instrumentCode = false } +val uiTestImplementation by configurations.getting +configurations.getByName(uiTestSource.compileClasspathConfigurationName) { + extendsFrom(uiTestImplementation) +} + +configurations.getByName(uiTestSource.runtimeClasspathConfigurationName) { + extendsFrom(uiTestImplementation) +} dependencies { - //testImplementation(platform("com.jetbrains.intellij.tools:ide-starter")) // should really be set by the BOM, but too much work to figure out right now - testImplementation("org.kodein.di:kodein-di-jvm:7.20.2") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.0") - - testImplementation(project(":plugin-core:jetbrains-community")) - testImplementation(project(":plugin-core:core")) - testImplementation(testFixtures(project(":plugin-core:jetbrains-community"))) - val testPrepImplementation by configurations.getting - - testPrepImplementation(testFixtures(project(":plugin-core:jetbrains-community"))) - - - + uiTestImplementation("org.kodein.di:kodein-di-jvm:7.20.2") + uiTestImplementation(platform(libs.junit5.bom)) + uiTestImplementation(libs.junit5.jupiter) intellijPlatform { - //intellijIdeaCommunity(IdeVersions.ideProfile(providers).map { it.name }) - //intellijIdeaCommunity(ideProfile.community.sdkVersion) val version = ideProfile.community.sdkVersion intellijIdeaCommunity(version, !version.contains("SNAPSHOT")) - testFramework(TestFrameworkType.JUnit5) - testFramework(TestFrameworkType.Starter) + + localPlugin(project(":plugin-core")) + testImplementation(project(":plugin-core:core")) + testImplementation(project(":plugin-core:jetbrains-community")) + testImplementation(testFixtures(project(":plugin-core:jetbrains-community"))) + testFramework(TestFrameworkType.Bundled) + testFramework(TestFrameworkType.JUnit5) + + testFramework(TestFrameworkType.Starter, configurationName = uiTestImplementation.name) } testPlugins(project(":plugin-amazonq", "pluginZip")) testPlugins(project(":plugin-core", "pluginZip")) } -val prepareAmazonQTest = tasks.register("prepareAmazonQTest") { -// dependsOn(":plugin-core:jetbrains-community:test:abc") -// filter { -// setIncludePatterns("abc.*") -// //includeTestsMatching("abc.AbcTest") -// //excludeTestsMatching("software.aws.toolkits.jetbrains.*") -// } - testClassesDirs = testPrep.output.classesDirs - classpath = testPrep.runtimeClasspath - - useJUnitPlatform()// Assuming your test task is named amazonQTest +tasks.test { + enabled = false +} + +val prepareAmazonQTest by intellijPlatformTesting.testIde.registering { + task { + useJUnitPlatform() + } } -tasks.test { - dependsOn(testPlugins) +tasks.register("uiTest") { + testClassesDirs = uiTestSource.output.classesDirs + classpath = uiTestSource.runtimeClasspath + dependsOn(prepareAmazonQTest) - useJUnitPlatform() + dependsOn(testPlugins) systemProperty("ui.test.plugins", testPlugins.get().asPath) } diff --git a/plugins/core/jetbrains-community/tstFixtures/abc/AbcTest.kt b/ui-tests-starter/tst-prep/PreAmazonQUiTest.kt similarity index 59% rename from plugins/core/jetbrains-community/tstFixtures/abc/AbcTest.kt rename to ui-tests-starter/tst-prep/PreAmazonQUiTest.kt index 5a6b39e2278..6d67b32f3ca 100644 --- a/plugins/core/jetbrains-community/tstFixtures/abc/AbcTest.kt +++ b/ui-tests-starter/tst-prep/PreAmazonQUiTest.kt @@ -1,35 +1,30 @@ // Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package abc - import com.intellij.openapi.Disposable -import com.intellij.openapi.util.Disposer import com.intellij.testFramework.ApplicationExtension import com.intellij.testFramework.junit5.TestDisposable import org.junit.Rule -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 software.aws.toolkits.core.rules.SystemPropertyHelper import software.aws.toolkits.jetbrains.core.credentials.LegacyManagedBearerSsoConnection import software.aws.toolkits.jetbrains.core.credentials.ManagedBearerSsoConnection +import software.aws.toolkits.jetbrains.core.credentials.pinning.ConnectionPinningManager +import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection import software.aws.toolkits.jetbrains.core.credentials.sono.Q_SCOPES import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.BearerTokenProvider import software.aws.toolkits.jetbrains.utils.extensions.SsoLogin import software.aws.toolkits.jetbrains.utils.extensions.SsoLoginExtension - @ExtendWith(ApplicationExtension::class, SsoLoginExtension::class) @SsoLogin("amazonq-test-account") -//@DisabledIfEnvironmentVariable(named = "IS_PROD", matches = "false") -class AbcTest { - +// @DisabledIfEnvironmentVariable(named = "IS_PROD", matches = "false") +class PreAmazonQUiTest { @TestDisposable - private lateinit var disposable: Disposable - + lateinit var disposable: Disposable @Rule @JvmField @@ -37,28 +32,21 @@ class AbcTest { private lateinit var connection: ManagedBearerSsoConnection - - @BeforeEach fun setUp() { - // Setup test environment - System.setProperty("AWS_PROFILE","act_cred") - + System.setProperty("aws.dev.useDAG", "true") } - @Test fun `can set up Connection`() { - println("This ran") - connection = LegacyManagedBearerSsoConnection("start_url", "us-east-1", Q_SCOPES) - //ConnectionPinningManager.getInstance().setPinnedConnection(QConnection.getInstance(), connection) - (connection.getConnectionSettings().tokenProvider.delegate as BearerTokenProvider).reauthenticate() - - //Disposer.register(disposable, connection) - // MockClientManager.useRealImplementations(disposableExtension.disposable) - + try { + val startUrl = System.getenv("TEST_START_URL") + val region = System.getenv("TEST_REGION") + connection = LegacyManagedBearerSsoConnection(startUrl, region, Q_SCOPES) + ConnectionPinningManager.getInstance().setPinnedConnection(QConnection.getInstance(), connection) + (connection.getConnectionSettings().tokenProvider.delegate as BearerTokenProvider).reauthenticate() + } catch (e: Exception) { + error("Could not connect to Idc.") + } } - - - } diff --git a/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt b/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt deleted file mode 100644 index 77612180063..00000000000 --- a/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/AmazonQChatTest.kt +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -package software.aws.toolkits.jetbrains.uitests - -import com.intellij.driver.sdk.waitForProjectOpen -import com.intellij.ide.starter.ci.CIServer -import com.intellij.ide.starter.di.di -import com.intellij.ide.starter.driver.engine.runIdeWithDriver -import com.intellij.ide.starter.ide.IdeProductProvider -import com.intellij.ide.starter.junit5.hyphenateWithClass -import com.intellij.ide.starter.models.TestCase -import com.intellij.ide.starter.project.LocalProjectInfo -import com.intellij.ide.starter.runner.CurrentTestMethod -import com.intellij.ide.starter.runner.Starter -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.kodein.di.DI -import org.kodein.di.bindSingleton -import java.io.File -import java.nio.file.Path -import java.nio.file.Paths -import kotlin.io.path.createParentDirectories -import kotlin.io.path.writeText - -class AmazonQChatTest { - - init { - di = DI { - extend(di) - bindSingleton(overrides = true) { TestCIServer } - } - } - - private val testResourcesPath = "src/test/tstData" - - @BeforeEach - fun setUp() { - // Setup test environment - setupTestEnvironment() - } - private fun setupTestEnvironment() { - // Ensure Puppeteer is installed - val npmInstall = ProcessBuilder() - .command("npm", "install", "puppeteer") - .inheritIO() - .start() - .waitFor() - - assertEquals(0, npmInstall, "Failed to install Puppeteer") - - } - - @Test - fun `can open up IDE`() { - val testCase = TestCase( - IdeProductProvider.IC, - LocalProjectInfo( - Paths.get("tstData", "Hello") - ) - ).useRelease("2024.3") - - - -// Paths.get(System.getProperty("user.home"), ".aws", "sso", "cache", "ee1d2538cb8d358377d7661466c866af747a8a3f.json") -// .createParentDirectories() -// .writeText( -// """ -// paste your client reg here -// """.trimIndent() -// ) -// -// Paths.get(System.getProperty("user.home"), ".aws", "sso", "cache", "d3b447f809607422aac1470dd17fbb32e358cdb3.json") -// .writeText( -// """ -// paste your access token here -// """.trimIndent() -// ) - - Starter.newContext(CurrentTestMethod.hyphenateWithClass(), testCase).apply { - System.getProperty("ui.test.plugins").split(File.pathSeparator).forEach { path -> - pluginConfigurator.installPluginFromPath( - Path.of(path) - ) - } - - copyExistingConfig(Paths.get("tstData", "config")) - updateGeneralSettings() - }.runIdeWithDriver() - .useDriverAndCloseIde { - waitForProjectOpen() - Thread.sleep(20000) - - - val result = executeScript(scr) - assertTrue(result.contains("/doc")) - assertTrue(result.contains("/dev")) - assertTrue(result.contains("/transform")) - assertTrue(result.contains("/help")) - assertTrue(result.contains("/clear")) - assertTrue(result.contains("/review")) - assertTrue(result.contains("/test")) - } - } - - private fun executeScript(scriptContent: String): String { - val scriptFile = File("$testResourcesPath/temp-script.js") - scriptFile.parentFile.mkdirs() - scriptFile.writeText(scriptContent) - - val process = ProcessBuilder() - .command("node", scriptFile.absolutePath) - .redirectErrorStream(true) - .start() - - val output = process.inputStream.bufferedReader().use { it.readText() } - val exitCode = process.waitFor() - - scriptFile.delete() - - assertEquals(0, exitCode, "Script execution failed with output: $output") - return output - } - - -} - -private val scr = """ -import puppeteer from "puppeteer"; - -async function testNavigation() { - const browser = await puppeteer.connect({ - browserURL: "http://localhost:9222" - }) - - try { - - const pages = await browser.pages() - //console.log(pages) - for(const page of pages) { - const contents = await page.evaluate(el => el.innerHTML, await page.${'$'}(':root')); - //console.log(contents) - const element = await page.$('.mynah-chat-prompt-input') - if(element) { - console.log("found") - - await page.type('.mynah-chat-prompt-input', '/') - const elements = await page.$$(".mynah-chat-command-selector-command"); - const attr = await Promise.all( - elements.map(async element => { - return element.evaluate(el => el.getAttribute("command")); - }) - ); - - - - console.log("found commands") - console.log(JSON.stringify(attr, null, 2)) - - } - } - - - } finally { - await browser.close(); - } -} - -testNavigation().catch(console.error); - -""".trimIndent() diff --git a/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/TestUtils.kt b/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/TestUtils.kt new file mode 100644 index 00000000000..65de953f7ee --- /dev/null +++ b/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/TestUtils.kt @@ -0,0 +1,104 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.uitests + +import org.junit.jupiter.api.Assertions.assertEquals +import java.io.File +import java.nio.file.Files +import java.nio.file.Paths +import java.nio.file.StandardOpenOption + +private const val TEST_RESOURCES_PATH = "src/test/tstData" +fun executePuppeteerScript(scriptContent: String): String { + val scriptFile = File("$TEST_RESOURCES_PATH/temp-script.js") + scriptFile.parentFile.mkdirs() + scriptFile.writeText(scriptContent) + + val process = ProcessBuilder() + .command("node", scriptFile.absolutePath) + .redirectErrorStream(true) + .start() + + val output = process.inputStream.bufferedReader().use { it.readText() } + val exitCode = process.waitFor() + + scriptFile.delete() + + assertEquals(0, exitCode, "Script execution failed with output: $output") + return output +} + +fun useExistingConnectionForTest() { + val testStartUrl = System.getenv("TEST_START_URL") + val testRegion = System.getenv("TEST_REGION") + val configContent = + """ + + + + + + + + + + + """.trimIndent() + writeToAwsXml(configContent) +} + +fun clearAwsXmlFile() { + val configContent = + """ + + + + """.trimIndent() + writeToAwsXml(configContent) +} + +fun setupTestEnvironment() { + // Ensure Puppeteer is installed + val npmInstall = ProcessBuilder() + .command("npm", "install", "puppeteer") + .inheritIO() + .start() + .waitFor() + + assertEquals(0, npmInstall, "Failed to install Puppeteer") +} + +fun writeToAwsXml(configContent: String) { + val path = Paths.get("tstData", "configAmazonQTests", "options", "aws.xml") + + Files.createDirectories(path.parent) + Files.write( + path, + configContent.toByteArray(), + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING + ) +} diff --git a/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt b/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt new file mode 100644 index 00000000000..3918a49413c --- /dev/null +++ b/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt @@ -0,0 +1,93 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.uitests.chatTests + +import com.intellij.driver.sdk.waitForProjectOpen +import com.intellij.ide.starter.ci.CIServer +import com.intellij.ide.starter.di.di +import com.intellij.ide.starter.driver.engine.runIdeWithDriver +import com.intellij.ide.starter.ide.IdeProductProvider +import com.intellij.ide.starter.junit5.hyphenateWithClass +import com.intellij.ide.starter.models.TestCase +import com.intellij.ide.starter.project.LocalProjectInfo +import com.intellij.ide.starter.runner.CurrentTestMethod +import com.intellij.ide.starter.runner.Starter +import org.junit.jupiter.api.AfterAll +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.kodein.di.DI +import org.kodein.di.bindSingleton +import software.aws.toolkits.jetbrains.uitests.TestCIServer +import software.aws.toolkits.jetbrains.uitests.clearAwsXmlFile +import software.aws.toolkits.jetbrains.uitests.executePuppeteerScript +import software.aws.toolkits.jetbrains.uitests.setupTestEnvironment +import software.aws.toolkits.jetbrains.uitests.useExistingConnectionForTest +import java.io.File +import java.nio.file.Path +import java.nio.file.Paths + +class AmazonQChatTest { + + init { + di = DI { + extend(di) + bindSingleton(overrides = true) { TestCIServer } + } + } + + @BeforeEach + fun setUp() { + // Setup test environment + setupTestEnvironment() + } + + @Test + fun `Ensure feature availability on slash`() { + val testCase = TestCase( + IdeProductProvider.IC, + LocalProjectInfo( + Paths.get("tstData", "Hello") + ) + ).useRelease("2024.3") + + // inject connection + useExistingConnectionForTest() + + Starter.newContext(CurrentTestMethod.hyphenateWithClass(), testCase).apply { + System.getProperty("ui.test.plugins").split(File.pathSeparator).forEach { path -> + pluginConfigurator.installPluginFromPath( + Path.of(path) + ) + } + + copyExistingConfig(Paths.get("tstData", "configAmazonQTests")) + updateGeneralSettings() + }.runIdeWithDriver() + .useDriverAndCloseIde { + waitForProjectOpen() + // required wait time for the system to be fully ready + Thread.sleep(30000) + + val result = executePuppeteerScript(testFeatureAvailabilityOnSlash) + assertTrue(result.contains("/doc")) + assertTrue(result.contains("/dev")) + assertTrue(result.contains("/transform")) + assertTrue(result.contains("/help")) + assertTrue(result.contains("/clear")) + assertTrue(result.contains("/review")) + assertTrue(result.contains("/test")) + + Thread.sleep(20000) + } + } + + companion object { + @JvmStatic + @AfterAll + fun clearAwsXml() { + clearAwsXmlFile() + } + } +} diff --git a/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt b/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt new file mode 100644 index 00000000000..f1989560e0d --- /dev/null +++ b/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt @@ -0,0 +1,35 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.uitests.chatTests + +val testFeatureAvailabilityOnSlash = """ +import puppeteer from "puppeteer"; + +async function testNavigation() { + const browser = await puppeteer.connect({ + browserURL: "http://localhost:9222" + }) + try { + const pages = await browser.pages() + for(const page of pages) { + const contents = await page.evaluate(el => el.innerHTML, await page.${'$'}(':root')); + const element = await page.$('.mynah-chat-prompt-input') + if(element) { + await page.type('.mynah-chat-prompt-input', '/') + const elements = await page.$$(".mynah-chat-command-selector-command"); + const attr = await Promise.all( + elements.map(async element => { + return element.evaluate(el => el.getAttribute("command")); + }) + ); + console.log(JSON.stringify(attr, null, 2)) + } + } + } finally { + await browser.close(); + } +} +testNavigation().catch(console.error); + +""".trimIndent() diff --git a/ui-tests-starter/tstData/config/options/ide.general.xml b/ui-tests-starter/tstData/config/options/ide.general.xml index 613e5f081fc..28da7b923dd 100644 --- a/ui-tests-starter/tstData/config/options/ide.general.xml +++ b/ui-tests-starter/tstData/config/options/ide.general.xml @@ -1,6 +1,5 @@ - diff --git a/ui-tests-starter/tstData/configAmazonQTests/options/aws.xml b/ui-tests-starter/tstData/configAmazonQTests/options/aws.xml new file mode 100644 index 00000000000..1dd984e2e57 --- /dev/null +++ b/ui-tests-starter/tstData/configAmazonQTests/options/aws.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml b/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml new file mode 100644 index 00000000000..613e5f081fc --- /dev/null +++ b/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml @@ -0,0 +1,6 @@ + + + + + + From bcb83deff79b011b9a6548547c68c313f1cce220 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Wed, 19 Feb 2025 15:03:58 -0800 Subject: [PATCH 04/21] handle env vars --- ui-tests-starter/build.gradle.kts | 1 + .../jetbrains/uitests/chatTests/AmazonQChatTest.kt | 10 +++++++++- .../jetbrains/uitests/chatTests/TestCaseScripts.kt | 0 3 files changed, 10 insertions(+), 1 deletion(-) rename ui-tests-starter/{tst => tst-243+}/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt (86%) rename ui-tests-starter/{tst => tst-243+}/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt (100%) diff --git a/ui-tests-starter/build.gradle.kts b/ui-tests-starter/build.gradle.kts index f1f3428e35d..36c6ba90f71 100644 --- a/ui-tests-starter/build.gradle.kts +++ b/ui-tests-starter/build.gradle.kts @@ -91,6 +91,7 @@ tasks.register("uiTest") { dependsOn(testPlugins) systemProperty("ui.test.plugins", testPlugins.get().asPath) + systemProperty("org.gradle.project.ideProfileName", ideProfile.name) } // hack to disable ui tests in ./gradlew check diff --git a/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt similarity index 86% rename from ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt rename to ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt index 3918a49413c..168d5f3aa7f 100644 --- a/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt +++ b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt @@ -5,6 +5,7 @@ package software.aws.toolkits.jetbrains.uitests.chatTests import com.intellij.driver.sdk.waitForProjectOpen import com.intellij.ide.starter.ci.CIServer +import com.intellij.ide.starter.config.ConfigurationStorage import com.intellij.ide.starter.di.di import com.intellij.ide.starter.driver.engine.runIdeWithDriver import com.intellij.ide.starter.ide.IdeProductProvider @@ -34,6 +35,13 @@ class AmazonQChatTest { di = DI { extend(di) bindSingleton(overrides = true) { TestCIServer } + val defaults = ConfigurationStorage.instance().defaults.toMutableMap().apply { + put("LOG_ENVIRONMENT_VARIABLES", (!System.getenv("CI").toBoolean()).toString()) + } + + bindSingleton(overrides = true) { + ConfigurationStorage(this, defaults) + } } } @@ -50,7 +58,7 @@ class AmazonQChatTest { LocalProjectInfo( Paths.get("tstData", "Hello") ) - ).useRelease("2024.3") + ).useRelease(System.getProperty("org.gradle.project.ideProfileName")) // inject connection useExistingConnectionForTest() diff --git a/ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt similarity index 100% rename from ui-tests-starter/tst/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt rename to ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt From 3b5fd0edf12d3cb741ce52cc46da7c84327023a6 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Wed, 19 Feb 2025 16:27:44 -0800 Subject: [PATCH 05/21] feedback 1 --- ui-tests-starter/build.gradle.kts | 1 - .../aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt | 1 + ui-tests-starter/tst-prep/PreAmazonQUiTest.kt | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ui-tests-starter/build.gradle.kts b/ui-tests-starter/build.gradle.kts index 36c6ba90f71..fa74b970b40 100644 --- a/ui-tests-starter/build.gradle.kts +++ b/ui-tests-starter/build.gradle.kts @@ -66,7 +66,6 @@ dependencies { testFramework(TestFrameworkType.JUnit5) testFramework(TestFrameworkType.Starter, configurationName = uiTestImplementation.name) - } testPlugins(project(":plugin-amazonq", "pluginZip")) diff --git a/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt index f1989560e0d..5091a0c8c3d 100644 --- a/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt +++ b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt @@ -3,6 +3,7 @@ package software.aws.toolkits.jetbrains.uitests.chatTests +// language=JS val testFeatureAvailabilityOnSlash = """ import puppeteer from "puppeteer"; diff --git a/ui-tests-starter/tst-prep/PreAmazonQUiTest.kt b/ui-tests-starter/tst-prep/PreAmazonQUiTest.kt index 6d67b32f3ca..ae5531fa41d 100644 --- a/ui-tests-starter/tst-prep/PreAmazonQUiTest.kt +++ b/ui-tests-starter/tst-prep/PreAmazonQUiTest.kt @@ -20,7 +20,6 @@ import software.aws.toolkits.jetbrains.utils.extensions.SsoLoginExtension @ExtendWith(ApplicationExtension::class, SsoLoginExtension::class) @SsoLogin("amazonq-test-account") -// @DisabledIfEnvironmentVariable(named = "IS_PROD", matches = "false") class PreAmazonQUiTest { @TestDisposable From 1985edf5d6c638008f0d7e120b8218056742f274 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 27 Feb 2025 10:40:54 -0800 Subject: [PATCH 06/21] Switch test package --- buildspec/linuxUiTests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildspec/linuxUiTests.yml b/buildspec/linuxUiTests.yml index 607736f9f46..2455e191762 100644 --- a/buildspec/linuxUiTests.yml +++ b/buildspec/linuxUiTests.yml @@ -47,7 +47,7 @@ phases: - chmod +x gradlew - ffmpeg -loglevel quiet -nostdin -f x11grab -video_size ${SCREEN_WIDTH}x${SCREEN_HEIGHT} -i ${DISPLAY} -codec:v libx264 -pix_fmt yuv420p -vf drawtext="fontsize=48:box=1:boxcolor=black@0.75:boxborderw=5:fontcolor=white:x=0:y=h-text_h:text='%{gmtime\:%H\\\\\:%M\\\\\:%S}'" -framerate 12 -g 12 /tmp/screen_recording.mp4 & - - ./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME :ui-tests-starter:test coverageReport --console plain --info + - ./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME :ui-tests-starter:uiTest coverageReport --console plain --info post_build: commands: From b9ae1670ca9056051e372ff94496949b6381c3ea Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 27 Feb 2025 11:19:16 -0800 Subject: [PATCH 07/21] Modify import --- .../aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt index 5091a0c8c3d..47a1cf88cdf 100644 --- a/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt +++ b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt @@ -5,7 +5,7 @@ package software.aws.toolkits.jetbrains.uitests.chatTests // language=JS val testFeatureAvailabilityOnSlash = """ -import puppeteer from "puppeteer"; +const puppeteer = require('puppeteer'); async function testNavigation() { const browser = await puppeteer.connect({ From 62c652672e944f019aa277e9d258b63130803633 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 27 Feb 2025 12:17:26 -0800 Subject: [PATCH 08/21] enable jcef --- noop/build.gradle.kts | 1 + .../tstData/configAmazonQTests/options/ide.general.xml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/noop/build.gradle.kts b/noop/build.gradle.kts index 54de3e72a44..1e1e680c606 100644 --- a/noop/build.gradle.kts +++ b/noop/build.gradle.kts @@ -3,3 +3,4 @@ // project that does nothing tasks.register("test") +tasks.register("uiTest") diff --git a/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml b/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml index 613e5f081fc..a5df43485ae 100644 --- a/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml +++ b/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml @@ -2,5 +2,8 @@ + + + From 0316bcf3be94ad1c078bd23e605d62863fafc9df Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 27 Feb 2025 13:04:52 -0800 Subject: [PATCH 09/21] more settings --- .../tstData/configAmazonQTests/options/ide.general.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml b/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml index a5df43485ae..af23c5b9939 100644 --- a/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml +++ b/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml @@ -5,5 +5,7 @@ + + From 7746823994fb887994f61cd2aa729640296ef564 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 27 Feb 2025 14:38:09 -0800 Subject: [PATCH 10/21] install apparmor --- buildspec/linuxUiTests.yml | 11 ++++++++ settings.gradle.kts | 7 ++--- ui-tests-starter/build.gradle.kts | 44 ++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/buildspec/linuxUiTests.yml b/buildspec/linuxUiTests.yml index 2455e191762..7a483fe5542 100644 --- a/buildspec/linuxUiTests.yml +++ b/buildspec/linuxUiTests.yml @@ -46,6 +46,17 @@ phases: - chmod +x gradlew + - | + >/etc/apparmor.d/jcef + abi , + include + + profile /usr/lib/jvm/java-21-amazon-corretto.x86_64/bin/java flags=(unconfined) { + userns, + + include if exists + } + - apparmor_parser -r /etc/apparmor.d/jcef - ffmpeg -loglevel quiet -nostdin -f x11grab -video_size ${SCREEN_WIDTH}x${SCREEN_HEIGHT} -i ${DISPLAY} -codec:v libx264 -pix_fmt yuv420p -vf drawtext="fontsize=48:box=1:boxcolor=black@0.75:boxborderw=5:fontcolor=white:x=0:y=h-text_h:text='%{gmtime\:%H\\\\\:%M\\\\\:%S}'" -framerate 12 -g 12 /tmp/screen_recording.mp4 & - ./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME :ui-tests-starter:uiTest coverageReport --console plain --info diff --git a/settings.gradle.kts b/settings.gradle.kts index c6872181877..e9daf9c6daf 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -100,10 +100,11 @@ include("sandbox-all") include("ui-tests-starter") when (providers.gradleProperty("ideProfileName").get()) { // FIX_WHEN_MIN_IS_242: `tmp-all` test module no longer needed in 242+ - "2023.3", "2024.1" -> { + "2024.1" -> { include("tmp-all") - - // only available 242+ + } + "2024.1", "2024.2" -> { + // only available 243+ project(":ui-tests-starter").projectDir = file("noop") } } diff --git a/ui-tests-starter/build.gradle.kts b/ui-tests-starter/build.gradle.kts index fa74b970b40..ba43847c385 100644 --- a/ui-tests-starter/build.gradle.kts +++ b/ui-tests-starter/build.gradle.kts @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import org.jetbrains.intellij.platform.gradle.TestFrameworkType +import org.jetbrains.intellij.platform.gradle.tasks.aware.RuntimeAware import software.aws.toolkits.gradle.findFolders import software.aws.toolkits.gradle.intellij.IdeVersions @@ -9,7 +10,7 @@ plugins { id("toolkit-kotlin-conventions") id("toolkit-intellij-plugin") - id("org.jetbrains.intellij.platform.module") + id("org.jetbrains.intellij.platform") } val ideProfile = IdeVersions.ideProfile(project) @@ -100,3 +101,44 @@ val action = Action { } } gradle.taskGraph.whenReady(action) +// +//abstract class InstallCefAppArmor : DefaultTask(), RuntimeAware { +// @TaskAction +// fun execute() { +// println(runtimeLauncher.get().executablePath) +// } +//} +//tasks.register("installCefAppArmor") { +// description = "Install AppArmor profile for JBCef" +// group = "Security" +// val osName = System.getProperty("os.name").lowercase() +// doFirst { +// if (!osName.contains("linux")) { +// println("Skipping AppArmor installation - not running on Linux") +// return@doFirst +// } +// } +// +// doLast { +// val profile = """ +// # This profile is autogenerated to allow running sandboxed JCEF +// abi , +// include +// +// profile %s flags=(unconfined) { +// userns, +// +// include if exists +// } +// """.trimIndent() +// profile.format("/usr/lib/jvm/java-21-amazon-corretto.x86_64/bin/java") +// val profileAction = JBCefAppArmorUtils.getInstallInstallAppArmorProfileAction() +// if (profileAction != null) { +// profileAction.run() +// println("AppArmor profile installation completed") +// } else { +// println("No AppArmor profile installation action available") +// } +// } +// +//} From 2a872053c124cabb461e7d03f65508c019ec42c1 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 27 Feb 2025 14:41:53 -0800 Subject: [PATCH 11/21] install apparmor --- buildspec/linuxUiTests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildspec/linuxUiTests.yml b/buildspec/linuxUiTests.yml index 7a483fe5542..572b6d51223 100644 --- a/buildspec/linuxUiTests.yml +++ b/buildspec/linuxUiTests.yml @@ -47,7 +47,7 @@ phases: - chmod +x gradlew - | - >/etc/apparmor.d/jcef + >/etc/apparmor.d/jcef echo " abi , include @@ -55,7 +55,7 @@ phases: userns, include if exists - } + }" - apparmor_parser -r /etc/apparmor.d/jcef - ffmpeg -loglevel quiet -nostdin -f x11grab -video_size ${SCREEN_WIDTH}x${SCREEN_HEIGHT} -i ${DISPLAY} -codec:v libx264 -pix_fmt yuv420p -vf drawtext="fontsize=48:box=1:boxcolor=black@0.75:boxborderw=5:fontcolor=white:x=0:y=h-text_h:text='%{gmtime\:%H\\\\\:%M\\\\\:%S}'" -framerate 12 -g 12 /tmp/screen_recording.mp4 & - ./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME :ui-tests-starter:uiTest coverageReport --console plain --info From 2f4899be4b3b238fded5a01a38c28086f2654825 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 27 Feb 2025 14:48:34 -0800 Subject: [PATCH 12/21] install apparmor --- buildspec/linuxUiTests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildspec/linuxUiTests.yml b/buildspec/linuxUiTests.yml index 572b6d51223..756f7811f87 100644 --- a/buildspec/linuxUiTests.yml +++ b/buildspec/linuxUiTests.yml @@ -45,7 +45,7 @@ phases: credential_source=EcsContainer" - chmod +x gradlew - + - touch /etc/apparmor.d/jcef - | >/etc/apparmor.d/jcef echo " abi , From c5b0124e8a145b71a4e2c77c1b9507987c482dae Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 27 Feb 2025 14:58:18 -0800 Subject: [PATCH 13/21] install apparmor --- buildspec/linuxUiTests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/buildspec/linuxUiTests.yml b/buildspec/linuxUiTests.yml index 756f7811f87..f6a83e95120 100644 --- a/buildspec/linuxUiTests.yml +++ b/buildspec/linuxUiTests.yml @@ -45,6 +45,7 @@ phases: credential_source=EcsContainer" - chmod +x gradlew + - mkdir -p /etc/apparmor.d - touch /etc/apparmor.d/jcef - | >/etc/apparmor.d/jcef echo " From 1241bca2b753bbf44b279bc7e545ae85baacd007 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 27 Feb 2025 15:03:33 -0800 Subject: [PATCH 14/21] install apparmor --- buildspec/linuxUiTests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildspec/linuxUiTests.yml b/buildspec/linuxUiTests.yml index f6a83e95120..06287ac592a 100644 --- a/buildspec/linuxUiTests.yml +++ b/buildspec/linuxUiTests.yml @@ -57,7 +57,7 @@ phases: include if exists }" - - apparmor_parser -r /etc/apparmor.d/jcef + - sudo apparmor_parser -r /etc/apparmor.d/jcef - ffmpeg -loglevel quiet -nostdin -f x11grab -video_size ${SCREEN_WIDTH}x${SCREEN_HEIGHT} -i ${DISPLAY} -codec:v libx264 -pix_fmt yuv420p -vf drawtext="fontsize=48:box=1:boxcolor=black@0.75:boxborderw=5:fontcolor=white:x=0:y=h-text_h:text='%{gmtime\:%H\\\\\:%M\\\\\:%S}'" -framerate 12 -g 12 /tmp/screen_recording.mp4 & - ./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME :ui-tests-starter:uiTest coverageReport --console plain --info From c9e6533614f9ae858deeb86d2529c4c470bc71ff Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Thu, 27 Feb 2025 15:32:55 -0800 Subject: [PATCH 15/21] Fix test --- buildspec/linuxUiTests.yml | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/buildspec/linuxUiTests.yml b/buildspec/linuxUiTests.yml index 06287ac592a..d2f8728ae86 100644 --- a/buildspec/linuxUiTests.yml +++ b/buildspec/linuxUiTests.yml @@ -45,19 +45,7 @@ phases: credential_source=EcsContainer" - chmod +x gradlew - - mkdir -p /etc/apparmor.d - - touch /etc/apparmor.d/jcef - - | - >/etc/apparmor.d/jcef echo " - abi , - include - - profile /usr/lib/jvm/java-21-amazon-corretto.x86_64/bin/java flags=(unconfined) { - userns, - - include if exists - }" - - sudo apparmor_parser -r /etc/apparmor.d/jcef + - sysctl -w kernel.unprivileged_userns_clone=1 - ffmpeg -loglevel quiet -nostdin -f x11grab -video_size ${SCREEN_WIDTH}x${SCREEN_HEIGHT} -i ${DISPLAY} -codec:v libx264 -pix_fmt yuv420p -vf drawtext="fontsize=48:box=1:boxcolor=black@0.75:boxborderw=5:fontcolor=white:x=0:y=h-text_h:text='%{gmtime\:%H\\\\\:%M\\\\\:%S}'" -framerate 12 -g 12 /tmp/screen_recording.mp4 & - ./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME :ui-tests-starter:uiTest coverageReport --console plain --info From 2f87eaa89c3a61e3f8b263eafde83d95dafd9ecc Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Fri, 28 Feb 2025 13:53:52 -0800 Subject: [PATCH 16/21] try this setting --- buildspec/linuxUiTests.yml | 2 +- ui-tests-starter/build.gradle.kts | 41 ------------------- .../options/ide.general.xml | 6 +-- 3 files changed, 2 insertions(+), 47 deletions(-) diff --git a/buildspec/linuxUiTests.yml b/buildspec/linuxUiTests.yml index d2f8728ae86..2455e191762 100644 --- a/buildspec/linuxUiTests.yml +++ b/buildspec/linuxUiTests.yml @@ -45,7 +45,7 @@ phases: credential_source=EcsContainer" - chmod +x gradlew - - sysctl -w kernel.unprivileged_userns_clone=1 + - ffmpeg -loglevel quiet -nostdin -f x11grab -video_size ${SCREEN_WIDTH}x${SCREEN_HEIGHT} -i ${DISPLAY} -codec:v libx264 -pix_fmt yuv420p -vf drawtext="fontsize=48:box=1:boxcolor=black@0.75:boxborderw=5:fontcolor=white:x=0:y=h-text_h:text='%{gmtime\:%H\\\\\:%M\\\\\:%S}'" -framerate 12 -g 12 /tmp/screen_recording.mp4 & - ./gradlew -PideProfileName=$ALTERNATIVE_IDE_PROFILE_NAME :ui-tests-starter:uiTest coverageReport --console plain --info diff --git a/ui-tests-starter/build.gradle.kts b/ui-tests-starter/build.gradle.kts index ba43847c385..854a460f298 100644 --- a/ui-tests-starter/build.gradle.kts +++ b/ui-tests-starter/build.gradle.kts @@ -101,44 +101,3 @@ val action = Action { } } gradle.taskGraph.whenReady(action) -// -//abstract class InstallCefAppArmor : DefaultTask(), RuntimeAware { -// @TaskAction -// fun execute() { -// println(runtimeLauncher.get().executablePath) -// } -//} -//tasks.register("installCefAppArmor") { -// description = "Install AppArmor profile for JBCef" -// group = "Security" -// val osName = System.getProperty("os.name").lowercase() -// doFirst { -// if (!osName.contains("linux")) { -// println("Skipping AppArmor installation - not running on Linux") -// return@doFirst -// } -// } -// -// doLast { -// val profile = """ -// # This profile is autogenerated to allow running sandboxed JCEF -// abi , -// include -// -// profile %s flags=(unconfined) { -// userns, -// -// include if exists -// } -// """.trimIndent() -// profile.format("/usr/lib/jvm/java-21-amazon-corretto.x86_64/bin/java") -// val profileAction = JBCefAppArmorUtils.getInstallInstallAppArmorProfileAction() -// if (profileAction != null) { -// profileAction.run() -// println("AppArmor profile installation completed") -// } else { -// println("No AppArmor profile installation action available") -// } -// } -// -//} diff --git a/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml b/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml index af23c5b9939..9cd270cc445 100644 --- a/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml +++ b/ui-tests-starter/tstData/configAmazonQTests/options/ide.general.xml @@ -2,10 +2,6 @@ - - - - - + From 32813db2b823a51c3bf20963b0f3d495fd979bd5 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Fri, 28 Feb 2025 14:24:55 -0800 Subject: [PATCH 17/21] modify 241 config --- settings.gradle.kts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index e9daf9c6daf..168f4da0a14 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -102,8 +102,9 @@ when (providers.gradleProperty("ideProfileName").get()) { // FIX_WHEN_MIN_IS_242: `tmp-all` test module no longer needed in 242+ "2024.1" -> { include("tmp-all") + project(":ui-tests-starter").projectDir = file("noop") } - "2024.1", "2024.2" -> { + "2024.2" -> { // only available 243+ project(":ui-tests-starter").projectDir = file("noop") } From dc7f4e0805a95ff79bea4ef2627aa127e63bb7eb Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Fri, 28 Feb 2025 14:26:19 -0800 Subject: [PATCH 18/21] detekt --- ui-tests-starter/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/ui-tests-starter/build.gradle.kts b/ui-tests-starter/build.gradle.kts index 854a460f298..e5baeb09608 100644 --- a/ui-tests-starter/build.gradle.kts +++ b/ui-tests-starter/build.gradle.kts @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 import org.jetbrains.intellij.platform.gradle.TestFrameworkType -import org.jetbrains.intellij.platform.gradle.tasks.aware.RuntimeAware import software.aws.toolkits.gradle.findFolders import software.aws.toolkits.gradle.intellij.IdeVersions From 08ab78297dd63b203ebf02e660e3999badc108b5 Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Fri, 28 Feb 2025 15:10:41 -0800 Subject: [PATCH 19/21] assertions --- .../jetbrains/uitests/chatTests/AmazonQChatTest.kt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt index 168d5f3aa7f..5e7ba0529e3 100644 --- a/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt +++ b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt @@ -3,6 +3,7 @@ package software.aws.toolkits.jetbrains.uitests.chatTests +import com.intellij.driver.sdk.waitForIndicators import com.intellij.driver.sdk.waitForProjectOpen import com.intellij.ide.starter.ci.CIServer import com.intellij.ide.starter.config.ConfigurationStorage @@ -28,6 +29,10 @@ import software.aws.toolkits.jetbrains.uitests.useExistingConnectionForTest import java.io.File import java.nio.file.Path import java.nio.file.Paths +import kotlin.time.Duration +import kotlin.time.Duration.Companion.minutes +import kotlin.time.DurationUnit +import kotlin.time.toDuration class AmazonQChatTest { @@ -76,7 +81,8 @@ class AmazonQChatTest { .useDriverAndCloseIde { waitForProjectOpen() // required wait time for the system to be fully ready - Thread.sleep(30000) + waitForIndicators(2.minutes) + // Thread.sleep(30000) val result = executePuppeteerScript(testFeatureAvailabilityOnSlash) assertTrue(result.contains("/doc")) @@ -86,8 +92,8 @@ class AmazonQChatTest { assertTrue(result.contains("/clear")) assertTrue(result.contains("/review")) assertTrue(result.contains("/test")) - - Thread.sleep(20000) + println("Assertion done") + //Thread.sleep(20000) } } From a00e5ebf8132b64b8e07db4ce5be568661afff8e Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Fri, 28 Feb 2025 15:59:31 -0800 Subject: [PATCH 20/21] revert to thread sleep --- .../toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt index 5e7ba0529e3..a7742114f09 100644 --- a/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt +++ b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt @@ -81,8 +81,7 @@ class AmazonQChatTest { .useDriverAndCloseIde { waitForProjectOpen() // required wait time for the system to be fully ready - waitForIndicators(2.minutes) - // Thread.sleep(30000) + Thread.sleep(30000) val result = executePuppeteerScript(testFeatureAvailabilityOnSlash) assertTrue(result.contains("/doc")) @@ -93,7 +92,7 @@ class AmazonQChatTest { assertTrue(result.contains("/review")) assertTrue(result.contains("/test")) println("Assertion done") - //Thread.sleep(20000) + } } From 7e9d97f857e2f53bb3a137f19504ab37c7f1aa8a Mon Sep 17 00:00:00 2001 From: Manodnya Bhoite Date: Mon, 3 Mar 2025 10:23:40 -0800 Subject: [PATCH 21/21] removed print statement --- .../jetbrains/uitests/chatTests/AmazonQChatTest.kt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt index a7742114f09..fbac6249c01 100644 --- a/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt +++ b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/AmazonQChatTest.kt @@ -3,7 +3,6 @@ package software.aws.toolkits.jetbrains.uitests.chatTests -import com.intellij.driver.sdk.waitForIndicators import com.intellij.driver.sdk.waitForProjectOpen import com.intellij.ide.starter.ci.CIServer import com.intellij.ide.starter.config.ConfigurationStorage @@ -29,10 +28,6 @@ import software.aws.toolkits.jetbrains.uitests.useExistingConnectionForTest import java.io.File import java.nio.file.Path import java.nio.file.Paths -import kotlin.time.Duration -import kotlin.time.Duration.Companion.minutes -import kotlin.time.DurationUnit -import kotlin.time.toDuration class AmazonQChatTest { @@ -91,8 +86,6 @@ class AmazonQChatTest { assertTrue(result.contains("/clear")) assertTrue(result.contains("/review")) assertTrue(result.contains("/test")) - println("Assertion done") - } }