1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.jetpackcamera 17 18 import android.os.Build 19 import androidx.compose.ui.test.isDisplayed 20 import androidx.compose.ui.test.junit4.createEmptyComposeRule 21 import androidx.compose.ui.test.onNodeWithTag 22 import androidx.compose.ui.test.performClick 23 import androidx.test.ext.junit.runners.AndroidJUnit4 24 import androidx.test.platform.app.InstrumentationRegistry 25 import androidx.test.rule.GrantPermissionRule 26 import androidx.test.uiautomator.By 27 import androidx.test.uiautomator.UiDevice 28 import androidx.test.uiautomator.Until 29 import com.google.common.truth.Truth.assertThat 30 import com.google.common.truth.TruthJUnit.assume 31 import com.google.jetpackcamera.feature.preview.quicksettings.ui.QUICK_SETTINGS_CAPTURE_MODE_BUTTON 32 import com.google.jetpackcamera.feature.preview.quicksettings.ui.QUICK_SETTINGS_DROP_DOWN 33 import com.google.jetpackcamera.feature.preview.quicksettings.ui.QUICK_SETTINGS_FLIP_CAMERA_BUTTON 34 import com.google.jetpackcamera.feature.preview.quicksettings.ui.QUICK_SETTINGS_RATIO_1_1_BUTTON 35 import com.google.jetpackcamera.feature.preview.quicksettings.ui.QUICK_SETTINGS_RATIO_BUTTON 36 import com.google.jetpackcamera.feature.preview.ui.CAPTURE_BUTTON 37 import org.junit.Before 38 import org.junit.Rule 39 import org.junit.Test 40 import org.junit.runner.RunWith 41 42 @RunWith(AndroidJUnit4::class) 43 class BackgroundDeviceTest { 44 @get:Rule 45 val permissionsRule: GrantPermissionRule = 46 GrantPermissionRule.grant(*(APP_REQUIRED_PERMISSIONS).toTypedArray()) 47 48 @get:Rule 49 val composeTestRule = createEmptyComposeRule() 50 51 private val instrumentation = InstrumentationRegistry.getInstrumentation() 52 private val uiDevice = UiDevice.getInstance(instrumentation) 53 backgroundThenForegroundAppnull54 private fun backgroundThenForegroundApp() { 55 uiDevice.pressHome() 56 uiDevice.pressRecentApps() 57 uiDevice.pressRecentApps() 58 59 // Wait for the app to return to the foreground 60 uiDevice.wait( 61 Until.hasObject(By.pkg("com.google.jetpackcamera")), 62 APP_START_TIMEOUT_MILLIS 63 ) 64 } 65 66 @Before setUpnull67 fun setUp() { 68 assertThat(uiDevice.isScreenOn).isTrue() 69 } 70 71 @Test <lambda>null72 fun background_foreground() = runScenarioTest<MainActivity> { 73 // Wait for the capture button to be displayed 74 composeTestRule.waitUntil(timeoutMillis = APP_START_TIMEOUT_MILLIS) { 75 composeTestRule.onNodeWithTag(CAPTURE_BUTTON).isDisplayed() 76 } 77 78 backgroundThenForegroundApp() 79 } 80 81 @Test <lambda>null82 fun flipCamera_then_background_foreground() = runScenarioTest<MainActivity> { 83 // Wait for the capture button to be displayed 84 composeTestRule.waitUntil(timeoutMillis = APP_START_TIMEOUT_MILLIS) { 85 composeTestRule.onNodeWithTag(CAPTURE_BUTTON).isDisplayed() 86 } 87 88 // Navigate to quick settings 89 composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN) 90 .assertExists() 91 .performClick() 92 93 // Click the flip camera button 94 composeTestRule.onNodeWithTag(QUICK_SETTINGS_FLIP_CAMERA_BUTTON) 95 .assertExists() 96 .performClick() 97 98 // Exit quick settings 99 composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN) 100 .assertExists() 101 .performClick() 102 103 backgroundThenForegroundApp() 104 } 105 106 @Test <lambda>null107 fun setAspectRatio_then_background_foreground() = runScenarioTest<MainActivity> { 108 // Wait for the capture button to be displayed 109 composeTestRule.waitUntil(timeoutMillis = APP_START_TIMEOUT_MILLIS) { 110 composeTestRule.onNodeWithTag(CAPTURE_BUTTON).isDisplayed() 111 } 112 113 // Navigate to quick settings 114 composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN) 115 .assertExists() 116 .performClick() 117 118 // Click the ratio button 119 composeTestRule.onNodeWithTag(QUICK_SETTINGS_RATIO_BUTTON) 120 .assertExists() 121 .performClick() 122 123 // Click the 1:1 ratio button 124 composeTestRule.onNodeWithTag(QUICK_SETTINGS_RATIO_1_1_BUTTON) 125 .assertExists() 126 .performClick() 127 128 // Exit quick settings 129 composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN) 130 .assertExists() 131 .performClick() 132 133 backgroundThenForegroundApp() 134 } 135 assumeSupportsSingleStreamnull136 private fun assumeSupportsSingleStream() { 137 // The GMD emulators with API <=28 do not support single-stream configs. 138 assume().that(Build.HARDWARE == "ranchu" && Build.VERSION.SDK_INT <= 28).isFalse() 139 } 140 141 @Test <lambda>null142 fun toggleCaptureMode_then_background_foreground() = runScenarioTest<MainActivity> { 143 // Skip this test on devices that don't support single stream 144 assumeSupportsSingleStream() 145 146 // Wait for the capture button to be displayed 147 composeTestRule.waitUntil(timeoutMillis = APP_START_TIMEOUT_MILLIS) { 148 composeTestRule.onNodeWithTag(CAPTURE_BUTTON).isDisplayed() 149 } 150 151 // Navigate to quick settings 152 composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN) 153 .assertExists() 154 .performClick() 155 156 // Click the flip camera button 157 composeTestRule.onNodeWithTag(QUICK_SETTINGS_CAPTURE_MODE_BUTTON) 158 .assertExists() 159 .performClick() 160 161 // Exit quick settings 162 composeTestRule.onNodeWithTag(QUICK_SETTINGS_DROP_DOWN) 163 .assertExists() 164 .performClick() 165 166 backgroundThenForegroundApp() 167 } 168 } 169