Repository: aws/aws-toolkit-jetbrains
Pull request #5402: test(amazonq): add e2e test for /transform
Author: login: dhasani23
Created: 2025-02-25T06:24:53Z | Merged: 2025-03-21T22:57:42Z

<!--- If you are a new contributor, please take a look at the README and CONTRIBUTING documents --->
<!--- Provide a general summary of your changes in the Title above -->

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)

## Description
<!--- Describe your changes in detail -->
<!--- If appropriate, providing screenshots will help us review your contribution -->
<!--- If there is a related issue, please provide a link here -->

## Checklist
- [ ] My code follows the code style of this project
- [ ] I have added tests to cover my changes
- [ ] A short description of the change has been added to the **[CHANGELOG](https://github.com/aws/aws-toolkit-jetbrains/blob/master/CONTRIBUTING.md#contributing-via-pull-requests)** if the change is customer-facing in the IDE.
- [ ] I have added metrics for my changes (if required)
 
## License
I confirm that my contribution is made under the terms of the Apache 2.0 license.



Diff:
diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt
index ffddd69b70b..592c588550e 100644
--- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt
+++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt
@@ -24,6 +24,7 @@ import software.aws.toolkits.jetbrains.services.amazonq.util.tabType
 import software.aws.toolkits.jetbrains.services.amazonq.webview.theme.AmazonQTheme
 import software.aws.toolkits.jetbrains.services.amazonq.webview.theme.ThemeBrowserAdapter
 import software.aws.toolkits.jetbrains.settings.MeetQSettings
+import software.aws.toolkits.telemetry.MetricResult
 import software.aws.toolkits.telemetry.Telemetry
 import java.util.function.Function
 
@@ -70,6 +71,7 @@ class BrowserConnector(
                             Telemetry.toolkit.willOpenModule.use {
                                 it.module(module.asText())
                                 it.source(trigger.asText())
+                                it.result(MetricResult.Succeeded)
                             }
                         }
                     }
diff --git a/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/transformTests/TransformChatTest.kt b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/transformTests/TransformChatTest.kt
new file mode 100644
index 00000000000..2a064983968
--- /dev/null
+++ b/ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/transformTests/TransformChatTest.kt
@@ -0,0 +1,161 @@
+// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package software.aws.toolkits.jetbrains.uitests.transformTests
+
+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
+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
+
+// language=JS
+val transformHappyPathScript = """
+const puppeteer = require('puppeteer');
+async function testNavigation() {
+    const browser = await puppeteer.connect({
+        browserURL: "http://localhost:9222"
+    })
+    try {
+        const pages = await browser.pages()
+        for (const page of pages) {
+            await page.type('.mynah-chat-prompt-input', '/transform')
+            await page.keyboard.press('Enter')
+            
+            await page.waitForSelector('.mynah-chat-item-form-items-container', {
+                timeout: 5000
+            })
+            const formInputs = await page.$$('.mynah-form-input-wrapper')
+            
+            const moduleLabel = await formInputs[0].evaluate(
+                element => element.querySelector('.mynah-ui-form-item-mandatory-title').textContent
+            )
+            console.log('Module selection label:', moduleLabel)
+            
+            const versionLabel = await formInputs[1].evaluate(
+                element => element.querySelector('.mynah-ui-form-item-mandatory-title').textContent
+            )
+            console.log('Version selection label:', versionLabel)
+            
+            await page.evaluate(() => {
+                const button = document.querySelector('button[action-id="codetransform-input-confirm"]')
+                button.click()
+            })
+            
+            const skipTestsForm = await page.waitForSelector('button[action-id="codetransform-input-confirm-skip-tests"]', {
+                timeout: 5000
+            })
+            console.log('Skip tests form appeared:', skipTestsForm !== null)
+            
+            await page.evaluate(() => {
+                const button = document.querySelector('button[action-id="codetransform-input-confirm-skip-tests"]')
+                button.click()
+            })
+            
+            const oneOrMultipleDiffsForm = await page.waitForSelector('button[action-id="codetransform-input-confirm-one-or-multiple-diffs"]', {
+                timeout: 5000
+            })
+            console.log('One or multiple diffs form appeared:', oneOrMultipleDiffsForm !== null)
+            
+            await page.evaluate(() => {
+                const button = document.querySelector('button[action-id="codetransform-input-confirm-one-or-multiple-diffs"]')
+                button.click()
+            })
+              
+            const errorMessage = await page.waitForSelector('text/Sorry, I couldn\'t run the Maven clean install command', {
+                timeout: 5000
+            })
+            console.log('Error message:', await errorMessage.evaluate(el => el.textContent))
+        }
+    } finally {
+        await browser.close()
+    }
+}
+testNavigation().catch(console.error)
+
+""".trimIndent()
+
+class TransformChatTest {
+
+    init {
+        di = DI {
+            extend(di)
+            bindSingleton<CIServer>(overrides = true) { TestCIServer }
+            val defaults = ConfigurationStorage.instance().defaults.toMutableMap().apply {
+                put("LOG_ENVIRONMENT_VARIABLES", (!System.getenv("CI").toBoolean()).toString())
+            }
+
+            bindSingleton<ConfigurationStorage>(overrides = true) {
+                ConfigurationStorage(this, defaults)
+            }
+        }
+    }
+
+    @BeforeEach
+    fun setUp() {
+        setupTestEnvironment()
+    }
+
+    @Test
+    fun `can run a transformation from the chat`() {
+        val testCase = TestCase(
+            IdeProductProvider.IC,
+            LocalProjectInfo(
+                Paths.get("tstData", "Hello")
+            )
+        ).useRelease(System.getProperty("org.gradle.project.ideProfileName"))
+
+        // 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(transformHappyPathScript)
+                assertTrue(result.contains("Choose a module to transform"))
+                assertTrue(result.contains("Choose the target code version"))
+                assertTrue(result.contains("Skip tests form appeared: true"))
+                assertTrue(result.contains("One or multiple diffs form appeared: true"))
+                assertTrue(result.contains("couldn't run the Maven clean install command"))
+            }
+    }
+
+    companion object {
+        @JvmStatic
+        @AfterAll
+        fun clearAwsXml() {
+            clearAwsXmlFile()
+        }
+    }
+}
diff --git a/ui-tests-starter/tstData/Hello/pom.xml b/ui-tests-starter/tstData/Hello/pom.xml
new file mode 100644
index 00000000000..72b6fc59528
--- /dev/null
+++ b/ui-tests-starter/tstData/Hello/pom.xml
@@ -0,0 +1,14 @@
+<!-- Sample pom.xml for testing /transform in TransformChatTest.kt -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>1.0.0</modelVersion>
+    <groupId>transform-testing-group-id</groupId>
+    <artifactId>transform-testing-artifact-id</artifactId>
+    <version>1.0</version>
+    <packaging>jar</packaging>
+    <url>http://maven.apache.org</url>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <java.version>1.8</java.version>
+    </properties>
+</project>


