Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d04791d6 authored by Nataniel Borges's avatar Nataniel Borges
Browse files

Split app pair tests into individual assertions

After this CL each assertion in the AppPairs test will appear as independent tests

Bug: 162923992
Test: atest FlickerTests WMShellFlickerTests
Change-Id: Id704301b3396c4330001ef639faed6e978237f10
parent 143d584e
Loading
Loading
Loading
Loading
+0 −227
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 com.android.wm.shell.flicker.apppairs

import android.os.SystemClock
import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.dsl.runWithFlicker
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import com.android.server.wm.flicker.traces.layers.getVisibleBounds
import com.android.wm.shell.flicker.appPairsDividerIsInvisible
import com.android.wm.shell.flicker.appPairsDividerIsVisible
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import com.android.wm.shell.flicker.helpers.AppPairsHelper.Companion.TEST_REPETITIONS
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized

/**
 * Test AppPairs launch.
 * To run this test: `atest WMShellFlickerTests:AppPairsTest`
 */
@Presubmit
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class AppPairsTest(
    rotationName: String,
    rotation: Int
) : AppPairsTestBase(rotationName, rotation) {
    private val appPairsSetup: FlickerBuilder
        get() = FlickerBuilder(instrumentation).apply {
            val testLaunchActivity = "launch_appPairs_primary_secondary_activities"
            withTestName {
                testLaunchActivity
            }
            setup {
                eachRun {
                    uiDevice.wakeUpAndGoToHomeScreen()
                    primaryApp.launchViaIntent()
                    secondaryApp.launchViaIntent()
                    nonResizeableApp.launchViaIntent()
                    updateTasksId()
                }
            }
            teardown {
                eachRun {
                    executeShellCommand(composePairsCommand(
                            primaryTaskId, secondaryTaskId, false /* pair */))
                    executeShellCommand(composePairsCommand(
                            primaryTaskId, nonResizeableTaskId, false /* pair */))
                    primaryApp.exit()
                    secondaryApp.exit()
                    nonResizeableApp.exit()
                }
            }
            assertions {
                layersTrace {
                    navBarLayerIsAlwaysVisible()
                    statusBarLayerIsAlwaysVisible()
                }
                windowManagerTrace {
                    navBarWindowIsAlwaysVisible()
                    statusBarWindowIsAlwaysVisible()
                }
            }
        }

    @Test
    fun testAppPairs_pairPrimaryAndSecondaryApps() {
        val testTag = "testAppPairs_pairPrimaryAndSecondaryApps"
        runWithFlicker(appPairsSetup) {
            withTestName { testTag }
            repeat {
                TEST_REPETITIONS
            }
            transitions {
                // TODO pair apps through normal UX flow
                executeShellCommand(composePairsCommand(
                        primaryTaskId, secondaryTaskId, true /* pair */))
                SystemClock.sleep(AppPairsHelper.TIMEOUT_MS)
            }
            assertions {
                layersTrace {
                    appPairsDividerIsVisible()
                    end("appsEndingBounds", enabled = false) {
                        val entry = this.trace.entries.firstOrNull()
                                ?: throw IllegalStateException("Trace is empty")
                        val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER)
                        this.hasVisibleRegion(primaryApp.defaultWindowName,
                                appPairsHelper.getPrimaryBounds(dividerRegion))
                                .hasVisibleRegion(secondaryApp.defaultWindowName,
                                        appPairsHelper.getSecondaryBounds(dividerRegion))
                    }
                }
                windowManagerTrace {
                    end {
                        showsAppWindow(primaryApp.defaultWindowName)
                                .showsAppWindow(secondaryApp.defaultWindowName)
                    }
                }
            }
        }
    }

    @Test
    fun testAppPairs_unpairPrimaryAndSecondary() {
        val testTag = "testAppPairs_unpairPrimaryAndSecondary"
        runWithFlicker(appPairsSetup) {
            withTestName { testTag }
            repeat {
                TEST_REPETITIONS
            }
            setup {
                executeShellCommand(composePairsCommand(
                        primaryTaskId, secondaryTaskId, true /* pair */))
                SystemClock.sleep(AppPairsHelper.TIMEOUT_MS)
            }
            transitions {
                // TODO pair apps through normal UX flow
                executeShellCommand(composePairsCommand(
                        primaryTaskId, secondaryTaskId, false /* pair */))
                SystemClock.sleep(AppPairsHelper.TIMEOUT_MS)
            }
            assertions {
                layersTrace {
                    appPairsDividerIsInvisible()
                    start("appsStartingBounds", enabled = false) {
                        val entry = this.trace.entries.firstOrNull()
                                ?: throw IllegalStateException("Trace is empty")
                        val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER)
                        this.hasVisibleRegion(primaryApp.defaultWindowName,
                                appPairsHelper.getPrimaryBounds(dividerRegion))
                                .hasVisibleRegion(secondaryApp.defaultWindowName,
                                        appPairsHelper.getSecondaryBounds(dividerRegion))
                    }
                    end("appsEndingBounds", enabled = false) {
                        this.hasNotLayer(primaryApp.defaultWindowName)
                                .hasNotLayer(secondaryApp.defaultWindowName)
                    }
                }
                windowManagerTrace {
                    end {
                        hidesAppWindow(primaryApp.defaultWindowName)
                                .hidesAppWindow(secondaryApp.defaultWindowName)
                    }
                }
            }
        }
    }

    @Test
    fun testAppPairs_canNotPairNonResizeableApps() {
        val testTag = "testAppPairs_canNotPairNonResizeableApps"
        runWithFlicker(appPairsSetup) {
            withTestName { testTag }
            repeat {
                TEST_REPETITIONS
            }
            transitions {
                // TODO pair apps through normal UX flow
                executeShellCommand(composePairsCommand(
                    primaryTaskId, nonResizeableTaskId, true /* pair */))
                SystemClock.sleep(AppPairsHelper.TIMEOUT_MS)
            }

            assertions {
                layersTrace {
                    appPairsDividerIsInvisible()
                }
                windowManagerTrace {
                    end {
                        showsAppWindow(nonResizeableApp.defaultWindowName)
                            .hidesAppWindow(primaryApp.defaultWindowName)
                    }
                }
            }
        }
    }

    fun updateTasksId() {
        if (primaryAppComponent != null) {
            primaryTaskId = getTaskIdForActivity(
                    primaryAppComponent.packageName, primaryAppComponent.className).toString()
        }
        if (secondaryAppComponent != null) {
            secondaryTaskId = getTaskIdForActivity(
                    secondaryAppComponent.packageName, secondaryAppComponent.className).toString()
        }
        if (nonResizeableAppComponent != null) {
            nonResizeableTaskId = getTaskIdForActivity(
                    nonResizeableAppComponent.packageName,
                    nonResizeableAppComponent.className).toString()
        }
    }

    companion object {
        @Parameterized.Parameters(name = "{0}")
        @JvmStatic
        fun getParams(): Collection<Array<Any>> {
            val supportedRotations = intArrayOf(Surface.ROTATION_0)
            return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) }
        }
    }
}
 No newline at end of file
