blob: 93547e5dc1c2226041aac85fffaf1b57aa2a2c36 [file] [log] [blame]
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.tools.device.flicker.integration
import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
import android.tools.common.Scenario
import android.tools.common.datatypes.Region
import android.tools.common.flicker.subject.FlickerSubject
import android.tools.common.flicker.subject.layers.LayersTraceSubject
import android.tools.common.flicker.subject.region.RegionSubject
import android.tools.common.flicker.subject.wm.WindowManagerTraceSubject
import android.tools.device.apphelpers.CalculatorAppHelper
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerBuilderProvider
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
import android.tools.device.traces.parsers.WindowManagerStateHelper
import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.tapl.LauncherInstrumentation
import com.google.common.truth.Truth
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@FlickerServiceCompatible
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
class FullTestRun(private val flicker: FlickerTest) {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val testApp: CalculatorAppHelper = CalculatorAppHelper(instrumentation)
private val tapl: LauncherInstrumentation = LauncherInstrumentation()
init {
flicker.scenario.setIsTablet(
WindowManagerStateHelper(instrumentation, clearCacheAfterParsing = false)
.currentState
.wmState
.isTablet
)
tapl.setExpectedRotationCheckEnabled(true)
}
/**
* Entry point for the test runner. It will use this method to initialize and cache flicker
* executions
*/
@FlickerBuilderProvider
fun buildFlicker(): FlickerBuilder {
return FlickerBuilder(instrumentation).apply {
setup { flicker.scenario.setIsTablet(wmHelper.currentState.wmState.isTablet) }
teardown { testApp.exit(wmHelper) }
transitions { testApp.launchViaIntent(wmHelper) }
}
}
/**
* This is a shel test from the flicker infra to ensure the WM tracing pipeline executed
* entirely executed correctly
*/
@Presubmit
@Test
fun internalWmCheck() {
var trace: WindowManagerTraceSubject? = null
var executionCount = 0
flicker.assertWm {
executionCount++
trace = this
this.isNotEmpty()
}
flicker.assertWm {
executionCount++
val failure: Result<Any> = runCatching { this.isEmpty() }
if (failure.isSuccess) {
error("Should have thrown failure")
}
}
flicker.assertWmStart {
executionCount++
validateState(this, trace?.first())
validateVisibleRegion(this.visibleRegion(), trace?.first()?.visibleRegion())
}
flicker.assertWmEnd {
executionCount++
validateState(this, trace?.last())
validateVisibleRegion(this.visibleRegion(), trace?.last()?.visibleRegion())
}
Truth.assertWithMessage("Execution count").that(executionCount).isEqualTo(4)
}
/**
* This is a shel test from the flicker infra to ensure the Layers tracing pipeline executed
* entirely executed correctly
*/
@Presubmit
@Test
fun internalLayersCheck() {
var trace: LayersTraceSubject? = null
var executionCount = 0
flicker.assertLayers {
executionCount++
trace = this
this.isNotEmpty()
}
flicker.assertLayers {
executionCount++
val failure: Result<Any> = runCatching { this.isEmpty() }
if (failure.isSuccess) {
error("Should have thrown failure")
}
}
flicker.assertLayersStart {
executionCount++
validateState(this, trace?.first())
validateVisibleRegion(this.visibleRegion(), trace?.first()?.visibleRegion())
}
flicker.assertLayersEnd {
executionCount++
validateState(this, trace?.last())
validateVisibleRegion(this.visibleRegion(), trace?.last()?.visibleRegion())
}
Truth.assertWithMessage("Execution count").that(executionCount).isEqualTo(4)
}
private fun validateState(actual: FlickerSubject?, expected: FlickerSubject?) {
Truth.assertWithMessage("Actual state").that(actual).isNotNull()
Truth.assertWithMessage("Expected state").that(expected).isNotNull()
Truth.assertWithMessage("Incorrect state")
.that(actual?.completeFacts?.joinToString { it.toString() })
.isEqualTo(expected?.completeFacts?.joinToString { it.toString() })
}
private fun validateVisibleRegion(
actual: RegionSubject?,
expected: RegionSubject?,
) {
Truth.assertWithMessage("Actual visible region").that(actual).isNotNull()
Truth.assertWithMessage("Expected visible region").that(expected).isNotNull()
actual?.coversExactly(expected?.region ?: Region.EMPTY)
val failure: Result<Any?> = runCatching {
actual?.isHigher(expected?.region ?: Region.EMPTY)
}
if (failure.isSuccess) {
error("Should have thrown failure")
}
}
companion object {
/**
* Creates the test configurations.
*
* See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<FlickerTest> {
return FlickerTestFactory.nonRotationTests(
extraArgs = mapOf(Scenario.FAAS_BLOCKING to true)
)
}
}
}