Reviews:
user: login: manodnyab
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T20:46:26Z
user: login: ntarakad-aws
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T17:16:21Z
user: login: manodnyab
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T22:37:46Z
user: login: manodnyab
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T17:51:20Z

Review comments:
diff_hunk: @@ -34,3 +34,69 @@ async function testNavigation() {
 testNavigation().catch(console.error);
 
 """.trimIndent()
+
+// language=JS
+val transformHappyPathScript = """
path: ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/chatTests/TestCaseScripts.kt
user: login: manodnyab
body: Can you move this script to the transform test folder?
created_at: 2025-03-12T20:46:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,161 @@
+// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package software.aws.toolkits.jetbrains.uitests.transformTests
+
+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
+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
+
+// language=JS
path: ui-tests-starter/tst-243+/software/aws/toolkits/jetbrains/uitests/transformTests/TransformChatTest.kt
user: login: manodnyab
body: nit: would recommend keeping the scripts separate, in case more need to be added!
created_at: 2025-03-18T22:37:14Z
author_association: CONTRIBUTOR

PR comments:
user: login: dhasani23
created_at: 2025-03-03T22:26:02Z
body: /runUiTests 
author_association: CONTRIBUTOR
user: login: dhasani23
created_at: 2025-03-12T17:44:42Z
body: /runUiTests
author_association: CONTRIBUTOR
user: login: dhasani23
created_at: 2025-03-13T00:01:42Z
body: /runUiTests
author_association: CONTRIBUTOR
user: login: dhasani23
created_at: 2025-03-13T19:19:53Z
body: /runUiTests
author_association: CONTRIBUTOR
user: login: dhasani23
created_at: 2025-03-18T22:39:16Z
body: /runUiTests
author_association: CONTRIBUTOR
user: login: dhasani23
created_at: 2025-03-19T16:43:53Z
body: /runUiTests
author_association: CONTRIBUTOR
user: login: dhasani23
created_at: 2025-03-19T23:06:02Z
body: /runUiTests
author_association: CONTRIBUTOR
user: login: dhasani23
created_at: 2025-03-20T22:23:40Z
body: /runUiTests
author_association: CONTRIBUTOR