+91 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 com.android.wm.shell.flicker.apppairs

import android.os.Bundle
import android.platform.test.annotations.Presubmit
import android.os.SystemClock
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.buildTestTag
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import com.android.wm.shell.flicker.appPairsDividerIsInvisible
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized

/**
 * Test AppPairs launch.
 * To run this test: `atest WMShellFlickerTests:AppPairsTest`
 */
/**
 * Test cold launch app from launcher.
 * To run this test: `atest WMShellFlickerTests:AppPairsTestCannotPairNonResizeableApps`
 */
@Presubmit
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class AppPairsTestCannotPairNonResizeableApps(
    testName: String,
    flickerProvider: () -> Flicker,
    cleanUp: Boolean
) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
    companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) {
        @Parameterized.Parameters(name = "{0}")
        @JvmStatic
        fun getParams(): List<Array<Any>> {
            val testTag = "testAppPairs_unpairPrimaryAndSecondaryApps"
            val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
                withTestName {
                    buildTestTag(testTag, configuration)
                }
                transitions {
                    nonResizeableApp?.launchViaIntent(wmHelper)
                    // TODO pair apps through normal UX flow
                    executeShellCommand(
                        composePairsCommand(primaryTaskId, nonResizeableTaskId, pair = true))
                    SystemClock.sleep(AppPairsHelper.TIMEOUT_MS)
                }
                assertions {
                    layersTrace {
                        appPairsDividerIsInvisible()
                    }
                    windowManagerTrace {
                        end {
                            val nonResizeableApp = nonResizeableApp
                            require(nonResizeableApp != null) {
                                "Non resizeable app not initialized"
                            }
                            isVisible(nonResizeableApp.defaultWindowName)
                            isInvisible(primaryApp.defaultWindowName)
                        }
                    }
                }
            }

            return FlickerTestRunnerFactory(instrumentation,
                repetitions = AppPairsHelper.TEST_REPETITIONS)
                .buildTest(transition, testSpec)
        }
    }
}
 No newline at end of file
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 com.android.wm.shell.flicker.apppairs

import android.os.Bundle
import android.os.SystemClock
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.buildTestTag
import com.android.server.wm.flicker.traces.layers.getVisibleBounds
import com.android.wm.shell.flicker.FlickerTestBase
import com.android.wm.shell.flicker.appPairsDividerIsVisible
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized

