perf: 添加性能追踪标记并改进基线配置文件生成器
This commit is contained in:
parent
4de00e35dc
commit
281abcf66b
@ -27,10 +27,17 @@
|
|||||||
trace 中包含自定义标记:
|
trace 中包含自定义标记:
|
||||||
|
|
||||||
- `MonthView:Compose` — 月视图重组
|
- `MonthView:Compose` — 月视图重组
|
||||||
|
- `CalendarPagerArea` — 日历分页器区域
|
||||||
|
- `CalendarPager:Page:*` — 月视图单页重组
|
||||||
|
- `CalendarMonthPage:*` — 月页面数据计算(含折叠动画准备)
|
||||||
|
- `WeekPager:Page` — 周视图单页重组
|
||||||
- `YearView:Compose` — 年视图重组
|
- `YearView:Compose` — 年视图重组
|
||||||
- `YearGridView:*` — 年视图网格组合(首帧耗时关键指标)
|
- `YearGridView:*` — 年视图网格组合(首帧耗时关键指标)
|
||||||
- `generateMiniMonthDays:*` — 月份网格计算
|
- `generateMiniMonthDays:*` — 月份网格计算
|
||||||
- `VM:collapseProgress` — 折叠动画
|
- `MonthView→YearView` / `YearView→MonthView` — 视图切换
|
||||||
|
- `YearView:SelectMonth` — 年视图选月
|
||||||
|
- `getMonthDays:*` — ViewModel 月份网格计算
|
||||||
|
- `VM:collapseProgress:*` — 折叠动画拖拽(onDrag/onDragEnd/onExpandDrag/onExpandDragEnd)
|
||||||
|
|
||||||
## Baseline Profile
|
## Baseline Profile
|
||||||
|
|
||||||
|
|||||||
@ -18617,4 +18617,17 @@ SPLplus/rua/project/ui/WeekdayHeaderKt;->WeekdayHeader$lambda$0$0(Landroidx/comp
|
|||||||
SPLplus/rua/project/ui/WeekdayHeaderKt;->WeekdayHeader(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V
|
SPLplus/rua/project/ui/WeekdayHeaderKt;->WeekdayHeader(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V
|
||||||
Lplus/rua/project/ui/WeekdayHeaderKt$$ExternalSyntheticLambda0;
|
Lplus/rua/project/ui/WeekdayHeaderKt$$ExternalSyntheticLambda0;
|
||||||
SPLplus/rua/project/ui/WeekdayHeaderKt$$ExternalSyntheticLambda0;-><init>()V
|
SPLplus/rua/project/ui/WeekdayHeaderKt$$ExternalSyntheticLambda0;-><init>()V
|
||||||
SPLplus/rua/project/ui/WeekdayHeaderKt$$ExternalSyntheticLambda0;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
|
SPLplus/rua/project/ui/WeekdayHeaderKt$$ExternalSyntheticLambda0;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
|
||||||
|
Lplus/rua/project/ui/YearGridViewKt;
|
||||||
|
HPLplus/rua/project/ui/YearGridViewKt;->YearGridView(IILkotlinx/datetime/LocalDate;Lkotlin/jvm/functions/Function1;Landroidx/compose/animation/SharedTransitionScope;Landroidx/compose/animation/AnimatedVisibilityScope;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V
|
||||||
|
HPLplus/rua/project/ui/YearGridViewKt;->generateMiniMonthDays(II)Ljava/util/List;
|
||||||
|
Lplus/rua/project/ui/YearGridViewKt;->MiniMonth(IIZLkotlinx/datetime/LocalDate;Ljava/util/List;Lplus/rua/project/ui/MiniMonthColors;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V
|
||||||
|
Lplus/rua/project/ui/YearGridViewKt;->YearHeader(IILkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;II)V
|
||||||
|
Lplus/rua/project/ui/MiniMonthColors;
|
||||||
|
HPLplus/rua/project/CalendarViewModel;->toggleYearView()V
|
||||||
|
HPLplus/rua/project/CalendarViewModel;->selectMonthFromYearView(I)V
|
||||||
|
HPLplus/rua/project/CalendarViewModel;->onDrag(F)V
|
||||||
|
HPLplus/rua/project/CalendarViewModel;->onDragEnd()V
|
||||||
|
HPLplus/rua/project/CalendarViewModel;->onExpandDrag(F)V
|
||||||
|
HPLplus/rua/project/CalendarViewModel;->onExpandDragEnd()V
|
||||||
|
HPLplus/rua/project/CalendarViewModel;->getMonthDays(II)Ljava/util/List;
|
||||||
|
|||||||
@ -280,7 +280,9 @@ class CalendarViewModel(
|
|||||||
* @param delta 拖拽增量,已归一化到 [0,1] 区间
|
* @param delta 拖拽增量,已归一化到 [0,1] 区间
|
||||||
*/
|
*/
|
||||||
fun onDrag(delta: Float) {
|
fun onDrag(delta: Float) {
|
||||||
|
composeTraceBeginSection("VM:collapseProgress:onDrag")
|
||||||
_collapseProgress.value = (_collapseProgress.value + delta).coerceIn(0f, 1f)
|
_collapseProgress.value = (_collapseProgress.value + delta).coerceIn(0f, 1f)
|
||||||
|
composeTraceEndSection()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -289,6 +291,7 @@ class CalendarViewModel(
|
|||||||
* 拖拽超过阈值时自动折叠到周视图,否则回弹到月视图。
|
* 拖拽超过阈值时自动折叠到周视图,否则回弹到月视图。
|
||||||
*/
|
*/
|
||||||
fun onDragEnd() {
|
fun onDragEnd() {
|
||||||
|
composeTraceBeginSection("VM:collapseProgress:onDragEnd")
|
||||||
val progress = _collapseProgress.value
|
val progress = _collapseProgress.value
|
||||||
if (progress > COLLAPSE_THRESHOLD) {
|
if (progress > COLLAPSE_THRESHOLD) {
|
||||||
_isCollapsed.value = true
|
_isCollapsed.value = true
|
||||||
@ -297,6 +300,7 @@ class CalendarViewModel(
|
|||||||
_isCollapsed.value = false
|
_isCollapsed.value = false
|
||||||
_collapseProgress.value = 0f
|
_collapseProgress.value = 0f
|
||||||
}
|
}
|
||||||
|
composeTraceEndSection()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -305,9 +309,11 @@ class CalendarViewModel(
|
|||||||
* @param delta 拖拽增量,已归一化到 [0,1] 区间
|
* @param delta 拖拽增量,已归一化到 [0,1] 区间
|
||||||
*/
|
*/
|
||||||
fun onExpandDrag(delta: Float) {
|
fun onExpandDrag(delta: Float) {
|
||||||
|
composeTraceBeginSection("VM:collapseProgress:onExpandDrag")
|
||||||
val old = _collapseProgress.value
|
val old = _collapseProgress.value
|
||||||
_collapseProgress.value = (_collapseProgress.value + delta).coerceIn(0f, 1f)
|
_collapseProgress.value = (_collapseProgress.value + delta).coerceIn(0f, 1f)
|
||||||
logd(TAG_VM, "onExpandDrag: delta=$delta old=$old new=${_collapseProgress.value}")
|
logd(TAG_VM, "onExpandDrag: delta=$delta old=$old new=${_collapseProgress.value}")
|
||||||
|
composeTraceEndSection()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -316,6 +322,7 @@ class CalendarViewModel(
|
|||||||
* 下拉超过阈值时自动展开到月视图,否则回弹到周视图。
|
* 下拉超过阈值时自动展开到月视图,否则回弹到周视图。
|
||||||
*/
|
*/
|
||||||
fun onExpandDragEnd() {
|
fun onExpandDragEnd() {
|
||||||
|
composeTraceBeginSection("VM:collapseProgress:onExpandDragEnd")
|
||||||
val progress = _collapseProgress.value
|
val progress = _collapseProgress.value
|
||||||
val result = if (progress < (1 - COLLAPSE_THRESHOLD)) {
|
val result = if (progress < (1 - COLLAPSE_THRESHOLD)) {
|
||||||
_isCollapsed.value = false
|
_isCollapsed.value = false
|
||||||
@ -327,6 +334,7 @@ class CalendarViewModel(
|
|||||||
"COLLAPSED (bounce back)"
|
"COLLAPSED (bounce back)"
|
||||||
}
|
}
|
||||||
logd(TAG_VM, "onExpandDragEnd: progress=$progress threshold=${1 - COLLAPSE_THRESHOLD} result=$result")
|
logd(TAG_VM, "onExpandDragEnd: progress=$progress threshold=${1 - COLLAPSE_THRESHOLD} result=$result")
|
||||||
|
composeTraceEndSection()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -21,12 +21,10 @@ import plus.rua.project.getWebpUri
|
|||||||
*/
|
*/
|
||||||
private val WEBP_FILES = (1..152).map { "${it.toString().padStart(3, '0')}.webp" }
|
private val WEBP_FILES = (1..152).map { "${it.toString().padStart(3, '0')}.webp" }
|
||||||
|
|
||||||
private const val REPEAT_COUNT = 2
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示动画 WebP 图片,切换日期时随机选择一个。
|
* 显示动画 WebP 图片,切换日期时随机选择一个。
|
||||||
*
|
*
|
||||||
* 动画播放 3 次(1 + [REPEAT_COUNT])后停止,避免持续解码导致的帧丢失。
|
* 动画无限循环播放。
|
||||||
*
|
*
|
||||||
* @param modifier 应用于图片的 Modifier
|
* @param modifier 应用于图片的 Modifier
|
||||||
* @param contentDescription 无障碍描述
|
* @param contentDescription 无障碍描述
|
||||||
@ -55,7 +53,7 @@ fun AnimatedGif(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val state = rememberAsyncImageState(
|
val state = rememberAsyncImageState(
|
||||||
options = remember { ImageOptions { repeatCount(REPEAT_COUNT) } }
|
options = remember { ImageOptions { repeatCount(-1) } }
|
||||||
)
|
)
|
||||||
|
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
|
|||||||
@ -21,6 +21,8 @@ import androidx.compose.ui.layout.onSizeChanged
|
|||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.zIndex
|
import androidx.compose.ui.zIndex
|
||||||
|
import plus.rua.project.composeTraceBeginSection
|
||||||
|
import plus.rua.project.composeTraceEndSection
|
||||||
import plus.rua.project.util.logd
|
import plus.rua.project.util.logd
|
||||||
import kotlinx.datetime.DatePeriod
|
import kotlinx.datetime.DatePeriod
|
||||||
import kotlinx.datetime.LocalDate
|
import kotlinx.datetime.LocalDate
|
||||||
@ -68,6 +70,7 @@ fun CalendarMonthPage(
|
|||||||
onRowHeightMeasured: ((Int) -> Unit)? = null,
|
onRowHeightMeasured: ((Int) -> Unit)? = null,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
|
composeTraceBeginSection("CalendarMonthPage:$year-$month")
|
||||||
val days = remember(year, month) {
|
val days = remember(year, month) {
|
||||||
generateMonthDays(year, month)
|
generateMonthDays(year, month)
|
||||||
}
|
}
|
||||||
@ -129,6 +132,7 @@ fun CalendarMonthPage(
|
|||||||
else Modifier
|
else Modifier
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
composeTraceEndSection()
|
||||||
weeks.forEachIndexed { weekIndex, week ->
|
weeks.forEachIndexed { weekIndex, week ->
|
||||||
key(weekIndex) {
|
key(weekIndex) {
|
||||||
WeekRow(
|
WeekRow(
|
||||||
|
|||||||
@ -15,6 +15,8 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.runtime.snapshotFlow
|
import androidx.compose.runtime.snapshotFlow
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
|
import plus.rua.project.composeTraceBeginSection
|
||||||
|
import plus.rua.project.composeTraceEndSection
|
||||||
import plus.rua.project.util.logd
|
import plus.rua.project.util.logd
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
import kotlinx.coroutines.flow.drop
|
import kotlinx.coroutines.flow.drop
|
||||||
@ -105,6 +107,7 @@ fun CalendarPager(
|
|||||||
if (isCurrentPage) {
|
if (isCurrentPage) {
|
||||||
logd("AnimLog", "[CalendarPager] Compose page=$page ($year-$month) alpha=$alpha pageOffset=$pageOffset")
|
logd("AnimLog", "[CalendarPager] Compose page=$page ($year-$month) alpha=$alpha pageOffset=$pageOffset")
|
||||||
}
|
}
|
||||||
|
composeTraceBeginSection("CalendarPager:Page:$year-$month")
|
||||||
CalendarMonthPage(
|
CalendarMonthPage(
|
||||||
year = year,
|
year = year,
|
||||||
month = month,
|
month = month,
|
||||||
@ -137,5 +140,6 @@ fun CalendarPager(
|
|||||||
onRowHeightMeasured = onRowHeightMeasured,
|
onRowHeightMeasured = onRowHeightMeasured,
|
||||||
modifier = Modifier.alpha(alpha)
|
modifier = Modifier.alpha(alpha)
|
||||||
)
|
)
|
||||||
|
composeTraceEndSection()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,10 +1,13 @@
|
|||||||
package plus.rua.project.baseline
|
package plus.rua.project.baseline
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.benchmark.macro.junit4.BaselineProfileRule
|
import androidx.benchmark.macro.junit4.BaselineProfileRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.uiautomator.By
|
import androidx.test.uiautomator.By
|
||||||
import androidx.test.uiautomator.Direction
|
import androidx.test.uiautomator.Direction
|
||||||
import androidx.test.uiautomator.Until
|
import androidx.test.uiautomator.Until
|
||||||
|
import org.junit.Assert.assertNotNull
|
||||||
|
import org.junit.Assert.fail
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@ -44,95 +47,95 @@ class BaselineProfileGenerator {
|
|||||||
packageName = "plus.rua.project",
|
packageName = "plus.rua.project",
|
||||||
includeInStartupProfile = true,
|
includeInStartupProfile = true,
|
||||||
profileBlock = {
|
profileBlock = {
|
||||||
|
val TAG = "BaselineProfile"
|
||||||
|
|
||||||
// 1. 冷启动:从 launcher 启动应用
|
// 1. 冷启动:从 launcher 启动应用
|
||||||
// 注:使用 shell command 绕过 startActivityAndWait,因为模拟器的 software
|
|
||||||
// renderer 不支持 gfxinfo framestats,会导致 amStartAndWait 超时。
|
|
||||||
pressHome()
|
pressHome()
|
||||||
device.executeShellCommand(
|
device.executeShellCommand(
|
||||||
"am start -W -n plus.rua.project/.MainActivity"
|
"am start -W -n plus.rua.project/.MainActivity"
|
||||||
)
|
)
|
||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
|
|
||||||
// 3. 模拟用户交互:展开 FAB 菜单
|
// 2. 展开 FAB 菜单,等待菜单项出现
|
||||||
val fab = device.findObject(By.res("plus.rua.project:id/fab_menu"))
|
val fab = device.findObject(By.res("plus.rua.project:id/fab_menu"))
|
||||||
if (fab != null) {
|
assertNotNull("FAB 按钮必须存在", fab)
|
||||||
fab.click()
|
fab!!.click()
|
||||||
device.waitForIdle()
|
val yearViewItem = device.wait(Until.findObject(By.text("年视图")), 3000)
|
||||||
}
|
Log.d(TAG, "FAB 菜单展开: yearViewItem=${yearViewItem != null}")
|
||||||
|
|
||||||
// 4. 切换到年视图(覆盖 YearGridView、YearHeader、MiniMonth 路径)
|
// 3. 切换到年视图(覆盖 YearGridView、YearHeader、MiniMonth 路径)
|
||||||
val yearViewButton = device.findObject(By.text("年视图"))
|
assertNotNull("年视图菜单项必须出现", yearViewItem)
|
||||||
if (yearViewButton != null) {
|
yearViewItem!!.click()
|
||||||
yearViewButton.click()
|
val yearGrid = device.wait(Until.findObject(By.res("plus.rua.project:id/year_grid")), 3000)
|
||||||
device.waitForIdle()
|
Log.d(TAG, "年视图加载: yearGrid=${yearGrid != null}")
|
||||||
}
|
assertNotNull("YearGridView 必须加载", yearGrid)
|
||||||
|
device.waitForIdle()
|
||||||
|
|
||||||
// 5. 在年视图中滑动到不同年份(覆盖动画和分页路径)
|
// 4. 在年视图中滑动到不同年份(覆盖动画和分页路径)
|
||||||
val yearGrid = device.findObject(By.res("plus.rua.project:id/year_grid"))
|
yearGrid!!.swipe(Direction.UP, 0.5f)
|
||||||
if (yearGrid != null) {
|
device.waitForIdle()
|
||||||
yearGrid.swipe(Direction.UP, 0.5f)
|
yearGrid.swipe(Direction.DOWN, 0.5f)
|
||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
yearGrid.swipe(Direction.DOWN, 0.5f)
|
|
||||||
device.waitForIdle()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. 切换回月视图
|
// 5. 展开 FAB 并切换回月视图
|
||||||
val monthViewButton = device.findObject(By.text("月视图"))
|
val fabForMonth = device.findObject(By.res("plus.rua.project:id/fab_menu"))
|
||||||
if (monthViewButton != null) {
|
assertNotNull("FAB 按钮必须存在(返回月视图)", fabForMonth)
|
||||||
monthViewButton.click()
|
fabForMonth!!.click()
|
||||||
device.waitForIdle()
|
val monthViewItem = device.wait(Until.findObject(By.text("月视图")), 3000)
|
||||||
}
|
Log.d(TAG, "FAB 菜单展开: monthViewItem=${monthViewItem != null}")
|
||||||
|
assertNotNull("月视图菜单项必须出现", monthViewItem)
|
||||||
|
monthViewItem!!.click()
|
||||||
|
device.waitForIdle()
|
||||||
|
|
||||||
// 7. 点击某一天(覆盖 DayCell 点击路径 + 底部卡片展开)
|
// 6. 点击某一天(覆盖 DayCell 点击路径 + 底部卡片展开)
|
||||||
val todayCell = device.findObject(By.descContains("今天"))
|
val todayCell = device.findObject(By.descContains("今天"))
|
||||||
?: device.findObject(By.text("21"))
|
?: device.findObject(By.text("21"))
|
||||||
if (todayCell != null) {
|
assertNotNull("DayCell 必须可点击", todayCell)
|
||||||
todayCell.click()
|
todayCell!!.click()
|
||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
}
|
|
||||||
|
|
||||||
// 8. 拖拽 BottomCard 触发月视图↔周视图折叠/展开
|
// 7. 拖拽 BottomCard 触发月视图↔周视图折叠/展开
|
||||||
val bottomCard = device.findObject(By.res("plus.rua.project:id/bottom_card"))
|
val bottomCard = device.findObject(By.res("plus.rua.project:id/bottom_card"))
|
||||||
if (bottomCard != null) {
|
assertNotNull("BottomCard 必须存在", bottomCard)
|
||||||
val bounds = bottomCard.visibleBounds
|
val bounds = bottomCard!!.visibleBounds
|
||||||
val centerX = bounds.centerX()
|
val centerX = bounds.centerX()
|
||||||
val centerY = bounds.centerY()
|
val centerY = bounds.centerY()
|
||||||
val dragDistance = (bounds.height() * 0.4).toInt()
|
val dragDistance = (bounds.height() * 0.4).toInt()
|
||||||
// 向上拖拽 → 折叠到周视图
|
// 向上拖拽 → 折叠到周视图
|
||||||
device.drag(centerX, centerY, centerX, centerY - dragDistance, 20)
|
device.drag(centerX, centerY, centerX, centerY - dragDistance, 20)
|
||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
// 向下拖拽 → 展开到月视图
|
// 向下拖拽 → 展开到月视图
|
||||||
device.drag(centerX, centerY - dragDistance, centerX, centerY, 20)
|
device.drag(centerX, centerY - dragDistance, centerX, centerY, 20)
|
||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
}
|
|
||||||
|
|
||||||
// 9. 展开 FAB 并进入工具页面
|
// 8. 展开 FAB 并进入工具页面
|
||||||
val fabMenu = device.findObject(By.res("plus.rua.project:id/fab_menu"))
|
val fabForTools = device.findObject(By.res("plus.rua.project:id/fab_menu"))
|
||||||
if (fabMenu != null) {
|
assertNotNull("FAB 按钮必须存在(工具页)", fabForTools)
|
||||||
fabMenu.click()
|
fabForTools!!.click()
|
||||||
device.waitForIdle()
|
val toolsButton = device.wait(Until.findObject(By.text("工具")), 3000)
|
||||||
}
|
Log.d(TAG, "FAB 菜单展开: toolsButton=${toolsButton != null}")
|
||||||
val toolsButton = device.findObject(By.text("工具"))
|
assertNotNull("工具菜单项必须出现", toolsButton)
|
||||||
if (toolsButton != null) {
|
toolsButton!!.click()
|
||||||
toolsButton.click()
|
device.waitForIdle()
|
||||||
device.waitForIdle()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 10. 进入日期检查器(覆盖 DateCheckerScreen)
|
// 9. 进入日期检查器(覆盖 DateCheckerScreen)
|
||||||
val dateCheckerEntry = device.findObject(By.res("plus.rua.project:id/tool_date_checker"))
|
val dateCheckerEntry = device.wait(
|
||||||
if (dateCheckerEntry != null) {
|
Until.findObject(By.res("plus.rua.project:id/tool_date_checker")), 3000
|
||||||
dateCheckerEntry.click()
|
)
|
||||||
device.waitForIdle()
|
assertNotNull("日期检查器入口必须存在", dateCheckerEntry)
|
||||||
}
|
dateCheckerEntry!!.click()
|
||||||
|
device.waitForIdle()
|
||||||
|
|
||||||
// 11. 点击日历图标打开 DatePickerDialog(覆盖 DatePicker)
|
// 10. 点击日历图标打开 DatePickerDialog(覆盖 DatePicker)
|
||||||
val datePickerBtn = device.findObject(By.res("plus.rua.project:id/date_picker_button"))
|
val datePickerBtn = device.wait(
|
||||||
|
Until.findObject(By.res("plus.rua.project:id/date_picker_button")), 3000
|
||||||
|
)
|
||||||
if (datePickerBtn != null) {
|
if (datePickerBtn != null) {
|
||||||
datePickerBtn.click()
|
datePickerBtn.click()
|
||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12. 等待 DatePickerDialog 并点击确定
|
// 11. 等待 DatePickerDialog 并点击确定
|
||||||
device.wait(Until.findObject(By.text("确定")), 2000)
|
device.wait(Until.findObject(By.text("确定")), 2000)
|
||||||
val confirmBtn = device.findObject(By.text("确定"))
|
val confirmBtn = device.findObject(By.text("确定"))
|
||||||
if (confirmBtn != null) {
|
if (confirmBtn != null) {
|
||||||
@ -140,54 +143,56 @@ class BaselineProfileGenerator {
|
|||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13. 点击 FAB 添加新行(覆盖 FAB + LazyColumn items 重组)
|
// 12. 点击 FAB 添加新行(覆盖 FAB + LazyColumn items 重组)
|
||||||
val dateCheckerFab = device.findObject(By.res("plus.rua.project:id/date_checker_fab"))
|
val dateCheckerFab = device.findObject(By.res("plus.rua.project:id/date_checker_fab"))
|
||||||
if (dateCheckerFab != null) {
|
if (dateCheckerFab != null) {
|
||||||
dateCheckerFab.click()
|
dateCheckerFab.click()
|
||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14. 返回工具页
|
// 13. 返回工具页
|
||||||
device.pressBack()
|
|
||||||
device.waitForIdle()
|
|
||||||
|
|
||||||
// 15. 返回主界面
|
|
||||||
device.pressBack()
|
|
||||||
device.waitForIdle()
|
|
||||||
|
|
||||||
// 16. 左右滑动切换月份(覆盖 CalendarPager 翻页)
|
|
||||||
val calendarPager = device.findObject(By.res("plus.rua.project:id/calendar_pager"))
|
|
||||||
if (calendarPager != null) {
|
|
||||||
calendarPager.swipe(Direction.LEFT, 0.5f)
|
|
||||||
device.waitForIdle()
|
|
||||||
calendarPager.swipe(Direction.RIGHT, 0.5f)
|
|
||||||
device.waitForIdle()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 17. 进入关于页面(覆盖 AboutScreen + AnimatedGif)
|
|
||||||
val aboutButton = device.findObject(By.text("关于"))
|
|
||||||
if (aboutButton != null) {
|
|
||||||
aboutButton.click()
|
|
||||||
device.waitForIdle()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 11. 进入开源许可页面(覆盖 LicensesScreen)
|
|
||||||
val licensesButton = device.findObject(By.text("开源许可"))
|
|
||||||
if (licensesButton != null) {
|
|
||||||
licensesButton.click()
|
|
||||||
device.waitForIdle()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 12. 等待许可列表加载
|
|
||||||
device.wait(Until.findObject(By.textContains("Apache")), 2000)
|
|
||||||
|
|
||||||
// 13. 返回关于页
|
|
||||||
device.pressBack()
|
device.pressBack()
|
||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
|
|
||||||
// 14. 返回主界面
|
// 14. 返回主界面
|
||||||
device.pressBack()
|
device.pressBack()
|
||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
|
|
||||||
|
// 15. 左右滑动切换月份(覆盖 CalendarPager 翻页)
|
||||||
|
val calendarPager = device.findObject(By.res("plus.rua.project:id/calendar_pager"))
|
||||||
|
assertNotNull("CalendarPager 必须存在", calendarPager)
|
||||||
|
calendarPager!!.swipe(Direction.LEFT, 0.5f)
|
||||||
|
device.waitForIdle()
|
||||||
|
calendarPager.swipe(Direction.RIGHT, 0.5f)
|
||||||
|
device.waitForIdle()
|
||||||
|
|
||||||
|
// 16. 进入关于页面(覆盖 AboutScreen + AnimatedGif)
|
||||||
|
val fabForAbout = device.findObject(By.res("plus.rua.project:id/fab_menu"))
|
||||||
|
assertNotNull("FAB 按钮必须存在(关于页)", fabForAbout)
|
||||||
|
fabForAbout!!.click()
|
||||||
|
val aboutButton = device.wait(Until.findObject(By.text("关于")), 3000)
|
||||||
|
assertNotNull("关于菜单项必须出现", aboutButton)
|
||||||
|
aboutButton!!.click()
|
||||||
|
device.waitForIdle()
|
||||||
|
|
||||||
|
// 17. 进入开源许可页面(覆盖 LicensesScreen)
|
||||||
|
val licensesButton = device.wait(Until.findObject(By.text("开源许可")), 3000)
|
||||||
|
assertNotNull("开源许可按钮必须存在", licensesButton)
|
||||||
|
licensesButton!!.click()
|
||||||
|
device.waitForIdle()
|
||||||
|
|
||||||
|
// 18. 等待许可列表加载
|
||||||
|
device.wait(Until.findObject(By.textContains("Apache")), 2000)
|
||||||
|
|
||||||
|
// 19. 返回关于页
|
||||||
|
device.pressBack()
|
||||||
|
device.waitForIdle()
|
||||||
|
|
||||||
|
// 20. 返回主界面
|
||||||
|
device.pressBack()
|
||||||
|
device.waitForIdle()
|
||||||
|
|
||||||
|
Log.d(TAG, "Baseline profile 生成完成,所有路径已覆盖")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user