mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
fix: add tests for MainFragment and refactor testing modules
This commit is contained in:
+39
@@ -31,6 +31,45 @@
|
||||
</AndroidTestResultsTableState>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="-166137969">
|
||||
<value>
|
||||
<AndroidTestResultsTableState>
|
||||
<option name="preferredColumnWidths">
|
||||
<map>
|
||||
<entry key="Duration" value="90" />
|
||||
<entry key="Tests" value="360" />
|
||||
<entry key="realme RMX3312" value="120" />
|
||||
</map>
|
||||
</option>
|
||||
</AndroidTestResultsTableState>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="-136582810">
|
||||
<value>
|
||||
<AndroidTestResultsTableState>
|
||||
<option name="preferredColumnWidths">
|
||||
<map>
|
||||
<entry key="Duration" value="90" />
|
||||
<entry key="Tests" value="360" />
|
||||
<entry key="realme RMX3312" value="120" />
|
||||
</map>
|
||||
</option>
|
||||
</AndroidTestResultsTableState>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="1123912474">
|
||||
<value>
|
||||
<AndroidTestResultsTableState>
|
||||
<option name="preferredColumnWidths">
|
||||
<map>
|
||||
<entry key="Duration" value="90" />
|
||||
<entry key="Tests" value="360" />
|
||||
<entry key="realme RMX3312" value="120" />
|
||||
</map>
|
||||
</option>
|
||||
</AndroidTestResultsTableState>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
|
||||
Generated
+12
@@ -116,6 +116,7 @@
|
||||
<module name="AndroidIDE.ksp-processor" target="11" />
|
||||
<module name="AndroidIDE.ksp-processor.main" target="11" />
|
||||
<module name="AndroidIDE.ksp-processor.test" target="11" />
|
||||
<module name="AndroidIDE.lsp.testing" target="17" />
|
||||
<module name="AndroidIDE.sdk-info" target="11" />
|
||||
<module name="AndroidIDE.subprojects.classfile" target="11" />
|
||||
<module name="AndroidIDE.subprojects.classfile.main" target="11" />
|
||||
@@ -128,12 +129,23 @@
|
||||
<module name="AndroidIDE.subprojects.tooling-api-model2" target="11" />
|
||||
<module name="AndroidIDE.subprojects.tooling-api-model2.main" target="11" />
|
||||
<module name="AndroidIDE.subprojects.tooling-api-model2.test" target="11" />
|
||||
<module name="AndroidIDE.subprojects.tooling-api-testing" target="11" />
|
||||
<module name="AndroidIDE.subprojects.tooling-api-testing.main" target="11" />
|
||||
<module name="AndroidIDE.subprojects.tooling-api-testing.test" target="11" />
|
||||
<module name="AndroidIDE.subprojects.xml-formatter.main" target="11" />
|
||||
<module name="AndroidIDE.subprojects.xml-formatter.test" target="11" />
|
||||
<module name="AndroidIDE.templates-testing" target="17" />
|
||||
<module name="AndroidIDE.templates-testing.main" target="11" />
|
||||
<module name="AndroidIDE.templates-testing.test" target="11" />
|
||||
<module name="AndroidIDE.testing-android" target="17" />
|
||||
<module name="AndroidIDE.testing.android.test" target="11" />
|
||||
<module name="AndroidIDE.testing.common" target="11" />
|
||||
<module name="AndroidIDE.testing.common.main" target="11" />
|
||||
<module name="AndroidIDE.testing.common.test" target="11" />
|
||||
<module name="AndroidIDE.testing.tooling-api" target="11" />
|
||||
<module name="AndroidIDE.testing.tooling-api.main" target="11" />
|
||||
<module name="AndroidIDE.testing.tooling-api.test" target="11" />
|
||||
<module name="AndroidIDE.testing.unit.test" target="11" />
|
||||
<module name="AndroidIDE.treesitter.test" target="1.7" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import androidx.navigation.safe.args.generator.ext.capitalize
|
||||
import com.android.build.gradle.BaseExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.extraProperties
|
||||
import java.util.Base64
|
||||
import java.util.Locale
|
||||
|
||||
@@ -162,13 +163,8 @@ dependencies {
|
||||
// So we always copy the latest JAR file to assets
|
||||
compileOnly(projects.subprojects.toolingApiImpl)
|
||||
|
||||
testImplementation(libs.common.editor)
|
||||
testImplementation(libs.tests.junit)
|
||||
testImplementation(libs.tests.google.truth)
|
||||
testImplementation(libs.tests.robolectric)
|
||||
androidTestImplementation(libs.tests.androidx.junit)
|
||||
androidTestImplementation(libs.tests.androidx.espresso)
|
||||
androidTestImplementation(libs.tests.google.truth)
|
||||
testImplementation(projects.testing.unit)
|
||||
androidTestImplementation(projects.testing.android)
|
||||
}
|
||||
|
||||
fun downloadSigningKey() {
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.activities
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.cardview.widget.CardView
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.action.ViewActions.*
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isChecked
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withParent
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.itsaky.androidide.R
|
||||
import com.itsaky.androidide.models.MainScreenAction
|
||||
import com.itsaky.androidide.templates.BooleanParameter
|
||||
import com.itsaky.androidide.templates.EnumParameter
|
||||
import com.itsaky.androidide.templates.ITemplateProvider
|
||||
import com.itsaky.androidide.templates.StringParameter
|
||||
import org.hamcrest.Description
|
||||
import org.hamcrest.Matcher
|
||||
import org.hamcrest.Matchers.allOf
|
||||
import org.hamcrest.TypeSafeMatcher
|
||||
import org.hamcrest.core.IsInstanceOf.instanceOf
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@LargeTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MainFragmentTest {
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
var mActivityScenarioRule = ActivityScenarioRule(MainActivity::class.java)
|
||||
|
||||
@Test
|
||||
fun testMainFragmentActionsAreShown() {
|
||||
val recyclerView = onView(allOf(
|
||||
withId(R.id.actions),
|
||||
childAtPosition(
|
||||
withId(R.id.coordinator),
|
||||
3)))
|
||||
|
||||
recyclerView.check(matches(isDisplayed()))
|
||||
|
||||
for (action in MainScreenAction.all()) {
|
||||
val button = onView(
|
||||
allOf(withText(action.text),
|
||||
withParent(allOf(withId(R.id.actions),
|
||||
withParent(withId(R.id.coordinator)))),
|
||||
isDisplayed()))
|
||||
button.check(matches(isDisplayed()))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTemplateWizardUi() {
|
||||
|
||||
onView(withText(R.string.get_started)).check(matches(isCompletelyDisplayed()))
|
||||
|
||||
val recyclerView = onView(allOf(
|
||||
withId(R.id.actions),
|
||||
childAtPosition(
|
||||
withId(R.id.coordinator),
|
||||
3)))
|
||||
|
||||
recyclerView.check(matches(isDisplayed()))
|
||||
|
||||
val action = MainScreenAction.all().find { it.id == MainScreenAction.ACTION_CREATE_PROJECT }
|
||||
assertThat(action).isNotNull()
|
||||
|
||||
action!!
|
||||
|
||||
val createProject = onView(allOf(withText(action.text), isDisplayed()))
|
||||
|
||||
createProject.check(matches(isCompletelyDisplayed()))
|
||||
createProject.perform(click())
|
||||
|
||||
val exitButton = onView(
|
||||
allOf(withId(R.id.exit_button), isCompletelyDisplayed())
|
||||
)
|
||||
|
||||
exitButton.check(matches(isCompletelyDisplayed()))
|
||||
|
||||
val templates = ITemplateProvider.getInstance().getTemplates()
|
||||
for (template in templates) {
|
||||
val templateTitle = onView(
|
||||
allOf(withId(R.id.template_name), withText(template.templateName),
|
||||
withParent(
|
||||
withParent(instanceOf(CardView::class.java))),
|
||||
isCompletelyDisplayed()))
|
||||
|
||||
templateTitle.check(matches(isCompletelyDisplayed()))
|
||||
}
|
||||
|
||||
val template = templates.first()
|
||||
val firstTemplateItem = onView(
|
||||
allOf(withId(R.id.template_name), withText(template.templateName),
|
||||
withParent(
|
||||
withParent(instanceOf(CardView::class.java))),
|
||||
isCompletelyDisplayed()))
|
||||
|
||||
firstTemplateItem.perform(click())
|
||||
|
||||
val previousButton = onView(
|
||||
allOf(withId(R.id.previous), withText(R.string.previous), isCompletelyDisplayed()))
|
||||
|
||||
val createProjectFinishButton = onView(
|
||||
allOf(withId(R.id.finish), withText(R.string.create_project),
|
||||
isCompletelyDisplayed()))
|
||||
|
||||
previousButton.check(matches(isCompletelyDisplayed()))
|
||||
createProjectFinishButton.check(matches(isCompletelyDisplayed()))
|
||||
|
||||
for (parameter in template.parameters) {
|
||||
val selector = when (parameter) {
|
||||
is StringParameter -> withText(parameter.value)
|
||||
is BooleanParameter -> allOf(withText(parameter.name),
|
||||
if (parameter.value) isChecked() else isNotChecked())
|
||||
|
||||
is EnumParameter -> withText(parameter.getDisplayName())
|
||||
else -> throw IllegalStateException("Unknown parameter type: $parameter")
|
||||
}
|
||||
val widget = onView(selector)
|
||||
widget.check(matches(isCompletelyDisplayed()))
|
||||
}
|
||||
|
||||
previousButton.perform(click())
|
||||
|
||||
Thread.sleep(1000L)
|
||||
|
||||
exitButton.check(matches(isCompletelyDisplayed()))
|
||||
exitButton.perform(click())
|
||||
|
||||
Thread.sleep(1000L)
|
||||
|
||||
onView(withText(R.string.get_started)).check(matches(isCompletelyDisplayed()))
|
||||
}
|
||||
|
||||
private fun childAtPosition(
|
||||
parentMatcher: Matcher<View>, position: Int): Matcher<View> {
|
||||
|
||||
return object : TypeSafeMatcher<View>() {
|
||||
override fun describeTo(description: Description) {
|
||||
description.appendText("Child at position $position in parent ")
|
||||
parentMatcher.describeTo(description)
|
||||
}
|
||||
|
||||
public override fun matchesSafely(view: View): Boolean {
|
||||
val parent = view.parent
|
||||
return parent is ViewGroup && parentMatcher.matches(parent)
|
||||
&& view == parent.getChildAt(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,7 +47,9 @@ constructor(val actions: List<MainScreenAction> = emptyList()) :
|
||||
binding.root.apply {
|
||||
setText(action.text)
|
||||
setIconResource(action.icon)
|
||||
setOnClickListener(action.onClick)
|
||||
setOnClickListener {
|
||||
action.onClick?.invoke(action, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import com.itsaky.androidide.common.databinding.LayoutDialogProgressBinding
|
||||
import com.itsaky.androidide.databinding.FragmentMainBinding
|
||||
import com.itsaky.androidide.models.MainScreenAction
|
||||
import com.itsaky.androidide.preferences.databinding.LayoutDialogTextInputBinding
|
||||
import com.itsaky.androidide.resources.R
|
||||
import com.itsaky.androidide.resources.R.string
|
||||
import com.itsaky.androidide.tasks.executeAsyncProvideError
|
||||
import com.itsaky.androidide.utils.DialogUtils
|
||||
@@ -40,7 +39,7 @@ class MainFragment : BaseFragment() {
|
||||
private val log = ILogger.newInstance("MainFragment")
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = FragmentMainBinding.inflate(inflater, container, false)
|
||||
return binding!!.root
|
||||
@@ -48,28 +47,26 @@ class MainFragment : BaseFragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val createProject = MainScreenAction(string.create_project,
|
||||
R.drawable.ic_add) { showCreateProject() }
|
||||
val openProject = MainScreenAction(string.msg_open_existing_project,
|
||||
R.drawable.ic_folder) { pickDirectory() }
|
||||
val cloneGitRepository = MainScreenAction(string.git_clone_repo,
|
||||
R.drawable.ic_git) { cloneGitRepo() }
|
||||
val openTerminal =
|
||||
MainScreenAction(string.title_terminal, R.drawable.ic_terminal) {
|
||||
startActivity(Intent(requireActivity(), TerminalActivity::class.java))
|
||||
|
||||
val actions = MainScreenAction.all().also { actions ->
|
||||
val onClick = { action: MainScreenAction, _: View ->
|
||||
when (action.id) {
|
||||
MainScreenAction.ACTION_CREATE_PROJECT -> showCreateProject()
|
||||
MainScreenAction.ACTION_OPEN_PROJECT -> pickDirectory()
|
||||
MainScreenAction.ACTION_CLONE_REPO -> cloneGitRepo()
|
||||
MainScreenAction.ACTION_OPEN_TERMINAL -> startActivity(
|
||||
Intent(requireActivity(), TerminalActivity::class.java))
|
||||
|
||||
MainScreenAction.ACTION_PREFERENCES -> gotoPreferences()
|
||||
MainScreenAction.ACTION_DONATE -> BaseApplication.getBaseInstance().openDonationsPage()
|
||||
MainScreenAction.ACTION_DOCS -> BaseApplication.getBaseInstance().openDocs()
|
||||
}
|
||||
}
|
||||
val preferences = MainScreenAction(string.msg_preferences,
|
||||
R.drawable.ic_settings) { gotoPreferences() }
|
||||
val sponsor = MainScreenAction(string.btn_donate, R.drawable.ic_donate) {
|
||||
BaseApplication.getBaseInstance().openSponsors()
|
||||
}
|
||||
val docs = MainScreenAction(string.btn_docs, R.drawable.ic_docs) {
|
||||
BaseApplication.getBaseInstance().openDocs()
|
||||
|
||||
actions.forEach { action -> action.onClick = onClick }
|
||||
}
|
||||
|
||||
binding!!.actions.adapter = MainActionsListAdapter(
|
||||
listOf(createProject, openProject, cloneGitRepository, openTerminal,
|
||||
preferences, docs, sponsor))
|
||||
binding!!.actions.adapter = MainActionsListAdapter(actions)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
@@ -182,7 +179,7 @@ class MainFragment : BaseFragment() {
|
||||
|
||||
// TODO(itsaky) : Improve this implementation
|
||||
class GitCloneProgressMonitor(val progress: LinearProgressIndicator,
|
||||
val message: TextView
|
||||
val message: TextView
|
||||
) : ProgressMonitor {
|
||||
|
||||
private var cancelled = false
|
||||
|
||||
@@ -20,6 +20,8 @@ package com.itsaky.androidide.models
|
||||
import android.view.View
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import com.itsaky.androidide.resources.R
|
||||
import java.util.Collections
|
||||
|
||||
/**
|
||||
* An action button shown on the main screen.
|
||||
@@ -28,4 +30,75 @@ import androidx.annotation.StringRes
|
||||
*/
|
||||
data class MainScreenAction
|
||||
@JvmOverloads
|
||||
constructor(@StringRes val text: Int, @DrawableRes val icon: Int, val onClick: (View) -> Unit = {})
|
||||
constructor(
|
||||
val id: Int,
|
||||
@StringRes val text: Int,
|
||||
@DrawableRes val icon: Int,
|
||||
var onClick: ((MainScreenAction, View) -> Unit)? = null
|
||||
) {
|
||||
|
||||
companion object {
|
||||
|
||||
const val ACTION_CREATE_PROJECT = 0
|
||||
const val ACTION_OPEN_PROJECT = 1
|
||||
const val ACTION_CLONE_REPO = 2
|
||||
const val ACTION_OPEN_TERMINAL = 3
|
||||
const val ACTION_PREFERENCES = 4
|
||||
const val ACTION_DONATE = 5
|
||||
const val ACTION_DOCS = 6
|
||||
|
||||
/**
|
||||
* Get all main screen actions.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun all(): List<MainScreenAction> {
|
||||
return mutableListOf<MainScreenAction>().apply {
|
||||
val createProject = MainScreenAction(
|
||||
ACTION_CREATE_PROJECT,
|
||||
R.string.create_project,
|
||||
R.drawable.ic_add)
|
||||
|
||||
val openProject = MainScreenAction(
|
||||
ACTION_OPEN_PROJECT,
|
||||
R.string.msg_open_existing_project,
|
||||
R.drawable.ic_folder)
|
||||
|
||||
val cloneGitRepository = MainScreenAction(
|
||||
ACTION_CLONE_REPO,
|
||||
R.string.git_clone_repo,
|
||||
R.drawable.ic_git)
|
||||
|
||||
val openTerminal = MainScreenAction(
|
||||
ACTION_OPEN_TERMINAL,
|
||||
R.string.title_terminal,
|
||||
R.drawable.ic_terminal)
|
||||
|
||||
val preferences = MainScreenAction(
|
||||
ACTION_PREFERENCES,
|
||||
R.string.msg_preferences,
|
||||
R.drawable.ic_settings)
|
||||
|
||||
val donate = MainScreenAction(
|
||||
ACTION_DONATE,
|
||||
R.string.btn_donate,
|
||||
R.drawable.ic_donate
|
||||
)
|
||||
|
||||
val docs = MainScreenAction(
|
||||
ACTION_DOCS,
|
||||
R.string.btn_docs,
|
||||
R.drawable.ic_docs)
|
||||
|
||||
Collections.addAll(this,
|
||||
createProject,
|
||||
openProject,
|
||||
cloneGitRepository,
|
||||
openTerminal,
|
||||
preferences,
|
||||
donate,
|
||||
docs
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ public class BaseApplication extends Application {
|
||||
openUrl(BuildInfo.PROJECT_SITE);
|
||||
}
|
||||
|
||||
public void openSponsors() {
|
||||
public void openDonationsPage() {
|
||||
openUrl(SPONSOR_URL);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ androidx-navigation = "2.5.3"
|
||||
ksp = "1.9.10-1.0.13"
|
||||
antlr4 = "4.13.1"
|
||||
androidx-work = "2.8.1"
|
||||
androidx-espresso = "3.5.1"
|
||||
retrofit = "2.9.0"
|
||||
|
||||
[libraries]
|
||||
@@ -113,7 +114,9 @@ tests-androidx-test-runner = { module = "androidx.test:runner", version = "1.5.2
|
||||
tests-androidx-test-rules = { module = "androidx.test:rules", version = "1.5.0" }
|
||||
tests-androidx-junit = { module = "androidx.test.ext:junit", version = "1.1.5" }
|
||||
tests-androidx-work-testing = { module = "androidx.work:work-testing", version.ref = "androidx-work" }
|
||||
tests-androidx-espresso = { module = "androidx.test.espresso:espresso-core", version = "3.5.1" }
|
||||
tests-androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso" }
|
||||
tests-androidx-espresso-contrib = { module = "androidx.test.espresso:espresso-contrib", version.ref = "androidx-espresso" }
|
||||
tests-androidx-uiautomator = { module = "androidx.test.uiautomator:uiautomator", version = "2.2.0" }
|
||||
tests-mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version = "5.1.0" }
|
||||
tests-mockk = { module = "io.mockk:mockk", version = "1.13.8" }
|
||||
|
||||
|
||||
@@ -58,15 +58,6 @@ dependencies {
|
||||
|
||||
implementation(libs.androidx.ktx)
|
||||
implementation(libs.common.kotlin)
|
||||
|
||||
testImplementation(projects.lsp.testing)
|
||||
testImplementation(projects.common)
|
||||
testImplementation(projects.actions)
|
||||
testImplementation(projects.subprojects.javac)
|
||||
testImplementation(libs.tests.junit)
|
||||
testImplementation(libs.tests.google.truth)
|
||||
testImplementation(libs.tests.robolectric)
|
||||
androidTestImplementation(libs.tests.androidx.junit)
|
||||
androidTestImplementation(libs.tests.androidx.espresso)
|
||||
androidTestImplementation(libs.tests.google.truth)
|
||||
|
||||
testImplementation(projects.testing.lsp)
|
||||
}
|
||||
@@ -49,21 +49,12 @@ dependencies {
|
||||
implementation(libs.androidx.ktx)
|
||||
implementation(libs.common.kotlin)
|
||||
implementation(libs.google.material)
|
||||
|
||||
|
||||
testImplementation(projects.actions)
|
||||
testImplementation(projects.subprojects.projects)
|
||||
testImplementation(projects.subprojects.toolingApi)
|
||||
testImplementation(projects.lsp.testing)
|
||||
testImplementation(projects.common)
|
||||
testImplementation(projects.actions)
|
||||
testImplementation(libs.tests.androidx.test.core)
|
||||
testImplementation(libs.tests.junit)
|
||||
testImplementation(libs.tests.google.truth)
|
||||
testImplementation(libs.tests.robolectric)
|
||||
androidTestImplementation(libs.tests.androidx.junit)
|
||||
androidTestImplementation(libs.tests.androidx.espresso)
|
||||
androidTestImplementation(libs.tests.google.truth)
|
||||
|
||||
testImplementation(projects.testing.lsp)
|
||||
|
||||
compileOnly(projects.common)
|
||||
|
||||
compileOnly(libs.common.antlr4)
|
||||
}
|
||||
|
||||
+5
-3
@@ -73,7 +73,6 @@ include(
|
||||
":lsp:models",
|
||||
":lsp:java",
|
||||
":lsp:xml",
|
||||
":lsp:testing",
|
||||
":subprojects:aaptcompiler",
|
||||
":subprojects:builder-model-impl",
|
||||
":subprojects:flashbar",
|
||||
@@ -94,7 +93,10 @@ include(
|
||||
":subprojects:tooling-api-events",
|
||||
":subprojects:tooling-api-impl",
|
||||
":subprojects:tooling-api-model",
|
||||
":subprojects:tooling-api-testing",
|
||||
":subprojects:xml-dom",
|
||||
":subprojects:xml-utils"
|
||||
":subprojects:xml-utils",
|
||||
":testing:android",
|
||||
":testing:lsp",
|
||||
":testing:tooling",
|
||||
":testing:unit",
|
||||
)
|
||||
|
||||
@@ -62,13 +62,16 @@ class FileProvider {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private fun testsDir(): Path = projectRoot().resolve("tests")
|
||||
private fun testingDir() = projectRoot().resolve("testing")
|
||||
|
||||
@JvmStatic
|
||||
fun testHomeDir(): Path = testsDir().resolve("test-home")
|
||||
private fun testReourcessDir(): Path = testingDir().resolve("resources")
|
||||
|
||||
@JvmStatic
|
||||
fun testProjectRoot(): Path = testsDir().resolve("test-project")
|
||||
fun testHomeDir(): Path = testReourcessDir().resolve("test-home")
|
||||
|
||||
@JvmStatic
|
||||
fun testProjectRoot(): Path = testReourcessDir().resolve("test-project")
|
||||
|
||||
/**
|
||||
* Get the path to the 'resources' directory.
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.utils
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> uncheckedCast(obj: Any): T {
|
||||
return obj as T
|
||||
}
|
||||
@@ -36,12 +36,5 @@ dependencies {
|
||||
implementation(libs.google.auto.service.annotations)
|
||||
implementation(libs.google.guava)
|
||||
|
||||
testImplementation(projects.subprojects.toolingApiTesting)
|
||||
testImplementation(projects.shared)
|
||||
testImplementation(libs.tests.junit)
|
||||
testImplementation(libs.tests.google.truth)
|
||||
testImplementation(libs.tests.robolectric)
|
||||
androidTestImplementation(libs.tests.androidx.junit)
|
||||
androidTestImplementation(libs.tests.androidx.espresso)
|
||||
androidTestImplementation(libs.tests.google.truth)
|
||||
testImplementation(projects.testing.tooling)
|
||||
}
|
||||
@@ -55,19 +55,17 @@ project.tasks.getByName("jar") {
|
||||
project.tasks.getByName("shadowJar") { finalizedBy("copyJar") }
|
||||
|
||||
dependencies {
|
||||
api(projects.subprojects.toolingApi)
|
||||
|
||||
implementation(projects.buildInfo)
|
||||
implementation(projects.shared)
|
||||
implementation(projects.subprojects.toolingApi)
|
||||
|
||||
implementation(libs.common.jkotlin)
|
||||
implementation(libs.xml.xercesImpl)
|
||||
implementation(libs.xml.apis)
|
||||
implementation(libs.tooling.gradleApi)
|
||||
|
||||
testImplementation(projects.subprojects.toolingApiTesting)
|
||||
testImplementation(projects.shared)
|
||||
testImplementation(libs.tests.junit)
|
||||
testImplementation(libs.tests.google.truth)
|
||||
testImplementation(projects.testing.tooling)
|
||||
|
||||
runtimeOnly(libs.tooling.slf4j)
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id 'groovy-gradle-plugin'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
group "com.itsaky.androidide"
|
||||
version "1.0.0"
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
url new File (project.buildDir, "repo")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
androidide {
|
||||
id = "com.itsaky.androidide"
|
||||
implementationClass = "com.itsaky.androidide.tooling.plugin.AndroidIDEToolingApiPlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task copyToTestDir (type: Copy) {
|
||||
from "$project.buildDir.absolutePath/libs/tooling-api-plugin-${version}.jar"
|
||||
into "${project.rootProject.file ("tests/test-home/.androidide/init").absolutePath}/"
|
||||
rename {
|
||||
"plugin.jar"
|
||||
}
|
||||
|
||||
outputs.upToDateWhen {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
project.tasks.jar {
|
||||
finalizedBy project.tasks.publish
|
||||
}
|
||||
|
||||
project.tasks.publish {
|
||||
finalizedBy copyToTestDir
|
||||
outputs.upToDateWhen {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project (path: ':subprojects:tooling-api-model')
|
||||
}
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.tooling.plugin;
|
||||
|
||||
import com.itsaky.androidide.tooling.api.model.IdeProject;
|
||||
import com.itsaky.androidide.tooling.api.model.ProjectDependency;
|
||||
import com.itsaky.androidide.tooling.api.model.internal.DefaultIdeProject;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.tooling.provider.model.ToolingModelBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
public class IdeProjectModelBuilder implements ToolingModelBuilder {
|
||||
|
||||
@Override
|
||||
public boolean canBuild(String s) {
|
||||
return IdeProject.class.getName().equals(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object buildAll(String s, Project project) {
|
||||
final var ideProject = new DefaultIdeProject();
|
||||
fillProjectDetails(project, ideProject);
|
||||
return ideProject;
|
||||
}
|
||||
|
||||
private void fillProjectDetails(Project project, DefaultIdeProject ideProject) {
|
||||
ideProject.setPath(project.getPath());
|
||||
ideProject.setDisplayName(project.getDisplayName());
|
||||
ideProject.setProjectDir(project.getProjectDir());
|
||||
ideProject.setBuildDir(project.getBuildDir());
|
||||
ideProject.setBuildFile(project.getBuildFile());
|
||||
ideProject.setDependencies(getDependencies(project));
|
||||
ideProject.setSubProjects(getSubProjects(project));
|
||||
}
|
||||
|
||||
private List<ProjectDependency> getDependencies(Project project) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<IdeProject> getSubProjects(Project project) {
|
||||
final var projects = new ArrayList<IdeProject>();
|
||||
project
|
||||
.getSubprojects()
|
||||
.forEach(
|
||||
sub -> {
|
||||
final var subProject = new DefaultIdeProject();
|
||||
fillProjectDetails(sub, subProject);
|
||||
projects.add(subProject);
|
||||
});
|
||||
return projects;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,4 @@ dependencies {
|
||||
api(libs.google.gson)
|
||||
api(libs.common.jsonrpc)
|
||||
implementation(libs.common.jkotlin)
|
||||
|
||||
testImplementation(libs.tests.junit)
|
||||
testImplementation(libs.tests.google.truth)
|
||||
}
|
||||
|
||||
@@ -323,7 +323,15 @@ class EnumParameter<T : Enum<*>>(@StringRes name: Int,
|
||||
val displayName: ((T) -> String)? = null,
|
||||
val filter: ((T) -> Boolean)? = null
|
||||
) : TextFieldParameter<T>(name, description, default, startIcon, endIcon,
|
||||
onStartIconClick, onEndIconClick, constraints)
|
||||
onStartIconClick, onEndIconClick, constraints) {
|
||||
|
||||
/**
|
||||
* Get the display name for this [EnumParameter].
|
||||
*/
|
||||
fun getDisplayName(): String? {
|
||||
return this.displayName?.invoke(value)
|
||||
}
|
||||
}
|
||||
|
||||
class EnumParameterBuilder<T : Enum<*>> : TextFieldParameterBuilder<T>() {
|
||||
|
||||
|
||||
@@ -38,15 +38,9 @@ dependencies {
|
||||
implementation(libs.androidx.ktx)
|
||||
implementation(libs.google.auto.service.annotations)
|
||||
|
||||
testImplementation(projects.common)
|
||||
testImplementation(projects.templatesApi)
|
||||
testImplementation(projects.lsp.api)
|
||||
testImplementation(projects.preferences)
|
||||
testImplementation(projects.shared)
|
||||
testImplementation(projects.subprojects.toolingApiTesting)
|
||||
testImplementation(libs.tests.androidx.test.core)
|
||||
testImplementation(libs.tests.google.truth)
|
||||
testImplementation(libs.tests.junit)
|
||||
testImplementation(libs.tests.mockk)
|
||||
testImplementation(libs.tests.robolectric)
|
||||
testImplementation(projects.testing.unit)
|
||||
testImplementation(projects.testing.tooling)
|
||||
}
|
||||
+24
-25
@@ -15,29 +15,28 @@
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.tooling.plugin;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class AndroidIDEToolingApiPlugin implements Plugin<Project> {
|
||||
|
||||
private final ToolingModelBuilderRegistry registry;
|
||||
|
||||
@Inject
|
||||
public AndroidIDEToolingApiPlugin(ToolingModelBuilderRegistry registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
if (project != project.getRootProject()) {
|
||||
return;
|
||||
}
|
||||
|
||||
registry.register(new IdeProjectModelBuilder());
|
||||
}
|
||||
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
|
||||
plugins {
|
||||
id("com.android.library")
|
||||
kotlin("android")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "${BuildConfig.packageName}.testing.android"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(libs.tests.androidx.test.core)
|
||||
api(libs.tests.androidx.test.runner)
|
||||
api(libs.tests.androidx.test.rules)
|
||||
api(libs.tests.androidx.junit)
|
||||
api(libs.tests.androidx.espresso.core)
|
||||
api(libs.tests.androidx.espresso.contrib)
|
||||
api(libs.tests.androidx.uiautomator)
|
||||
api(libs.tests.junit)
|
||||
api(libs.tests.google.truth)
|
||||
|
||||
api(projects.buildInfo)
|
||||
api(projects.common)
|
||||
api(projects.shared)
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
+7
-20
@@ -15,27 +15,14 @@
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.projects
|
||||
package com.itsaky.androidide.testing.android
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
import android.content.Context
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
* Get the value of the string resource.
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.itsaky.androidide.projects.test", appContext.packageName)
|
||||
}
|
||||
}
|
||||
fun stringRes(@StringRes resource: Int, vararg formatArgs: Any) =
|
||||
ApplicationProvider.getApplicationContext<Context>().getString(resource, *formatArgs)
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.testing.android
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry
|
||||
import androidx.test.runner.lifecycle.Stage
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.Until
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.itsaky.androidide.app.BaseApplication
|
||||
import com.itsaky.androidide.buildinfo.BuildInfo
|
||||
import com.itsaky.androidide.utils.uncheckedCast
|
||||
|
||||
const val LAUNCH_TIMEOUT = 5000L
|
||||
|
||||
/**
|
||||
* Launches the AndroidIDE application using UI Automator.
|
||||
*
|
||||
* @param fromLauncher Whether the application must be launched from the Android launcher.
|
||||
* @param clearTasks Whether the application's previous tasks must be cleared.
|
||||
*/
|
||||
fun launchAndroidIDE(
|
||||
fromLauncher: Boolean = true,
|
||||
clearTasks: Boolean = true,
|
||||
): UiDevice {
|
||||
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
|
||||
if (fromLauncher) {
|
||||
device.pressHome()
|
||||
|
||||
val launcherPackage = device.launcherPackageName
|
||||
assertThat(launcherPackage).isNotNull()
|
||||
|
||||
device.wait(
|
||||
Until.hasObject(By.pkg(launcherPackage).depth(0)),
|
||||
LAUNCH_TIMEOUT
|
||||
)
|
||||
}
|
||||
|
||||
// Launch the app
|
||||
val context = ApplicationProvider.getApplicationContext<BaseApplication>()
|
||||
val intent = context.packageManager.getLaunchIntentForPackage(BuildInfo.PACKAGE_NAME)
|
||||
assertThat(intent).isNotNull()
|
||||
|
||||
if (clearTasks) {
|
||||
intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
}
|
||||
|
||||
context.startActivity(intent)
|
||||
|
||||
// Wait for the app to appear
|
||||
device.wait(
|
||||
Until.hasObject(By.pkg(BuildInfo.PACKAGE_NAME).depth(0)),
|
||||
LAUNCH_TIMEOUT
|
||||
)
|
||||
|
||||
return device
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first activity in the given [stage].
|
||||
*/
|
||||
fun <T : Activity> getActivityInStage(stage: Stage): T? {
|
||||
var activity: T? = null
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
val activities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(stage)
|
||||
if (activities.isNotEmpty()) {
|
||||
activity = uncheckedCast(activities.first())
|
||||
}
|
||||
}
|
||||
|
||||
return activity
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.testing.android
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.UiObject2
|
||||
import com.itsaky.androidide.buildinfo.BuildInfo
|
||||
|
||||
/**
|
||||
* @see UiDevice.waitForWindowUpdate
|
||||
*/
|
||||
fun UiDevice.waitForWindowUpdate(timeout: Long) =
|
||||
waitForWindowUpdate(BuildInfo.PACKAGE_NAME, timeout)
|
||||
|
||||
/**
|
||||
* @see UiDevice.hasObject
|
||||
*/
|
||||
fun UiDevice.hasObjectWithText(text: String) =
|
||||
hasObject(By.text(text))
|
||||
|
||||
/**
|
||||
* @see UiDevice.hasObject
|
||||
*/
|
||||
fun UiDevice.hasObjectWithText(@StringRes text: Int) =
|
||||
hasObject(By.text(stringRes(text)))
|
||||
|
||||
/**
|
||||
* @see UiDevice.findObject
|
||||
*/
|
||||
fun UiDevice.findObjectWithText(text: String): UiObject2? =
|
||||
findObject(By.text(text))
|
||||
|
||||
/**
|
||||
* @see UiDevice.findObjectWithText
|
||||
*/
|
||||
fun UiDevice.findObjectWithText(@StringRes text: Int): UiObject2? =
|
||||
findObject(By.text(stringRes(text)))
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.testing.android
|
||||
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.UiObject2
|
||||
import androidx.test.uiautomator.Until
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
|
||||
/**
|
||||
* Click this object and wait for window update with the given timeout duration.
|
||||
*
|
||||
* @see UiDevice.waitForWindowUpdate
|
||||
*/
|
||||
fun UiObject2?.clickAndWaitForWindowUpdate(device: UiDevice, timeout: Long = 500L) =
|
||||
run {
|
||||
assertThat(this).isNotNull()
|
||||
this!!.click()
|
||||
device.waitForWindowUpdate(timeout)
|
||||
}
|
||||
|
||||
/**
|
||||
* Click this object and wait for a new window to appear within the given timeout duration.
|
||||
*
|
||||
* @see UiObject2.clickAndWait
|
||||
*/
|
||||
fun UiObject2?.clickAndWaitForNewWindow(timeout: Long = LAUNCH_TIMEOUT) =
|
||||
run {
|
||||
assertThat(this).isNotNull()
|
||||
this!!.clickAndWait(Until.newWindow(), timeout)
|
||||
}
|
||||
@@ -25,19 +25,14 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.androidx.ktx)
|
||||
implementation(libs.common.kotlin)
|
||||
api(libs.androidx.ktx)
|
||||
api(libs.common.kotlin)
|
||||
|
||||
implementation(projects.lsp.api)
|
||||
implementation(projects.actions)
|
||||
implementation(projects.common)
|
||||
implementation(projects.eventbusAndroid)
|
||||
implementation(projects.subprojects.toolingApiTesting)
|
||||
implementation(projects.shared)
|
||||
api(projects.lsp.api)
|
||||
api(projects.actions)
|
||||
api(projects.eventbusAndroid)
|
||||
|
||||
implementation(libs.common.editor)
|
||||
implementation(libs.tests.junit)
|
||||
implementation(libs.tests.google.truth)
|
||||
implementation(libs.tests.robolectric)
|
||||
implementation(libs.tests.mockk)
|
||||
api(libs.common.editor)
|
||||
api(projects.testing.tooling)
|
||||
api(projects.testing.unit)
|
||||
}
|
||||
Vendored
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user