fix(android): locate address above spec panel (#193)

This commit is contained in:
QiuSW
2026-09-02 09:33:27 +08:00
parent a1a9343bf6
commit 15e2a008a7
2 changed files with 34 additions and 8 deletions
@@ -48,14 +48,19 @@ class PurchaseLiveAutomation(
var previousSignature: String? = null
var unchangedCount = 0
var verifiedPanelBounds: NodeBounds? = null
var trustedPurchaseSurfaceBounds: NodeBounds? = null
for (attempt in 0 until 5) {
pageProblem(snapshot)
val panel = purchasePanelScrollTargets(snapshot)
if (panel.size == 1) verifiedPanelBounds = panel.single().bounds
if (verifiedPanelBounds == null && input != null) {
verifiedPanelBounds = verifiedPurchaseSurfaceBounds(snapshot, input)
if (trustedPurchaseSurfaceBounds == null && input != null) {
trustedPurchaseSurfaceBounds = verifiedPurchaseSurfaceBounds(snapshot, input)
}
val entries = verifiedPanelBounds?.let { bounds -> addressEntryTargets(snapshot, bounds) }.orEmpty()
val entries = mergedDirect(
listOfNotNull(trustedPurchaseSurfaceBounds, verifiedPanelBounds)
.distinct()
.flatMap { bounds -> addressEntryTargets(snapshot, bounds) },
)
if (entries.size == 1) {
when (driver.tapPurchaseFresh(entries.single())) {
FreshActionResult.SUCCESS -> Unit
@@ -68,7 +73,8 @@ class PurchaseLiveAutomation(
}
return editAndVerifyAddress(snapshot, addressSuffix)
}
val fallbackBounds = if (panel.size == 1) panel.single().bounds else input?.let { verifiedPurchaseSurfaceBounds(snapshot, it) }
val fallbackBounds = if (panel.size == 1) panel.single().bounds else trustedPurchaseSurfaceBounds
?: input?.let { verifiedPurchaseSurfaceBounds(snapshot, it) }
?: fail("PURCHASE_ADDRESS_ENTRY_AMBIGUOUS", "无法确认唯一的采购页面滑动区域,未创建订单")
val signature = viewportSignature(snapshot, fallbackBounds)
unchangedCount = if (signature == previousSignature) unchangedCount + 1 else 0
@@ -335,6 +335,18 @@ class PurchaseLiveAutomationTest {
assertEquals("address-card", driver.lastAddressTapPath)
}
@Test
fun `verified purchase surface finds address above a separate scrollable spec panel`() {
val driver = LiveDriver(addressClipped = true, addressAboveScrollablePanel = true)
val address = PurchaseLiveAutomation(driver, pause = {}).updateShippingAddress(input().copy(addressSuffix = "_cg58"))
assertEquals("广东省广州市天园街道骏景花园骏晖轩1202_cg58", address.expectedAddress)
assertEquals(1, driver.scopedSwipes)
assertEquals(0, driver.surfacePullDowns)
assertEquals(1, driver.addressTaps)
assertEquals("address-card", driver.lastAddressTapPath)
}
@Test
fun `verified purchase surface pulls down when PDD exposes multiple scrollable panels`() {
val driver = LiveDriver(addressClipped = true, duplicatePanels = true)
@@ -414,6 +426,7 @@ class PurchaseLiveAutomationTest {
private val panelScrollableAfterReveal: Boolean = true,
private val hideSelectedSummary: Boolean = false,
private val addressAtTopAfterReveal: Boolean = false,
private val addressAboveScrollablePanel: Boolean = false,
private val chooserAfterSubmit: Boolean = false,
private val trustedChooser: Boolean = true,
private val splitConfirmationAddress: Boolean = false,
@@ -489,7 +502,12 @@ class PurchaseLiveAutomationTest {
else -> {
val nodes = mutableListOf(
node("root", "", bounds = NodeBounds(0, 0, 1080, 2200)),
node("panel", "", scrollable = if (addressVisible) panelScrollableAfterReveal else panelInitiallyScrollable, bounds = NodeBounds(0, 400, 1080, 2100)),
node(
"panel",
"",
scrollable = if (addressVisible) panelScrollableAfterReveal else panelInitiallyScrollable,
bounds = if (addressAboveScrollablePanel) NodeBounds(0, 900, 1080, 2079) else NodeBounds(0, 400, 1080, 2100),
),
node("price", "¥20.00"),
node("quantity", "2", className = "android.widget.EditText"),
node("submit-parent", "", clickable = true), node("submit", "提交订单", parentPath = "submit-parent"),
@@ -509,9 +527,11 @@ class PurchaseLiveAutomationTest {
nodes += node("phone", "138****5678", bounds = NodeBounds(20, 650, 300, 710), parentPath = "address-card")
nodes += node("phone-duplicate", "138****5678", bounds = NodeBounds(20, 735, 300, 795), parentPath = "address-card")
}
addressAtTopAfterReveal -> {
nodes += node("address-card", "", clickable = true, bounds = NodeBounds(0, 300, 1080, 520))
nodes += node("phone", "138****5678", bounds = NodeBounds(300, 330, 800, 380), parentPath = "address-card")
addressAtTopAfterReveal || addressAboveScrollablePanel -> {
val cardBounds = if (addressAboveScrollablePanel) NodeBounds(0, 366, 1080, 520) else NodeBounds(0, 300, 1080, 520)
val phoneBounds = if (addressAboveScrollablePanel) NodeBounds(412, 382, 993, 431) else NodeBounds(300, 330, 800, 380)
nodes += node("address-card", "", clickable = true, bounds = cardBounds)
nodes += node("phone", "138****5678", bounds = phoneBounds, parentPath = "address-card")
}
else -> {
nodes += node("address-card", "", clickable = true, bounds = NodeBounds(0, 620, 1080, 850))