/**
 * Test cold launch app from launcher.
 * To run this test: `atest WMShellFlickerTests:AppPairsTestPairPrimaryAndSecondaryApps`
 */
@Presubmit
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class AppPairsTestPairPrimaryAndSecondaryApps(
    testName: String,
    flickerProvider: () -> Flicker,
    cleanUp: Boolean
) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
    companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) {
        @Parameterized.Parameters(name = "{0}")
        @JvmStatic
        fun getParams(): List<Array<Any>> {
            val testTag = "testAppPairs_pairPrimaryAndSecondaryApps"
            val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
                withTestName {
                    buildTestTag(testTag, configuration)
                }
                transitions {
                    // TODO pair apps through normal UX flow
                    executeShellCommand(
                        composePairsCommand(primaryTaskId, secondaryTaskId, pair = true))
                    SystemClock.sleep(AppPairsHelper.TIMEOUT_MS)
                }
                assertions {
                    layersTrace {
                        appPairsDividerIsVisible()
                        end("appsEndingBounds", enabled = false) {
                            val dividerRegion = entry.getVisibleBounds(
                                    FlickerTestBase.APP_PAIR_SPLIT_DIVIDER)
                            this.hasVisibleRegion(primaryApp.defaultWindowName,
                                appPairsHelper.getPrimaryBounds(dividerRegion))
                                .hasVisibleRegion(secondaryApp.defaultWindowName,
                                    appPairsHelper.getSecondaryBounds(dividerRegion))
                        }
                    }
                    windowManagerTrace {
                        end {
                            isVisible(primaryApp.defaultWindowName)
                            isVisible(secondaryApp.defaultWindowName)
                        }
                    }
                }
            }
            return FlickerTestRunnerFactory(instrumentation,
                repetitions = AppPairsHelper.TEST_REPETITIONS).buildTest(transition, testSpec)
        }
    }
}
+99 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 com.android.wm.shell.flicker.apppairs

import android.os.Bundle
import android.os.SystemClock
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.buildTestTag
import com.android.server.wm.flicker.traces.layers.getVisibleBounds
import com.android.wm.shell.flicker.FlickerTestBase
import com.android.wm.shell.flicker.appPairsDividerIsInvisible
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized

/**
 * Test cold launch app from launcher.
 * To run this test: `atest WMShellFlickerTests:AppPairsTestUnpairPrimaryAndSecondaryApps`
 */
@Presubmit
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class AppPairsTestUnpairPrimaryAndSecondaryApps(
    testName: String,
    flickerProvider: () -> Flicker,
    cleanUp: Boolean
) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
    companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) {
        @Parameterized.Parameters(name = "{0}")
        @JvmStatic
        fun getParams(): List<Array<Any>> {
            val testTag = "testAppPairs_unpairPrimaryAndSecondaryApps"
            val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
                withTestName {
                    buildTestTag(testTag, configuration)
                }
                setup {
                    executeShellCommand(
                        composePairsCommand(primaryTaskId, secondaryTaskId, pair = true))
                    SystemClock.sleep(AppPairsHelper.TIMEOUT_MS)
                }
                transitions {
                    // TODO pair apps through normal UX flow
                    executeShellCommand(
                        composePairsCommand(primaryTaskId, secondaryTaskId, pair = false))
                    SystemClock.sleep(AppPairsHelper.TIMEOUT_MS)
                }
                assertions {
                    layersTrace {
                        appPairsDividerIsInvisible()
                        start("appsStartingBounds", enabled = false) {
                            val dividerRegion = entry.getVisibleBounds(
                                FlickerTestBase.APP_PAIR_SPLIT_DIVIDER)
                            this.hasVisibleRegion(primaryApp.defaultWindowName,
                                appPairsHelper.getPrimaryBounds(dividerRegion))
                                .hasVisibleRegion(secondaryApp.defaultWindowName,
                                    appPairsHelper.getSecondaryBounds(dividerRegion))
                        }
                        end("appsEndingBounds", enabled = false) {
                            this.notExists(primaryApp.defaultWindowName)
                                .notExists(secondaryApp.defaultWindowName)
                        }
                    }
                    windowManagerTrace {
                        end {
                            isInvisible(primaryApp.defaultWindowName)
                            isInvisible(secondaryApp.defaultWindowName)
                        }
                    }
                }
            }
            return FlickerTestRunnerFactory(instrumentation,
                repetitions = AppPairsHelper.TEST_REPETITIONS).buildTest(transition, testSpec)
        }
    }
}
+131 −0

File changed and moved.

Preview size limit exceeded, changes collapsed.

Loading