fix(android): retry copy-link click after share rerender (#133)
This commit is contained in:
@@ -11,8 +11,8 @@ android {
|
||||
applicationId = "cn.ilapage.goauto.agent"
|
||||
minSdk = 23
|
||||
targetSdk = 34
|
||||
versionCode = 32
|
||||
versionName = "0.9.19"
|
||||
versionCode = 33
|
||||
versionName = "0.9.20"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
|
||||
+33
-6
@@ -146,13 +146,10 @@ class CurrentPageIdentityRunner(
|
||||
AgentDiagnosticReason.PANEL_FOUND,
|
||||
elapsedMs = now() - startedAt,
|
||||
)
|
||||
val copy = uniqueAction(panel, config.copyLinkAliases, topOnly = false)
|
||||
?: return failure("PDD_COPY_LINK_UNAVAILABLE", "复制链接入口不唯一")
|
||||
val copiedAt = now()
|
||||
when (driver.clickFresh(copy)) {
|
||||
FreshActionResult.SUCCESS -> Unit
|
||||
FreshActionResult.AMBIGUOUS -> return failure("PDD_COPY_LINK_UNAVAILABLE", "复制链接入口不唯一")
|
||||
else -> return failure("PDD_COPY_LINK_UNAVAILABLE", "复制商品链接失败")
|
||||
val copyResult = clickCopyLinkWithRetry(config.copyLinkAliases)
|
||||
if (!copyResult.successful) {
|
||||
return failure("PDD_COPY_LINK_UNAVAILABLE", copyResult.message)
|
||||
}
|
||||
val clipboard = readFreshClipboard(copiedAt, config.clipboardTimeoutMs)
|
||||
diagnose(
|
||||
@@ -354,6 +351,35 @@ class CurrentPageIdentityRunner(
|
||||
}
|
||||
return ShareClickResult(false, message)
|
||||
}
|
||||
private fun clickCopyLinkWithRetry(aliases: List<String>): ShareClickResult {
|
||||
val deadline = now() + COPY_LINK_CLICK_RETRY_MILLIS
|
||||
var lastReason = FreshClickReason.TARGET_NOT_FOUND
|
||||
do {
|
||||
val snapshot = driver.capture()
|
||||
detailProblem(snapshot)?.let { return ShareClickResult(false, it.message) }
|
||||
val candidates = actionCandidates(snapshot, aliases, topOnly = false)
|
||||
if (candidates.size > 1) return ShareClickResult(false, "复制链接入口不唯一")
|
||||
val target = candidates.singleOrNull()
|
||||
if (target != null) {
|
||||
val outcome = driver.clickFreshDetailed(target)
|
||||
lastReason = outcome.reason
|
||||
when (outcome.result) {
|
||||
FreshActionResult.SUCCESS -> return ShareClickResult(true, "")
|
||||
FreshActionResult.AMBIGUOUS -> return ShareClickResult(false, "复制链接入口不唯一")
|
||||
FreshActionResult.NOT_FOUND, FreshActionResult.FAILED -> Unit
|
||||
}
|
||||
}
|
||||
pause(POLL_MILLIS)
|
||||
} while (now() <= deadline)
|
||||
return ShareClickResult(
|
||||
false,
|
||||
when (lastReason) {
|
||||
FreshClickReason.NO_CLICKABLE_ANCESTOR -> "复制链接入口暂时无法点击"
|
||||
else -> "复制商品链接失败"
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun waitForAction(aliases: List<String>, timeoutMillis: Long): UiSnapshot? {
|
||||
val deadline = now() + timeoutMillis
|
||||
@@ -517,6 +543,7 @@ class CurrentPageIdentityRunner(
|
||||
const val POLL_MILLIS = 100L
|
||||
const val SHARE_STABLE_MILLIS = 300L
|
||||
const val SHARE_CLICK_RETRY_MILLIS = 1_000L
|
||||
const val COPY_LINK_CLICK_RETRY_MILLIS = 1_000L
|
||||
const val PDD_PACKAGE = "com.xunmeng.pinduoduo"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,6 +294,31 @@ class CurrentPageCollectionTest {
|
||||
assertTrue(events.any { it.reason == AgentDiagnosticReason.LONG_LINK_DIRECT })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun retriesCopyLinkWhenSharePanelRerendersBeforeFreshClick() {
|
||||
var currentTime = 0L
|
||||
val driver = FakeDriver(
|
||||
snapshots = List(6) { detailSnapshot() } + List(4) { sharePanelSnapshot() },
|
||||
freshOutcomes = ArrayDeque(
|
||||
listOf(
|
||||
FreshClickOutcome(FreshActionResult.SUCCESS, FreshClickReason.SUCCESS, candidateCount = 1),
|
||||
FreshClickOutcome(FreshActionResult.NOT_FOUND, FreshClickReason.TARGET_NOT_FOUND),
|
||||
FreshClickOutcome(FreshActionResult.SUCCESS, FreshClickReason.SUCCESS, candidateCount = 1),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
val result = CurrentPageIdentityRunner(
|
||||
driver = driver,
|
||||
readFreshClipboard = { _, _ -> ClipboardReadOutcome("https://mobile.yangkeduo.com/goods.html?goods_id=12345") },
|
||||
now = { currentTime },
|
||||
pause = { currentTime += it },
|
||||
).identify(rule())
|
||||
|
||||
assertTrue(result.successful)
|
||||
assertEquals(listOf("分享", "复制链接", "复制链接"), driver.clicked)
|
||||
}
|
||||
|
||||
private class FakeDriver(
|
||||
private val snapshots: List<UiSnapshot>,
|
||||
private val freshOutcomes: ArrayDeque<FreshClickOutcome> = ArrayDeque(),
|
||||
|
||||
Reference in New Issue
Block a user