185 lines
6.0 KiB
Python
185 lines
6.0 KiB
Python
# coding=utf-8
|
|
"""
|
|
APA (艺赛旗) BrowserAdapter 实现
|
|
将 contract_flow_steps.BrowserAdapter 协议映射到 ubpa/iedge 浏览器 API
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
import json
|
|
import time
|
|
import base64
|
|
|
|
|
|
def _make_apa_attr_map(css_selector: str) -> str:
|
|
"""将 CSS 选择器转换为 APA attrMap JSON 格式"""
|
|
hierarchy = {
|
|
"hasReachedRelativeAncestor": "false",
|
|
"nodeHierarchyInfo": [
|
|
{
|
|
"isPresentInSelector": 1,
|
|
"otherAttributes": {},
|
|
"selectorInfo": {
|
|
"attributes": {
|
|
"css-selector": css_selector,
|
|
"tag": "",
|
|
"xpath": ""
|
|
},
|
|
"index": 0,
|
|
"tagName": ""
|
|
}
|
|
}
|
|
]
|
|
}
|
|
return json.dumps(hierarchy, ensure_ascii=False)
|
|
|
|
|
|
class ApaBrowserAdapter:
|
|
"""APA Studio Edge 浏览器适配器,实现 BrowserAdapter 协议"""
|
|
|
|
def __init__(self, url: str = ""):
|
|
from ubpa.iobject.browser import Browser
|
|
self._browser = Browser(Browser.AppName.edge)
|
|
self._url = url
|
|
self._is_open = False
|
|
|
|
def _ensure_open(self):
|
|
if not self._is_open:
|
|
from ubpa.iobject.browser import Browser
|
|
self._browser.open(url=self._url, timeout=30)
|
|
self._is_open = True
|
|
|
|
# ---- BrowserAdapter 协议实现 ----
|
|
|
|
def open_url(self, url: str) -> None:
|
|
self._url = url
|
|
self._ensure_open()
|
|
|
|
def fill_first(self, selectors: list[str], value: str) -> None:
|
|
self._ensure_open()
|
|
import ubpa.iedge as iedge
|
|
last_error = None
|
|
for sel in selectors:
|
|
try:
|
|
attr_map = _make_apa_attr_map(sel)
|
|
iedge.set_element_val(
|
|
attrMap=attr_map, title="*", url="*",
|
|
text=str(value), waitfor=5, program="msedge.exe"
|
|
)
|
|
time.sleep(0.3)
|
|
return
|
|
except Exception as e:
|
|
last_error = e
|
|
continue
|
|
raise RuntimeError(
|
|
f"fill_first failed for all selectors {selectors}: {last_error}"
|
|
)
|
|
|
|
def click_first(self, selectors: list[str]) -> None:
|
|
self._ensure_open()
|
|
import ubpa.iedge as iedge
|
|
last_error = None
|
|
for sel in selectors:
|
|
try:
|
|
attr_map = _make_apa_attr_map(sel)
|
|
iedge.do_click_pos(
|
|
attrMap=attr_map, title="*", url="*",
|
|
waitfor=5, program="msedge.exe"
|
|
)
|
|
time.sleep(0.5)
|
|
return
|
|
except Exception as e:
|
|
last_error = e
|
|
continue
|
|
raise RuntimeError(
|
|
f"click_first failed for all selectors {selectors}: {last_error}"
|
|
)
|
|
|
|
def wait_for_text(self, text: str, timeout_seconds: int = 15) -> None:
|
|
import ubpa.iedge as iedge
|
|
elapsed = 0
|
|
interval = 1
|
|
while elapsed < timeout_seconds:
|
|
try:
|
|
# 尝试获取页面文本匹配
|
|
result = iedge.get_element_val(
|
|
attrMap=_make_apa_attr_map(f"text={text}"),
|
|
title="*", url="*", waitfor=3, program="msedge.exe"
|
|
)
|
|
if result:
|
|
return
|
|
except Exception:
|
|
pass
|
|
time.sleep(interval)
|
|
elapsed += interval
|
|
raise TimeoutError(f"wait_for_text '{text}' timed out after {timeout_seconds}s")
|
|
|
|
def select_first(self, selectors: list[str], value: str) -> None:
|
|
self._ensure_open()
|
|
import ubpa.iedge as iedge
|
|
last_error = None
|
|
for sel in selectors:
|
|
try:
|
|
attr_map = _make_apa_attr_map(sel)
|
|
iedge.set_element_selected_item(
|
|
attrMap=attr_map, title="*", url="*",
|
|
itemText=value, itemMode="text",
|
|
waitfor=5, program="msedge.exe"
|
|
)
|
|
time.sleep(0.3)
|
|
return
|
|
except Exception as e:
|
|
last_error = e
|
|
continue
|
|
raise RuntimeError(
|
|
f"select_first failed for all selectors {selectors}: {last_error}"
|
|
)
|
|
|
|
def upload_file_first(self, selectors: list[str], file_path: str) -> None:
|
|
self._ensure_open()
|
|
import ubpa.iedge as iedge
|
|
last_error = None
|
|
for sel in selectors:
|
|
try:
|
|
attr_map = _make_apa_attr_map(sel)
|
|
iedge.set_element_val(
|
|
attrMap=attr_map, title="*", url="*",
|
|
text=file_path, waitfor=5, program="msedge.exe"
|
|
)
|
|
time.sleep(1)
|
|
return
|
|
except Exception as e:
|
|
last_error = e
|
|
continue
|
|
raise RuntimeError(
|
|
f"upload_file_first failed for all selectors {selectors}: {last_error}"
|
|
)
|
|
|
|
def read_first(self, selectors: list[str], value_name: str = "") -> str:
|
|
self._ensure_open()
|
|
import ubpa.iedge as iedge
|
|
last_error = None
|
|
for sel in selectors:
|
|
try:
|
|
attr_map = _make_apa_attr_map(sel)
|
|
result = iedge.get_element_val(
|
|
attrMap=attr_map, title="*", url="*",
|
|
waitfor=5, program="msedge.exe"
|
|
)
|
|
if result:
|
|
return str(result)
|
|
except Exception as e:
|
|
last_error = e
|
|
continue
|
|
raise RuntimeError(
|
|
f"read_first failed for all selectors {selectors}: {last_error}"
|
|
)
|
|
|
|
def screenshot(self, name: str) -> str:
|
|
import os
|
|
save_dir = os.path.join(os.path.dirname(__file__), "screenshots")
|
|
os.makedirs(save_dir, exist_ok=True)
|
|
path = os.path.join(save_dir, f"{name}.png")
|
|
# APA browser screenshot capability - placeholder
|
|
print(f" [screenshot] {name} -> {path}")
|
|
return path
|