diff --git a/android/benchmark/src/main/java/com/naviapp/benchmark/baselineprofile/HomePageScrollBaselineProfile.kt b/android/benchmark/src/main/java/com/naviapp/benchmark/baselineprofile/NaviBaselineProfile.kt similarity index 88% rename from android/benchmark/src/main/java/com/naviapp/benchmark/baselineprofile/HomePageScrollBaselineProfile.kt rename to android/benchmark/src/main/java/com/naviapp/benchmark/baselineprofile/NaviBaselineProfile.kt index 5b2389d99a..2fb0df9de5 100644 --- a/android/benchmark/src/main/java/com/naviapp/benchmark/baselineprofile/HomePageScrollBaselineProfile.kt +++ b/android/benchmark/src/main/java/com/naviapp/benchmark/baselineprofile/NaviBaselineProfile.kt @@ -11,6 +11,7 @@ import android.os.Build import androidx.annotation.RequiresApi import androidx.benchmark.macro.junit4.BaselineProfileRule import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.naviapp.benchmark.navipay.utils.openAllNaviPayEntryPoints import com.naviapp.benchmark.utils.PACKAGE_NAME import com.naviapp.benchmark.utils.performLogin import com.naviapp.benchmark.utils.scrollHomePage @@ -21,7 +22,7 @@ import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) -class HomePageScrollBaselineProfile { +class NaviBaselineProfile { @RequiresApi(Build.VERSION_CODES.P) @get:Rule val baselineProfileRule = BaselineProfileRule() @RequiresApi(Build.VERSION_CODES.P) @@ -32,5 +33,6 @@ class HomePageScrollBaselineProfile { performLogin() waitForHomePage() scrollHomePage() + openAllNaviPayEntryPoints() } } diff --git a/android/benchmark/src/main/java/com/naviapp/benchmark/navipay/benchmark/NaviPayBenchmarkGenerator.kt b/android/benchmark/src/main/java/com/naviapp/benchmark/navipay/benchmark/NaviPayBenchmarkGenerator.kt new file mode 100644 index 0000000000..3fa7ff3571 --- /dev/null +++ b/android/benchmark/src/main/java/com/naviapp/benchmark/navipay/benchmark/NaviPayBenchmarkGenerator.kt @@ -0,0 +1,79 @@ +/* + * + * * Copyright © 2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.naviapp.benchmark.navipay.benchmark + +import android.os.Build +import androidx.annotation.RequiresApi +import androidx.benchmark.macro.BaselineProfileMode +import androidx.benchmark.macro.CompilationMode +import androidx.benchmark.macro.ExperimentalMetricApi +import androidx.benchmark.macro.FrameTimingMetric +import androidx.benchmark.macro.MemoryCountersMetric +import androidx.benchmark.macro.MemoryUsageMetric +import androidx.benchmark.macro.junit4.MacrobenchmarkRule +import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner +import com.naviapp.benchmark.navipay.utils.openAllNaviPayEntryPoints +import com.naviapp.benchmark.utils.PACKAGE_NAME +import com.naviapp.benchmark.utils.performLogin +import com.naviapp.benchmark.utils.waitForHomePage +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4ClassRunner::class) +class NaviPayBenchmarkGenerator { + + @get:Rule val benchmarkRule = MacrobenchmarkRule() + + @RequiresApi(Build.VERSION_CODES.Q) + @Test + fun launchAllNaviPayEntryPointsNoCompilation() = + launchAllNaviPayEntryPoints(CompilationMode.None()) + + @RequiresApi(Build.VERSION_CODES.Q) + @Test + fun launchAllNaviPayEntryPointsPartialWithBaselineProfiles() = + launchAllNaviPayEntryPoints( + CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Require) + ) + + @RequiresApi(Build.VERSION_CODES.Q) + @Test + fun launchAllNaviPayEntryPointsPartialCompilation() = + launchAllNaviPayEntryPoints( + CompilationMode.Partial( + baselineProfileMode = BaselineProfileMode.Disable, + warmupIterations = 3 + ) + ) + + @RequiresApi(Build.VERSION_CODES.Q) + @Test + fun launchAllNaviPayEntryPointsFullCompilation() = + launchAllNaviPayEntryPoints(CompilationMode.Full()) + + @RequiresApi(Build.VERSION_CODES.Q) + @OptIn(ExperimentalMetricApi::class) + private fun launchAllNaviPayEntryPoints(compilationMode: CompilationMode) = + benchmarkRule.measureRepeated( + packageName = PACKAGE_NAME, + metrics = + listOf( + FrameTimingMetric(), + MemoryUsageMetric(mode = MemoryUsageMetric.Mode.Last), + MemoryCountersMetric(), + ), + iterations = 15, + compilationMode = compilationMode, + setupBlock = { pressHome() } + ) { + performLogin() + waitForHomePage() + openAllNaviPayEntryPoints() + } +} diff --git a/android/benchmark/src/main/java/com/naviapp/benchmark/navipay/utils/NaviPayEntry.kt b/android/benchmark/src/main/java/com/naviapp/benchmark/navipay/utils/NaviPayEntry.kt new file mode 100644 index 0000000000..d06a561d46 --- /dev/null +++ b/android/benchmark/src/main/java/com/naviapp/benchmark/navipay/utils/NaviPayEntry.kt @@ -0,0 +1,106 @@ +/* + * + * * Copyright © 2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.naviapp.benchmark.navipay.utils + +import android.Manifest +import androidx.benchmark.macro.MacrobenchmarkScope +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until +import com.naviapp.benchmark.utils.allowPermission +import com.naviapp.benchmark.utils.delay +import java.util.concurrent.TimeUnit + +fun MacrobenchmarkScope.openAllNaviPayEntryPoints() { + allowAllNaviPayPermissions() + + clickScanAndPayFab() + device.pressBack() + + clickTransactionHistory() + device.pressBack() + + // clickPayToContact() + // device.pressBack() + // + // clickPayToUPIID() + // device.pressBack() + // + // clickCheckBalance() + // device.pressBack() + // + // clickMyQRCode() + // device.pressBack() +} + +private fun MacrobenchmarkScope.allowAllNaviPayPermissions() { + device.waitForIdle() + allowPermission(permission = Manifest.permission.READ_PHONE_STATE) + allowPermission(permission = Manifest.permission.ACCESS_FINE_LOCATION) + allowPermission(permission = Manifest.permission.CAMERA) + allowPermission(permission = Manifest.permission.SEND_SMS) + allowPermission(permission = Manifest.permission.READ_SMS) + allowPermission(permission = Manifest.permission.READ_CONTACTS) +} + +private fun MacrobenchmarkScope.checkAndExecuteDeviceBinding() { + device.waitForIdle() + device.findObject(By.text("Validate mobile number")) ?: return + + device.findObject(By.text("Continue")).click() + device.wait(Until.hasObject(By.text("Mobile number verified!")), TimeUnit.SECONDS.toMillis(60)) + device.delay(durationInSeconds = 5) +} + +private fun MacrobenchmarkScope.clickScanAndPayFab() { + device.waitForIdle() + val scanAndPayButton = device.findObject(By.textStartsWith("Scan")) + if (scanAndPayButton != null) { + scanAndPayButton.click() + device.delay(durationInSeconds = 10) + } else { + device.delay(durationInSeconds = 5) + clickScanAndPayFab() + } +} + +private fun MacrobenchmarkScope.clickTransactionHistory() { + device.waitForIdle() + device.findObject(UiSelector().textStartsWith("Transaction")).click() + device.delay(durationInSeconds = 5) +} + +private fun MacrobenchmarkScope.clickPayToContact() { + device.waitForIdle() + device.findObject(UiSelector().textStartsWith("Pay mobile")).click() + device.delay(durationInSeconds = 5) +} + +private fun MacrobenchmarkScope.clickPayToUPIID() { + device.waitForIdle() + device.findObject(UiSelector().textStartsWith("Pay to UPI")).click() + device.delay(durationInSeconds = 5) +} + +private fun MacrobenchmarkScope.clickMoreOptions() { + device.waitForIdle() + device.findObject(UiSelector().textStartsWith("More")).click() + device.delay(durationInSeconds = 5) +} + +private fun MacrobenchmarkScope.clickCheckBalance() { + device.waitForIdle() + device.findObject(UiSelector().textStartsWith("Check")).click() + device.delay(durationInSeconds = 5) +} + +private fun MacrobenchmarkScope.clickMyQRCode() { + device.waitForIdle() + device.findObject(UiSelector().textStartsWith("My QR")).click() + device.delay(durationInSeconds = 5) +} diff --git a/android/benchmark/src/main/java/com/naviapp/benchmark/utils/Utils.kt b/android/benchmark/src/main/java/com/naviapp/benchmark/utils/Utils.kt index 31bbc94895..a30e9fe24d 100644 --- a/android/benchmark/src/main/java/com/naviapp/benchmark/utils/Utils.kt +++ b/android/benchmark/src/main/java/com/naviapp/benchmark/utils/Utils.kt @@ -12,6 +12,7 @@ import androidx.test.uiautomator.Direction import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiObject2 import androidx.test.uiautomator.Until +import java.util.concurrent.TimeUnit val PACKAGE_NAME = buildString { append("com.naviapp.dev") } @@ -27,6 +28,12 @@ fun UiDevice.waitAndFindObject(selector: BySelector, timeout: Long): UiObject2 { return findObject(selector) } +fun UiDevice.delay(durationInSeconds: Long) { + val durationInMillis = TimeUnit.SECONDS.toMillis(durationInSeconds) + waitForIdle(durationInMillis) + waitForWindowUpdate(PACKAGE_NAME, durationInMillis) +} + fun UiDevice.flingElementDownUp(element: UiObject2) { element.setGestureMargin(displayWidth / 5) element.fling(Direction.DOWN)