diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LandscapeIntegrationTest.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LandscapeIntegrationTest.kt index 11c0738fda..0b9655f742 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LandscapeIntegrationTest.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LandscapeIntegrationTest.kt @@ -34,6 +34,7 @@ import androidx.test.espresso.action.ViewActions.scrollTo import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.idling.CountingIdlingResource import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.espresso.matcher.ViewMatchers.withClassName import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText @@ -44,6 +45,8 @@ import org.catrobat.paintroid.R import org.catrobat.paintroid.colorpicker.HSVColorPickerView import org.catrobat.paintroid.colorpicker.PresetSelectorView import org.catrobat.paintroid.colorpicker.RgbSelectorView +import org.catrobat.paintroid.test.espresso.util.EspressoUtils +import org.catrobat.paintroid.test.espresso.util.UiInteractions.waitFor import org.catrobat.paintroid.test.espresso.util.UiMatcher.withBackground import org.catrobat.paintroid.test.espresso.util.UiMatcher.withBackgroundColor import org.catrobat.paintroid.test.espresso.util.wrappers.BottomNavigationViewInteraction.Companion.onBottomNavigationView @@ -57,7 +60,6 @@ import org.catrobat.paintroid.tools.ToolType import org.catrobat.paintroid.tools.options.ToolOptionsViewController import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.`is` -import org.hamcrest.Matchers.not import org.junit.After import org.junit.Assert.assertEquals import org.junit.Before @@ -97,7 +99,7 @@ class LandscapeIntegrationTest { } @Test - fun testTools() { + fun testIfClickingOnCurrentToolTogglesToolOptions() { setOrientation(SCREEN_ORIENTATION_LANDSCAPE) for (toolType in ToolType.values()) { val tool = toolType == ToolType.IMPORTPNG || @@ -105,18 +107,22 @@ class LandscapeIntegrationTest { toolType == ToolType.REDO || toolType == ToolType.UNDO || toolType == ToolType.LAYER || + toolType == ToolType.CLIPBOARD || + toolType == ToolType.TEXT || !toolType.hasOptions() if (tool) { continue } onToolBarView() .performSelectTool(toolType) - if (toolOptionsViewController?.isVisible?.not() == true) { + if (toolOptionsViewController?.isVisible == false) { onToolBarView() .performClickSelectedToolButton() } onBottomNavigationView() .onCurrentClicked() - onView(withId(R.id.pocketpaint_layout_tool_specific_options)) - .check(matches(not(isDisplayed()))) + EspressoUtils.waitForViewToDisappear(withId(R.id.pocketpaint_layout_tool_specific_options)) + // BaseRobot().waitForViewToDisappear(withId(R.id.pocketpaint_layout_tool_specific_options)).check(matches(not(isDisplayed()))) +// onView(withId(R.id.pocketpaint_layout_tool_specific_options)) +// .check(matches(not(isDisplayed()))) } } @@ -408,6 +414,7 @@ class LandscapeIntegrationTest { @Test fun testIfCurrentToolIsShownInBottomNavigation() { setOrientation(SCREEN_ORIENTATION_LANDSCAPE) + onView(isRoot()).perform(waitFor(5000)) for (toolType in ToolType.values()) { val tools = toolType == ToolType.IMPORTPNG || toolType == ToolType.COLORCHOOSER || @@ -416,15 +423,39 @@ class LandscapeIntegrationTest { toolType == ToolType.LAYER || !toolType.hasOptions() if (tools) { continue } + onView(isRoot()).perform(waitFor(5000)) onToolBarView() .performSelectTool(toolType) - onBottomNavigationView() - .checkShowsCurrentTool(toolType) + onView(isRoot()).perform(waitFor(500)) + onBottomNavigationView().checkShowsCurrentTool(toolType) + onView(isRoot()).perform(waitFor(5000)) } } private fun setOrientation(orientation: Int) { activityTestRule.activity.requestedOrientation = orientation } + /*private fun checkShowsCurrentTool(toolType: ToolType) { + var matcher = allOf(withId(R.id.icon), + ViewMatchers.isDescendantOfA(withId(R.id.action_current_tool)) + ) + var assertion = ViewAssertions.matches( + Matchers.allOf( + isDisplayed(), + UiMatcher.withDrawable(toolType.drawableResource) + ) + ) + EspressoUtils.assertOnView(matcher, assertion) + + matcher = withId(R.id.action_current_tool) + assertion = ViewAssertions.matches( + Matchers.allOf( + isDisplayed(), + ViewMatchers.hasDescendant(withText(toolType.nameResource)) + ) + ) + EspressoUtils.assertOnView(matcher, assertion) + }*/ + companion object { @ColorInt private fun getColorArrayFromResource(context: Context, @ArrayRes id: Int): IntArray { diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LayerIntegrationTest.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LayerIntegrationTest.kt index da096f3772..6915619394 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LayerIntegrationTest.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/LayerIntegrationTest.kt @@ -583,7 +583,8 @@ class LayerIntegrationTest { LayerMenuViewInteraction.onLayerMenuView() .performOpen() .performSetOpacityTo(50, 0) - .performClose() + + LayerMenuViewInteraction.onLayerMenuView().performClose() ToolBarViewInteraction.onToolBarView() .performSelectTool(ToolType.PIPETTE) diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MoreOptionsIntegrationTest.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MoreOptionsIntegrationTest.kt index 7beb1c5c94..87c41ce705 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MoreOptionsIntegrationTest.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/MoreOptionsIntegrationTest.kt @@ -23,8 +23,10 @@ import android.app.Instrumentation.ActivityResult import android.content.Context import android.content.Intent import androidx.test.espresso.Espresso +import androidx.test.espresso.IdlingRegistry import androidx.test.espresso.action.ViewActions import androidx.test.espresso.assertion.ViewAssertions +import androidx.test.espresso.idling.CountingIdlingResource import androidx.test.espresso.intent.Intents import androidx.test.espresso.intent.matcher.IntentMatchers import androidx.test.espresso.matcher.RootMatchers @@ -65,9 +67,22 @@ class MoreOptionsIntegrationTest { @JvmField @Rule var screenshotOnFailRule = ScreenshotOnFailRule() + + private var idlingResource: CountingIdlingResource? = null + private var mainActivity: MainActivity? = null var defaultPictureName = "moreOptionsImageTest" + + companion object { + @JvmField + @ClassRule + var grantPermissionRule = grantPermissionRulesVersionCheck() + } + @Before fun setUp() { + mainActivity = activityTestRule.activity + idlingResource = mainActivity?.idlingResource + IdlingRegistry.getInstance().register(idlingResource) TopBarViewInteraction.onTopBarView() .performOpenMoreOptions() activityTestRule.activity.getPreferences(Context.MODE_PRIVATE) @@ -78,6 +93,7 @@ class MoreOptionsIntegrationTest { @After fun tearDown() { + IdlingRegistry.getInstance().unregister(idlingResource) activityTestRule.activity.getPreferences(Context.MODE_PRIVATE) .edit() .clear() @@ -275,10 +291,4 @@ class MoreOptionsIntegrationTest { Espresso.onView(withText(R.string.cancel_button_text)).perform(ViewActions.click()) Assert.assertTrue("Smoothing is off after cancel!", AdvancedSettingsAlgorithms.smoothing) } - - companion object { - @JvmField - @ClassRule - var grantPermissionRule = grantPermissionRulesVersionCheck() - } } diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/TemporaryFileSavingTest.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/TemporaryFileSavingTest.kt index d96adb9a2e..6d7231a1b3 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/TemporaryFileSavingTest.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/TemporaryFileSavingTest.kt @@ -21,8 +21,12 @@ package org.catrobat.paintroid.test.espresso import android.content.Intent import android.graphics.Color import androidx.test.espresso.Espresso +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.IdlingRegistry import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.idling.CountingIdlingResource import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.rule.ActivityTestRule import org.catrobat.paintroid.MainActivity @@ -31,6 +35,7 @@ import org.catrobat.paintroid.common.TEMP_IMAGE_PATH import org.catrobat.paintroid.test.espresso.util.BitmapLocationProvider import org.catrobat.paintroid.test.espresso.util.DrawingSurfaceLocationProvider import org.catrobat.paintroid.test.espresso.util.UiInteractions +import org.catrobat.paintroid.test.espresso.util.UiInteractions.waitFor import org.catrobat.paintroid.test.espresso.util.wrappers.DrawingSurfaceInteraction.Companion.onDrawingSurfaceView import org.catrobat.paintroid.test.espresso.util.wrappers.ToolBarViewInteraction import org.catrobat.paintroid.test.espresso.util.wrappers.TopBarViewInteraction @@ -38,6 +43,7 @@ import org.catrobat.paintroid.tools.ToolReference import org.catrobat.paintroid.tools.ToolType import org.catrobat.paintroid.tools.Workspace import org.catrobat.paintroid.ui.Perspective +import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test @@ -58,13 +64,17 @@ class TemporaryFileSavingTest { private lateinit var toolReference: ToolReference private lateinit var mainActivity: MainActivity private lateinit var intent: Intent + private var idlingResource: CountingIdlingResource? = null @Before fun setUp() { - ToolBarViewInteraction.onToolBarView() - .performSelectTool(ToolType.BRUSH) intent = Intent().putExtra("isTemporaryFileSavingTest", true) mainActivity = launchActivityRule.launchActivity(intent) + idlingResource = mainActivity.idlingResource + IdlingRegistry.getInstance().register(idlingResource) + ToolBarViewInteraction.onToolBarView() + .performSelectTool(ToolType.BRUSH) + workspace = mainActivity.workspace perspective = mainActivity.perspective toolReference = mainActivity.toolReference @@ -74,6 +84,9 @@ class TemporaryFileSavingTest { } } + @After + fun tearDown() { IdlingRegistry.getInstance().unregister(idlingResource) } + @Test fun testOneUserInteraction() { onDrawingSurfaceView() @@ -110,15 +123,20 @@ class TemporaryFileSavingTest { fun testMultipleUserInteractions() { onDrawingSurfaceView() .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.MIDDLE)) + onView(isRoot()).perform(waitFor(1000)) onDrawingSurfaceView() .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.HALFWAY_TOP_LEFT)) - Thread.sleep(THREAD_WAITING_TIME) + onView(isRoot()).perform(waitFor(1000)) onDrawingSurfaceView() .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.HALFWAY_BOTTOM_RIGHT)) - Thread.sleep(THREAD_WAITING_TIME) + onView(isRoot()).perform(waitFor(1000)) onDrawingSurfaceView() .perform(UiInteractions.touchAt(DrawingSurfaceLocationProvider.HALFWAY_BOTTOM_LEFT)) + Thread.sleep(4000) + onView(isRoot()).perform(waitFor(5000)) launchActivityRule.finishActivity() + onView(isRoot()).perform(waitFor(1000)) + Thread.sleep(1000) launchActivityRule.launchActivity(intent) onDrawingSurfaceView() .checkPixelColor(Color.BLACK, BitmapLocationProvider.MIDDLE) diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/ImportToolIntegrationTest.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/ImportToolIntegrationTest.kt index 2dc62bf6bf..6546e10627 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/ImportToolIntegrationTest.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/tools/ImportToolIntegrationTest.kt @@ -21,17 +21,21 @@ package org.catrobat.paintroid.test.espresso.tools import androidx.test.espresso.Espresso +import androidx.test.espresso.IdlingRegistry import androidx.test.espresso.action.ViewActions import androidx.test.espresso.assertion.ViewAssertions +import androidx.test.espresso.idling.CountingIdlingResource import androidx.test.espresso.matcher.ViewMatchers import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.rule.ActivityTestRule import org.catrobat.paintroid.MainActivity import org.catrobat.paintroid.R import org.catrobat.paintroid.test.espresso.rtl.util.RtlActivityTestRule +import org.catrobat.paintroid.test.espresso.util.ViewRobot import org.catrobat.paintroid.test.espresso.util.wrappers.ToolBarViewInteraction import org.catrobat.paintroid.test.utils.ScreenshotOnFailRule import org.catrobat.paintroid.tools.ToolType +import org.junit.After import org.junit.Assert import org.junit.Before import org.junit.Rule @@ -47,14 +51,21 @@ class ImportToolIntegrationTest { @get:Rule var screenshotOnFailRule = ScreenshotOnFailRule() private var mainActivity: MainActivity? = null + private var idlingResource: CountingIdlingResource? = null + @Before fun setUp() { mainActivity = launchActivityRule.activity - ToolBarViewInteraction.onToolBarView().performSelectTool(ToolType.IMPORTPNG) + idlingResource = mainActivity?.idlingResource + IdlingRegistry.getInstance().register(idlingResource) } + @After + fun tearDown() { IdlingRegistry.getInstance().unregister(idlingResource) } + @Test fun testImportDialogShownOnImportToolSelected() { + ToolBarViewInteraction.onToolBarView().performSelectTool(ToolType.IMPORTPNG) Espresso.onView(ViewMatchers.withId(R.id.pocketpaint_dialog_import_stickers)) .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) Espresso.onView(ViewMatchers.withId(R.id.pocketpaint_dialog_import_gallery)) @@ -63,8 +74,6 @@ class ImportToolIntegrationTest { @Test fun testImportDialogDismissedOnCancelClicked() { - Espresso.onView(ViewMatchers.withText(R.string.pocketpaint_cancel)) - .perform(ViewActions.click()) Espresso.onView(ViewMatchers.withId(R.id.pocketpaint_dialog_import_stickers)) .check(ViewAssertions.doesNotExist()) Espresso.onView(ViewMatchers.withId(R.id.pocketpaint_dialog_import_gallery)) @@ -73,8 +82,6 @@ class ImportToolIntegrationTest { @Test fun testImportDoesNotResetPerspectiveScale() { - Espresso.onView(ViewMatchers.withText(R.string.pocketpaint_cancel)) - .perform(ViewActions.click()) ToolBarViewInteraction.onToolBarView() .performSelectTool(ToolType.BRUSH) val scale = 2.0f @@ -82,8 +89,7 @@ class ImportToolIntegrationTest { mainActivity?.refreshDrawingSurface() ToolBarViewInteraction.onToolBarView() .performSelectTool(ToolType.IMPORTPNG) - Espresso.onView(ViewMatchers.withText(R.string.pocketpaint_cancel)) - .perform(ViewActions.click()) + ViewRobot().doOnView(ViewMatchers.withText(R.string.pocketpaint_cancel), ViewActions.click()) mainActivity?.perspective?.let { Assert.assertEquals(scale, it.scale, Float.MIN_VALUE) } } } diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/EspressoUtils.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/EspressoUtils.kt index f40903af83..cd5adb7d2d 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/EspressoUtils.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/EspressoUtils.kt @@ -24,12 +24,17 @@ import android.app.Activity import android.content.res.Configuration import android.graphics.PointF import android.os.Build +import android.os.SystemClock import android.util.TypedValue import android.view.View import androidx.test.espresso.Espresso +import androidx.test.espresso.Espresso.onView import androidx.test.espresso.NoMatchingViewException +import androidx.test.espresso.UiController +import androidx.test.espresso.ViewAction +import androidx.test.espresso.ViewAssertion import androidx.test.espresso.assertion.ViewAssertions -import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.platform.app.InstrumentationRegistry import androidx.test.rule.GrantPermissionRule import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry @@ -37,6 +42,10 @@ import androidx.test.runner.lifecycle.Stage import org.catrobat.paintroid.MainActivity import org.hamcrest.Matcher import org.junit.Assert +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.isRoot +import androidx.test.espresso.util.TreeIterables +import org.hamcrest.Matchers.not object EspressoUtils { const val DEFAULT_STROKE_WIDTH = 25 @@ -87,19 +96,55 @@ object EspressoUtils { val viewInteraction = Espresso.onView(viewMatcher).inRoot(UiMatcher.isToast) while (System.currentTimeMillis() < waitTime) { try { - viewInteraction.check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + viewInteraction.check(ViewAssertions.matches(isDisplayed())) return } catch (e: NoMatchingViewException) { - Espresso.onView(ViewMatchers.isRoot()).perform(UiInteractions.waitFor(250)) + Espresso.onView(isRoot()).perform(UiInteractions.waitFor(250)) + } + } + viewInteraction.check(ViewAssertions.matches(isDisplayed())) + } + + @SuppressWarnings("SwallowedException") + fun waitForViewToDisappear( + viewMatcher: org.hamcrest.Matcher, + timeoutMillis: Long = 10_000, // Default timeout 10 seconds + pollIntervalMillis: Long = 100 // Default poll interval 100 ms + ) { + val endTime = System.currentTimeMillis() + timeoutMillis + var viewFound = true // Assume view is initially present + + while (System.currentTimeMillis() < endTime && viewFound) { + try { + // Check if the view is still displayed + onView(viewMatcher).check(matches(isDisplayed())) + // If the check passes, the view is still displayed. + // Wait for a short interval before trying again. + onView(isRoot()).perform(UiInteractions.waitFor(pollIntervalMillis)) + } catch (e: NoMatchingViewException) { + // View is not found in the hierarchy, so it has "disappeared" in this sense. + viewFound = false + } catch (e: AssertionError) { + // View is in the hierarchy but not displayed (e.g., GONE, INVISIBLE). + // This also means it has "disappeared" for the user. + viewFound = false + } + } + + if (viewFound) { + try { + onView(viewMatcher).check(matches(not(isDisplayed()))) + } catch (e: NoMatchingViewException) { + // This is acceptable, means it's not in hierarchy } } - viewInteraction.check(ViewAssertions.matches(ViewMatchers.isDisplayed())) } val configuration: Configuration get() = InstrumentationRegistry.getInstrumentation().targetContext.resources.configuration fun grantPermissionRulesVersionCheck(): GrantPermissionRule { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { GrantPermissionRule.grant(Manifest.permission.READ_EXTERNAL_STORAGE) } else { @@ -109,4 +154,45 @@ object EspressoUtils { ) } } + fun searchFor(matcher: Matcher): ViewAction { + return object : ViewAction { + + override fun getConstraints(): Matcher { + return isRoot() + } + + override fun getDescription(): String { + return "searching for view $matcher in the root view" + } + + override fun perform(uiController: UiController, view: View) { + val childViews: Iterable = TreeIterables.breadthFirstViewTraversal(view) + childViews.forEach { + if (matcher.matches(it)) { + return + } + } + throw NoMatchingViewException.Builder() + .withRootView(view) + .withViewMatcher(matcher) + .build() + } + } + } + + @SuppressWarnings("SwallowedException") + fun assertOnView(viewMatcher: Matcher?, assertion: ViewAssertion, waitMillis: Int = 10_000, waitMillisPerTry: Long = 50) { + val endTime = System.currentTimeMillis() + waitMillis + while (System.currentTimeMillis() < endTime) { + try { + onView(viewMatcher).check(assertion) + return + } catch (e: NoMatchingViewException) { + SystemClock.sleep(waitMillisPerTry) + } catch (e: AssertionError) { + SystemClock.sleep(waitMillisPerTry) + } + } + onView(viewMatcher).check(assertion) + } } diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/ViewRobot.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/ViewRobot.kt new file mode 100644 index 0000000000..d3c3a91cce --- /dev/null +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/ViewRobot.kt @@ -0,0 +1,55 @@ +package org.catrobat.paintroid.test.espresso.util + +import android.os.SystemClock.sleep +import android.view.View +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.ViewAction +import androidx.test.espresso.ViewAssertion +import androidx.test.espresso.ViewInteraction +import androidx.test.espresso.matcher.ViewMatchers.isRoot +import org.catrobat.paintroid.test.espresso.util.EspressoUtils.searchFor +import org.hamcrest.Matcher + +open class ViewRobot { + + fun doOnView(matcher: Matcher, vararg actions: ViewAction) { + actions.forEach { + waitForView(matcher).perform(it) + } + } + + fun assertOnView(matcher: Matcher, vararg assertions: ViewAssertion) { + assertions.forEach { + waitForView(matcher).check(it) + } + } + + @SuppressWarnings("SwallowedException", "TooGenericExceptionThrown") + private fun waitForView(viewMatcher: Matcher, waitMillis: Int = 10_000, waitMillisPerTry: Long = 100): ViewInteraction { + val endTime = System.currentTimeMillis() + waitMillis + while (System.currentTimeMillis() < endTime) { + try { + onView(isRoot()).perform(searchFor(viewMatcher)) + return onView(viewMatcher) + } catch (e: Exception) { + sleep(waitMillisPerTry) + } + } + throw Exception("Error finding a view matching $viewMatcher after ${waitMillis}ms milliseconds") + } + + @SuppressWarnings("SwallowedException", "TooGenericExceptionThrown") + fun waitForViewToDisappear(viewMatcher: Matcher, waitMillis: Int = 5000, waitMillisPerTry: Long = 50): ViewInteraction { + val endTime = System.currentTimeMillis() + waitMillis + while (System.currentTimeMillis() < endTime) { + try { + onView(isRoot()).perform(searchFor(viewMatcher)) + sleep(waitMillisPerTry) + } catch (e: Exception) { + return onView(viewMatcher) + } + } + onView(isRoot()).perform(searchFor(viewMatcher)) + throw Exception("View $viewMatcher did not disappear after ${waitMillis}ms") + } +} diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/wrappers/BottomNavigationViewInteraction.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/wrappers/BottomNavigationViewInteraction.kt index 182d6a5570..bc808d4548 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/wrappers/BottomNavigationViewInteraction.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/wrappers/BottomNavigationViewInteraction.kt @@ -19,15 +19,22 @@ package org.catrobat.paintroid.test.espresso.util.wrappers import androidx.test.espresso.Espresso +import androidx.test.espresso.Espresso.onView import androidx.test.espresso.ViewInteraction import androidx.test.espresso.action.ViewActions import androidx.test.espresso.assertion.ViewAssertions import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText import org.catrobat.paintroid.R -import org.catrobat.paintroid.test.espresso.util.UiMatcher +import org.catrobat.paintroid.test.espresso.util.EspressoUtils.assertOnView +import org.catrobat.paintroid.test.espresso.util.UiInteractions.waitFor import org.catrobat.paintroid.tools.ToolType import org.hamcrest.Matchers.allOf +import org.catrobat.paintroid.test.espresso.util.UiMatcher +import org.catrobat.paintroid.test.espresso.util.ViewRobot class BottomNavigationViewInteraction private constructor() : CustomViewInteraction(Espresso.onView(withId(R.id.pocketpaint_bottom_navigation))) { @@ -51,7 +58,28 @@ class BottomNavigationViewInteraction private constructor() : .perform(ViewActions.click()) } - fun checkShowsCurrentTool(toolType: ToolType): ViewInteraction { + fun checkShowsCurrentTool(toolType: ToolType) { + onView(isRoot()).perform(waitFor(2000)) + val viewRobot = ViewRobot() + onView(isRoot()).perform(waitFor(2000)) + var matcher = allOf(withId(R.id.icon), + ViewMatchers.isDescendantOfA(withId(R.id.action_current_tool)), + UiMatcher.withDrawable(toolType.drawableResource) + ) + onView(isRoot()).perform(waitFor(2000)) + var assertion = ViewAssertions.matches(isDisplayed()) + onView(isRoot()).perform(waitFor(2000)) + viewRobot.assertOnView(matcher, assertion) + + onView(isRoot()).perform(waitFor(2000)) + matcher = allOf(withId(R.id.action_current_tool)) + onView(isRoot()).perform(waitFor(2000)) + assertion = ViewAssertions.matches(allOf(ViewMatchers.hasDescendant(withText(toolType.nameResource)), isDisplayed())) + onView(isRoot()).perform(waitFor(2000)) + assertOnView(matcher, assertion) + } + + /*fun checkShowsCurrentTool(toolType: ToolType): ViewInteraction { Espresso.onView( allOf( withId(R.id.icon), @@ -61,7 +89,7 @@ class BottomNavigationViewInteraction private constructor() : .check(ViewAssertions.matches(UiMatcher.withDrawable(toolType.drawableResource))) return Espresso.onView(withId(R.id.action_current_tool)) .check(ViewAssertions.matches(ViewMatchers.hasDescendant(ViewMatchers.withText(toolType.nameResource)))) - } + }*/ fun onColorClicked(): ViewInteraction { return Espresso.onView( diff --git a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/wrappers/LayerMenuViewInteraction.kt b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/wrappers/LayerMenuViewInteraction.kt index 133c05db90..cbd8f2ee99 100644 --- a/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/wrappers/LayerMenuViewInteraction.kt +++ b/Paintroid/src/androidTest/java/org/catrobat/paintroid/test/espresso/util/wrappers/LayerMenuViewInteraction.kt @@ -29,6 +29,9 @@ import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.Espresso import androidx.test.espresso.ViewInteraction import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.action.ViewActions.closeSoftKeyboard +import androidx.test.espresso.action.ViewActions.replaceText import androidx.test.espresso.assertion.ViewAssertions import androidx.test.espresso.contrib.DrawerActions import androidx.test.espresso.contrib.RecyclerViewActions @@ -64,8 +67,8 @@ class LayerMenuViewInteraction private constructor() : CustomViewInteraction(Esp fun performSetOpacityTo(opacityPercentage: Int, listPosition: Int): LayerMenuViewInteraction { Espresso.onView(withRecyclerView(R.id.pocketpaint_layer_side_nav_list) - .atPositionOnView(listPosition, R.id.pocketpaint_layer_opacity_seekbar)) - .perform(UiInteractions.setProgress(opacityPercentage)) + .atPositionOnView(listPosition, R.id.pocketpaint_layer_opacity_value)) + .perform(click(), replaceText(opacityPercentage.toString()), closeSoftKeyboard()) return this } diff --git a/Paintroid/src/main/java/org/catrobat/paintroid/controller/DefaultToolController.kt b/Paintroid/src/main/java/org/catrobat/paintroid/controller/DefaultToolController.kt index 5f49fc9bc2..a2b87dfeb4 100644 --- a/Paintroid/src/main/java/org/catrobat/paintroid/controller/DefaultToolController.kt +++ b/Paintroid/src/main/java/org/catrobat/paintroid/controller/DefaultToolController.kt @@ -103,7 +103,9 @@ class DefaultToolController( } override fun switchTool(toolType: ToolType) { + idlingResource.increment() switchTool(createAndSetupTool(toolType)) + idlingResource.decrement() } override fun hideToolOptionsView() {