Skip to content

Commit acb2128

Browse files
committed
feat: introduce platform-specific browser action and page state implementations #532
- Added Android stub implementations for `BrowserActionExecutor` and `PageStateExtractor`. - Defined `BrowserActionExecutor` and `PageStateExtractor` as `expect`/`actual` interfaces for multiplatform support. - Implemented a self-healing locator for element selector recovery with algorithmic and LLM-based approaches. - Introduced comprehensive models for test actions, results, and page states with serialization support.
1 parent 7c59d36 commit acb2128

File tree

23 files changed

+3928
-0
lines changed

23 files changed

+3928
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package cc.unitmesh.agent.e2etest.executor
2+
3+
import cc.unitmesh.agent.e2etest.model.*
4+
5+
/**
6+
* Android implementation of BrowserActionExecutor.
7+
*
8+
* @see <a href="https://github.com/phodal/auto-dev/issues/532">Issue #532</a>
9+
*/
10+
actual interface BrowserActionExecutor {
11+
actual val isAvailable: Boolean
12+
actual suspend fun execute(action: TestAction, context: ActionExecutionContext): ActionResult
13+
actual suspend fun navigateTo(url: String): ActionResult
14+
actual suspend fun click(tagId: Int, options: ClickOptions): ActionResult
15+
actual suspend fun type(tagId: Int, text: String, options: TypeOptions): ActionResult
16+
actual suspend fun scroll(direction: ScrollDirection, amount: Int, tagId: Int?): ActionResult
17+
actual suspend fun waitFor(condition: WaitCondition): ActionResult
18+
actual suspend fun pressKey(key: String, modifiers: List<KeyModifier>): ActionResult
19+
actual suspend fun screenshot(name: String, fullPage: Boolean): ScreenshotResult
20+
actual fun close()
21+
}
22+
23+
/**
24+
* Android stub implementation
25+
*/
26+
class AndroidBrowserActionExecutor(
27+
private val config: BrowserExecutorConfig
28+
) : BrowserActionExecutor {
29+
30+
override val isAvailable: Boolean = false
31+
32+
override suspend fun execute(action: TestAction, context: ActionExecutionContext): ActionResult {
33+
return ActionResult.failure("Not implemented on Android", 0)
34+
}
35+
36+
override suspend fun navigateTo(url: String): ActionResult {
37+
return ActionResult.failure("Not implemented", 0)
38+
}
39+
40+
override suspend fun click(tagId: Int, options: ClickOptions): ActionResult {
41+
return ActionResult.failure("Not implemented", 0)
42+
}
43+
44+
override suspend fun type(tagId: Int, text: String, options: TypeOptions): ActionResult {
45+
return ActionResult.failure("Not implemented", 0)
46+
}
47+
48+
override suspend fun scroll(direction: ScrollDirection, amount: Int, tagId: Int?): ActionResult {
49+
return ActionResult.failure("Not implemented", 0)
50+
}
51+
52+
override suspend fun waitFor(condition: WaitCondition): ActionResult {
53+
return ActionResult.failure("Not implemented", 0)
54+
}
55+
56+
override suspend fun pressKey(key: String, modifiers: List<KeyModifier>): ActionResult {
57+
return ActionResult.failure("Not implemented", 0)
58+
}
59+
60+
override suspend fun screenshot(name: String, fullPage: Boolean): ScreenshotResult {
61+
return ScreenshotResult(success = false, error = "Not implemented")
62+
}
63+
64+
override fun close() {}
65+
}
66+
67+
actual fun createBrowserActionExecutor(config: BrowserExecutorConfig): BrowserActionExecutor? {
68+
return AndroidBrowserActionExecutor(config)
69+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package cc.unitmesh.agent.e2etest.perception
2+
3+
import cc.unitmesh.agent.e2etest.model.*
4+
5+
/**
6+
* Android implementation of PageStateExtractor.
7+
*
8+
* Uses Android WebView for browser control.
9+
*
10+
* @see <a href="https://github.com/phodal/auto-dev/issues/532">Issue #532</a>
11+
*/
12+
actual interface PageStateExtractor {
13+
actual val isAvailable: Boolean
14+
actual suspend fun extractPageState(): PageState
15+
actual suspend fun extractAccessibilityTree(): AccessibilityNode?
16+
actual suspend fun extractCleanDOM(): String
17+
actual suspend fun captureScreenshotWithSoM(): SoMScreenshot?
18+
actual suspend fun getActionableElements(): List<ActionableElement>
19+
actual suspend fun getElementByTagId(tagId: Int): ActionableElement?
20+
actual suspend fun getElementFingerprint(selector: String): ElementFingerprint?
21+
actual suspend fun isPageLoaded(): Boolean
22+
actual suspend fun getCurrentUrl(): String
23+
actual suspend fun getPageTitle(): String
24+
actual fun close()
25+
}
26+
27+
/**
28+
* Android stub implementation - WebView integration pending
29+
*/
30+
class AndroidPageStateExtractor(
31+
private val config: PageStateExtractorConfig
32+
) : PageStateExtractor {
33+
34+
override val isAvailable: Boolean = false
35+
36+
override suspend fun extractPageState(): PageState {
37+
return PageState(
38+
url = "",
39+
title = "",
40+
viewport = Viewport(config.viewportWidth, config.viewportHeight),
41+
actionableElements = emptyList(),
42+
capturedAt = System.currentTimeMillis()
43+
)
44+
}
45+
46+
override suspend fun extractAccessibilityTree(): AccessibilityNode? = null
47+
override suspend fun extractCleanDOM(): String = ""
48+
override suspend fun captureScreenshotWithSoM(): SoMScreenshot? = null
49+
override suspend fun getActionableElements(): List<ActionableElement> = emptyList()
50+
override suspend fun getElementByTagId(tagId: Int): ActionableElement? = null
51+
override suspend fun getElementFingerprint(selector: String): ElementFingerprint? = null
52+
override suspend fun isPageLoaded(): Boolean = false
53+
override suspend fun getCurrentUrl(): String = ""
54+
override suspend fun getPageTitle(): String = ""
55+
override fun close() {}
56+
}
57+
58+
actual fun createPageStateExtractor(config: PageStateExtractorConfig): PageStateExtractor? {
59+
return AndroidPageStateExtractor(config)
60+
}

0 commit comments

Comments
 (0)