fix: 兼容提交提示型非滚动规格面板 (#175)

This commit is contained in:
chengma
2026-08-12 10:15:19 +08:00
parent 354aa6b264
commit 0f24165ee2
4 changed files with 229 additions and 26 deletions
+62
View File
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<hierarchy rotation="0">
<node package="com.xunmeng.pinduoduo" class="android.widget.FrameLayout"
bounds="[0,0][1080,2376]" visible-to-user="true" enabled="true">
<node package="com.xunmeng.pinduoduo" class="android.widget.LinearLayout"
clickable="true" bounds="[0,120][1080,2328]"
visible-to-user="true" enabled="true">
<node package="com.xunmeng.pinduoduo" class="android.widget.ImageView"
content-desc="关闭" clickable="true" bounds="[975,273][1050,348]"
visible-to-user="true" enabled="true" />
<node package="com.xunmeng.pinduoduo" class="android.widget.TextView"
text="券后¥5.03" bounds="[396,580][679,647]"
visible-to-user="true" enabled="true" />
<node package="com.xunmeng.pinduoduo" class="android.widget.TextView"
text="请选择: 颜色分类 尺码" bounds="[396,731][1053,793]"
visible-to-user="true" enabled="true" />
<node package="com.xunmeng.pinduoduo" class="android.widget.ImageView"
content-desc="减少数量" clickable="true" bounds="[396,829][474,904]"
visible-to-user="true" enabled="true" />
<node package="com.xunmeng.pinduoduo" class="android.widget.EditText"
text="1" clickable="true" bounds="[480,829][561,904]"
visible-to-user="true" enabled="true" />
<node package="com.xunmeng.pinduoduo" class="android.widget.ImageView"
content-desc="增加数量" clickable="true" bounds="[567,829][645,904]"
visible-to-user="true" enabled="true" />
<node package="com.xunmeng.pinduoduo" class="android.widget.TextView"
text="颜色分类" bounds="[36,1102][216,1163]"
visible-to-user="true" enabled="true" />
<node package="com.xunmeng.pinduoduo" class="android.view.ViewGroup"
clickable="true" bounds="[36,1188][352,1591]"
visible-to-user="true" enabled="true">
<node package="com.xunmeng.pinduoduo" class="android.widget.TextView"
text="测试黑色" bounds="[36,1483][352,1591]"
visible-to-user="true" enabled="true" />
</node>
<node package="com.xunmeng.pinduoduo" class="android.view.ViewGroup"
clickable="true" bounds="[382,1188][698,1591]"
visible-to-user="true" enabled="true">
<node package="com.xunmeng.pinduoduo" class="android.widget.TextView"
text="测试红色" bounds="[382,1483][698,1591]"
visible-to-user="true" enabled="true" />
</node>
<node package="com.xunmeng.pinduoduo" class="android.widget.TextView"
text="尺码" bounds="[36,1641][126,1694]"
visible-to-user="true" enabled="true" />
<node package="com.xunmeng.pinduoduo" class="android.widget.TextView"
text="M" clickable="true" bounds="[36,1720][119,1805]"
visible-to-user="true" enabled="true" />
<node package="com.xunmeng.pinduoduo" class="android.widget.TextView"
text="L" clickable="true" bounds="[149,1720][217,1805]"
visible-to-user="true" enabled="true" />
<node package="com.xunmeng.pinduoduo" class="android.widget.FrameLayout"
clickable="true" bounds="[0,2181][1080,2328]"
visible-to-user="true" enabled="true">
<node package="com.xunmeng.pinduoduo" class="android.widget.TextView"
text="选择颜色分类及尺码后,提交订单"
bounds="[208,2225][871,2284]"
visible-to-user="true" enabled="true" />
</node>
</node>
</node>
</hierarchy>
+64
View File
@@ -609,6 +609,9 @@ class PddCollectParserTest(unittest.TestCase):
cls.non_scrollable_spec_xml = (
FIXTURES / "pdd_spec_panel_non_scrollable.xml"
).read_text(encoding="utf-8")
cls.submit_hint_spec_xml = (
FIXTURES / "pdd_spec_panel_submit_hint.xml"
).read_text(encoding="utf-8")
cls.sold_out_xml = (
FIXTURES / "pdd_sold_out_recommendations.xml"
).read_text(encoding="utf-8")
@@ -789,6 +792,41 @@ class PddCollectParserTest(unittest.TestCase):
self.assertEqual(result.raw_price, "¥8.17")
self.assertNotIn("确认款式", [item.name for item in result.dimensions])
def test_parse_non_scrollable_submit_hint_spec_panel(self):
result = parse_spec_panel(self.submit_hint_spec_xml)
self.assertTrue(_is_spec_panel_open(self.submit_hint_spec_xml))
self.assertEqual(
[(item.key, item.name) for item in result.dimensions],
[("color", "颜色分类"), ("size", "尺码")],
)
self.assertEqual(
[value.text for value in result.dimensions[0].values],
["测试黑色", "测试红色"],
)
self.assertEqual(
[value.text for value in result.dimensions[1].values],
["M", "L"],
)
self.assertNotIn(
"请选择: 颜色分类 尺码",
[item.name for item in result.dimensions],
)
def test_isolated_submit_hint_is_not_a_spec_panel(self):
xml_data = """<hierarchy>
<node package="com.xunmeng.pinduoduo"
class="android.widget.FrameLayout" bounds="[0,0][1080,2376]">
<node package="com.xunmeng.pinduoduo" content-desc="关闭"
clickable="true" bounds="[975,273][1050,348]" />
<node package="com.xunmeng.pinduoduo"
text="选择规格后,提交订单" clickable="true"
bounds="[0,2181][1080,2328]" />
</node>
</hierarchy>"""
self.assertFalse(_is_spec_panel_open(xml_data))
def test_non_scrollable_spec_panel_exposes_three_color_rows(self):
service = PddCollectService(
PddDeviceService(lambda _serial: object()),
@@ -1790,6 +1828,32 @@ class PddCollectParserTest(unittest.TestCase):
artifacts = raised.exception.diagnostics["artifacts"]
self.assertTrue(Path(artifacts[0]["path"]).is_file())
def test_open_confirmation_with_unrecognized_structure_is_not_timeout(self):
malformed_panel = self.submit_hint_spec_xml.replace(
'<node package="com.xunmeng.pinduoduo" class="android.widget.EditText"\n'
' text="1" clickable="true" bounds="[480,829][561,904]"\n'
' visible-to-user="true" enabled="true" />',
"",
)
device = FakeCollectDevice(self.home_xml, malformed_panel)
device.opened_url = "https://mobile.yangkeduo.com/goods.html?goods_id=123"
device.panel_open = True
clock = FakeClock()
service = PddCollectService(
PddDeviceService(lambda _serial: device),
"USB-001",
"client-001",
sleeper=clock.sleep,
monotonic=clock.monotonic,
spec_panel_timeout=1.0,
)
with self.assertRaises(PddCollectError) as raised:
service._wait_spec_panel(device)
self.assertEqual(raised.exception.code, "PDD_DATA_SPEC_INCOMPLETE")
self.assertIn("已经打开", raised.exception.message)
def test_transient_empty_spec_trees_are_skipped_during_full_collection(self):
device = TransientSpecTreeDevice(
self.home_xml, keep_only_one_sku(self.spec_xml)