From 181febb95e28dcac7f6fd9e337e995006e929dd4 Mon Sep 17 00:00:00 2001 From: Egor Hutsko Date: Tue, 11 Feb 2025 12:20:03 +0100 Subject: [PATCH 1/2] [ADFA-365] - project build test with Base Project and Kotlin --- .../com/itsaky/androidide/ProjectBuildTest.kt | 133 +++++++++++++++++- .../screens/ProjectSettingsScreen.kt | 12 +- .../itsaky/androidide/templates/parameters.kt | 7 +- 3 files changed, 140 insertions(+), 12 deletions(-) diff --git a/app/src/androidTest/kotlin/com/itsaky/androidide/ProjectBuildTest.kt b/app/src/androidTest/kotlin/com/itsaky/androidide/ProjectBuildTest.kt index 9fc9adfedb..44fdde4cdd 100644 --- a/app/src/androidTest/kotlin/com/itsaky/androidide/ProjectBuildTest.kt +++ b/app/src/androidTest/kotlin/com/itsaky/androidide/ProjectBuildTest.kt @@ -9,6 +9,7 @@ import com.itsaky.androidide.screens.ProjectSettingsScreen import com.itsaky.androidide.screens.TemplateScreen import com.kaspersky.kaspresso.testcases.api.testcase.TestCase import io.github.kakaocup.kakao.common.views.KView +import io.github.kakaocup.kakao.spinner.KSpinnerItem import io.github.kakaocup.kakao.toolbar.KToolbar import org.junit.Rule import org.junit.Test @@ -19,7 +20,7 @@ class ProjectBuildTest : TestCase() { val activityRule = activityScenarioRule() @Test - fun test_projectBuild_withJava_withBasicProject() { + fun test_projectBuild_baseProject_java() { run { step("Initialize the app") { scenario(NavigateToMainScreenScenario()) @@ -48,12 +49,16 @@ class ProjectBuildTest : TestCase() { } step("Select the java language") { ProjectSettingsScreen { - languageField { + spinner { isVisible() - click() - } + open() - KView { withText("Java") }.click() + childAt(0) { + isVisible() + hasText("Java") + click() + } + } createProjectButton { isVisible() @@ -129,4 +134,122 @@ class ProjectBuildTest : TestCase() { } } } + + @Test + fun test_projectBuild_baseProject_kotlin() { + run { + step("Initialize the app") { + scenario(NavigateToMainScreenScenario()) + } + step("Click create project") { + flakySafely(60000) { + HomeScreen { + rvActions { + childAt(0) { + click() + } + } + } + } + } + step("Select the basic project") { + flakySafely(10000) { + TemplateScreen { + rvTemplates { + childWith { + withDescendant { withText(R.string.template_basic) } + } perform { click() } + } + } + } + } + step("Select the kotlin language") { + flakySafely { + ProjectSettingsScreen { + spinner { + isVisible() + open() + + childAt(1) { + isVisible() + hasText("Kotlin") + click() + } + } + + createProjectButton { + isVisible() + click() + } + } + } + } + step("Close the first build dialog") { + flakySafely(120000) { + EditorScreen { + firstBuildDialog { + isDisplayed() + title { + hasText(R.string.title_first_build) + } + message { + hasText(R.string.msg_first_build) + } + positiveButton { + click() + } + } + } + } + } + step("Wait for the green button") { + flakySafely(180000) { + KView { + withText(R.string.msg_project_initialized) + }.isVisible() + flakySafely { + KView { + withParent { + KToolbar { + withId(R.id.editor_appBarLayout) + } + } + withId("ide.editor.build.quickRun".hashCode()) + }.click() + } + } + } + step("Confirm that the install dialog appears and click cancel") { + flakySafely(120000) { + val installDialog = + device.uiDevice.findObject(UiSelector().text("Do you want to install this app?")) + val cancelButton = device.uiDevice.findObject(UiSelector().text("Cancel")) + if (installDialog.waitForExists(120000)) { + installDialog.exists() + cancelButton.click() + } else { + throw AssertionError("Install dialog not found!") + } + } + } + step("Click back and confirm that the Close Project dialog appears") { + device.uiDevice.pressBack() + flakySafely { + EditorScreen { + closeProjectDialog { + title { + hasText(R.string.title_confirm_project_close) + } + message { + hasText(R.string.msg_confirm_project_close) + } + positiveButton { + click() + } + } + } + } + } + } + } } \ No newline at end of file diff --git a/app/src/androidTest/kotlin/com/itsaky/androidide/screens/ProjectSettingsScreen.kt b/app/src/androidTest/kotlin/com/itsaky/androidide/screens/ProjectSettingsScreen.kt index 41f84e4ba3..360b7c1f48 100644 --- a/app/src/androidTest/kotlin/com/itsaky/androidide/screens/ProjectSettingsScreen.kt +++ b/app/src/androidTest/kotlin/com/itsaky/androidide/screens/ProjectSettingsScreen.kt @@ -2,7 +2,8 @@ package com.itsaky.androidide.screens import com.itsaky.androidide.R import com.kaspersky.kaspresso.screens.KScreen -import io.github.kakaocup.kakao.common.views.KView +import io.github.kakaocup.kakao.spinner.KSpinner +import io.github.kakaocup.kakao.spinner.KSpinnerItem import io.github.kakaocup.kakao.text.KButton object ProjectSettingsScreen : KScreen() { @@ -11,12 +12,13 @@ object ProjectSettingsScreen : KScreen() { override val viewClass: Class<*>? = null - val languageField = KView { - withHint("Project Language") - } - val createProjectButton = KButton { withText(R.string.create_project) withId(R.id.finish) } + + val spinner = KSpinner( + builder = { withHint("Project Language") }, + itemTypeBuilder = { itemType(::KSpinnerItem) } + ) } \ No newline at end of file diff --git a/templates-api/src/main/java/com/itsaky/androidide/templates/parameters.kt b/templates-api/src/main/java/com/itsaky/androidide/templates/parameters.kt index a9dcc7d23a..d9b5d5596a 100644 --- a/templates-api/src/main/java/com/itsaky/androidide/templates/parameters.kt +++ b/templates-api/src/main/java/com/itsaky/androidide/templates/parameters.kt @@ -389,8 +389,11 @@ inline fun projectLanguageParameter( default = Java displayName = Language::lang startIcon = { - if (it.value == Kotlin) R.drawable.ic_language_kotlin - else R.drawable.ic_language_java + if (it.value == Kotlin) { + R.drawable.ic_language_kotlin + } else { + R.drawable.ic_language_java + } } configure() From ae86c6e71290ed84febf0550edd9d9fb1dd63825 Mon Sep 17 00:00:00 2001 From: Egor Hutsko Date: Tue, 11 Feb 2025 12:39:02 +0100 Subject: [PATCH 2/2] [ADFA-365] - project build test with Base Project and Kotlin - extract InitializationProjectAndCancelingBuildScenario --- .../com/itsaky/androidide/ProjectBuildTest.kt | 140 +----------------- ...izationProjectAndCancelingBuildScenario.kt | 81 ++++++++++ .../NavigateToMainScreenScenario.kt | 2 +- 3 files changed, 88 insertions(+), 135 deletions(-) create mode 100644 app/src/androidTest/kotlin/com/itsaky/androidide/scenarios/InitializationProjectAndCancelingBuildScenario.kt rename app/src/androidTest/kotlin/com/itsaky/androidide/{ => scenarios}/NavigateToMainScreenScenario.kt (98%) diff --git a/app/src/androidTest/kotlin/com/itsaky/androidide/ProjectBuildTest.kt b/app/src/androidTest/kotlin/com/itsaky/androidide/ProjectBuildTest.kt index 44fdde4cdd..a22193f612 100644 --- a/app/src/androidTest/kotlin/com/itsaky/androidide/ProjectBuildTest.kt +++ b/app/src/androidTest/kotlin/com/itsaky/androidide/ProjectBuildTest.kt @@ -1,16 +1,14 @@ package com.itsaky.androidide import androidx.test.ext.junit.rules.activityScenarioRule -import androidx.test.uiautomator.UiSelector import com.itsaky.androidide.activities.SplashActivity -import com.itsaky.androidide.screens.EditorScreen +import com.itsaky.androidide.scenarios.InitializationProjectAndCancelingBuildScenario +import com.itsaky.androidide.scenarios.NavigateToMainScreenScenario import com.itsaky.androidide.screens.HomeScreen import com.itsaky.androidide.screens.ProjectSettingsScreen import com.itsaky.androidide.screens.TemplateScreen import com.kaspersky.kaspresso.testcases.api.testcase.TestCase -import io.github.kakaocup.kakao.common.views.KView import io.github.kakaocup.kakao.spinner.KSpinnerItem -import io.github.kakaocup.kakao.toolbar.KToolbar import org.junit.Rule import org.junit.Test @@ -66,71 +64,8 @@ class ProjectBuildTest : TestCase() { } } } - step("Close the first build dialog") { - flakySafely(120000) { - EditorScreen { - firstBuildDialog { - isDisplayed() - title { - hasText(R.string.title_first_build) - } - message { - hasText(R.string.msg_first_build) - } - positiveButton { - click() - } - } - } - } - } - step("Wait for the green button") { - flakySafely(180000) { - KView { - withText(R.string.msg_project_initialized) - }.isVisible() - flakySafely { - KView { - withParent { - KToolbar { - withId(R.id.editor_appBarLayout) - } - } - withId("ide.editor.build.quickRun".hashCode()) - }.click() - } - } - } - step("Confirm that the install dialog appears and click cancel") { - flakySafely(120000) { - val installDialog = - device.uiDevice.findObject(UiSelector().text("Do you want to install this app?")) - val cancelButton = device.uiDevice.findObject(UiSelector().text("Cancel")) - if (installDialog.waitForExists(120000)) { - installDialog.exists() - cancelButton.click() - } else { - throw AssertionError("Install dialog not found!") - } - } - } - step("Click back and confirm that the Close Project dialog appears") { - device.uiDevice.pressBack() - flakySafely { - EditorScreen { - closeProjectDialog { - title { - hasText(R.string.title_confirm_project_close) - } - message { - hasText(R.string.msg_confirm_project_close) - } - positiveButton { - click() - } - } - } - } + step("Initialization the project and cancelling the build") { + scenario(InitializationProjectAndCancelingBuildScenario()) } } } @@ -184,71 +119,8 @@ class ProjectBuildTest : TestCase() { } } } - step("Close the first build dialog") { - flakySafely(120000) { - EditorScreen { - firstBuildDialog { - isDisplayed() - title { - hasText(R.string.title_first_build) - } - message { - hasText(R.string.msg_first_build) - } - positiveButton { - click() - } - } - } - } - } - step("Wait for the green button") { - flakySafely(180000) { - KView { - withText(R.string.msg_project_initialized) - }.isVisible() - flakySafely { - KView { - withParent { - KToolbar { - withId(R.id.editor_appBarLayout) - } - } - withId("ide.editor.build.quickRun".hashCode()) - }.click() - } - } - } - step("Confirm that the install dialog appears and click cancel") { - flakySafely(120000) { - val installDialog = - device.uiDevice.findObject(UiSelector().text("Do you want to install this app?")) - val cancelButton = device.uiDevice.findObject(UiSelector().text("Cancel")) - if (installDialog.waitForExists(120000)) { - installDialog.exists() - cancelButton.click() - } else { - throw AssertionError("Install dialog not found!") - } - } - } - step("Click back and confirm that the Close Project dialog appears") { - device.uiDevice.pressBack() - flakySafely { - EditorScreen { - closeProjectDialog { - title { - hasText(R.string.title_confirm_project_close) - } - message { - hasText(R.string.msg_confirm_project_close) - } - positiveButton { - click() - } - } - } - } + step("Initialization the project and cancelling the build") { + scenario(InitializationProjectAndCancelingBuildScenario()) } } } diff --git a/app/src/androidTest/kotlin/com/itsaky/androidide/scenarios/InitializationProjectAndCancelingBuildScenario.kt b/app/src/androidTest/kotlin/com/itsaky/androidide/scenarios/InitializationProjectAndCancelingBuildScenario.kt new file mode 100644 index 0000000000..ff508a9728 --- /dev/null +++ b/app/src/androidTest/kotlin/com/itsaky/androidide/scenarios/InitializationProjectAndCancelingBuildScenario.kt @@ -0,0 +1,81 @@ +package com.itsaky.androidide.scenarios + +import androidx.test.uiautomator.UiSelector +import com.itsaky.androidide.R +import com.itsaky.androidide.screens.EditorScreen +import com.kaspersky.kaspresso.testcases.api.scenario.Scenario +import com.kaspersky.kaspresso.testcases.core.testcontext.TestContext +import io.github.kakaocup.kakao.common.views.KView +import io.github.kakaocup.kakao.toolbar.KToolbar + +class InitializationProjectAndCancelingBuildScenario : Scenario() { + + override val steps: TestContext.() -> Unit = { + step("Close the first build dialog") { + flakySafely(120000) { + EditorScreen { + firstBuildDialog { + isDisplayed() + title { + hasText(R.string.title_first_build) + } + message { + hasText(R.string.msg_first_build) + } + positiveButton { + click() + } + } + } + } + } + step("Wait for the green button") { + flakySafely(180000) { + KView { + withText(R.string.msg_project_initialized) + }.isVisible() + flakySafely { + KView { + withParent { + KToolbar { + withId(R.id.editor_appBarLayout) + } + } + withId("ide.editor.build.quickRun".hashCode()) + }.click() + } + } + } + step("Confirm that the install dialog appears and click cancel") { + flakySafely(120000) { + val installDialog = + device.uiDevice.findObject(UiSelector().text("Do you want to install this app?")) + val cancelButton = device.uiDevice.findObject(UiSelector().text("Cancel")) + if (installDialog.waitForExists(120000)) { + installDialog.exists() + cancelButton.click() + } else { + throw AssertionError("Install dialog not found!") + } + } + } + step("Click back and confirm that the Close Project dialog appears") { + device.uiDevice.pressBack() + flakySafely { + EditorScreen { + closeProjectDialog { + title { + hasText(R.string.title_confirm_project_close) + } + message { + hasText(R.string.msg_confirm_project_close) + } + positiveButton { + click() + } + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/androidTest/kotlin/com/itsaky/androidide/NavigateToMainScreenScenario.kt b/app/src/androidTest/kotlin/com/itsaky/androidide/scenarios/NavigateToMainScreenScenario.kt similarity index 98% rename from app/src/androidTest/kotlin/com/itsaky/androidide/NavigateToMainScreenScenario.kt rename to app/src/androidTest/kotlin/com/itsaky/androidide/scenarios/NavigateToMainScreenScenario.kt index 552cb54e3f..7b41f21438 100644 --- a/app/src/androidTest/kotlin/com/itsaky/androidide/NavigateToMainScreenScenario.kt +++ b/app/src/androidTest/kotlin/com/itsaky/androidide/scenarios/NavigateToMainScreenScenario.kt @@ -1,4 +1,4 @@ -package com.itsaky.androidide +package com.itsaky.androidide.scenarios import com.itsaky.androidide.screens.InstallToolsScreen import com.itsaky.androidide.screens.OnboardingScreen