fix: 完整遍历尺码与套餐第二规格 (#167)
This commit is contained in:
@@ -460,6 +460,55 @@ class DefaultPackageDevice(DefaultSizeDevice):
|
||||
return super()._spec_xml().replace('text="尺码"', 'text="套餐"')
|
||||
|
||||
|
||||
class HorizontalPackageDevice:
|
||||
"""模拟独立横向套餐列表,每屏只有三个且相邻页面有重叠。"""
|
||||
|
||||
packages = tuple(f"套餐{i}" for i in range(1, 8))
|
||||
|
||||
def __init__(self, expected_count=7):
|
||||
self.page = 1
|
||||
self.expected_count = expected_count
|
||||
self.swipes = []
|
||||
self.clicks = []
|
||||
|
||||
def dump_hierarchy(self):
|
||||
start = min(self.page * 2, len(self.packages) - 3)
|
||||
visible = self.packages[start : start + 3]
|
||||
options = []
|
||||
for index, text in enumerate(visible):
|
||||
left = 36 + index * 320
|
||||
options.append(
|
||||
f'<node text="{text}" clickable="true" '
|
||||
f'bounds="[{left},1250][{left + 280},1370]" />'
|
||||
)
|
||||
return f"""<hierarchy>
|
||||
<node bounds="[0,0][1080,2340]">
|
||||
<node class="android.widget.ScrollView" scrollable="true"
|
||||
bounds="[0,650][1080,2200]">
|
||||
<node text="券后 ¥5.69" bounds="[300,680][600,740]" />
|
||||
<node text="款式" bounds="[36,800][180,860]" />
|
||||
<node text="口罩款" clickable="true" selected="true"
|
||||
bounds="[36,900][300,1000]" />
|
||||
<node text="套餐({self.expected_count})"
|
||||
bounds="[36,1120][240,1180]" />
|
||||
<node class="androidx.recyclerview.widget.RecyclerView"
|
||||
scrollable="true" bounds="[24,1200][1056,1420]">
|
||||
{''.join(options)}
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</hierarchy>"""
|
||||
|
||||
def swipe(self, x1, y1, x2, y2, duration=0.35):
|
||||
self.swipes.append((x1, y1, x2, y2, duration))
|
||||
if abs(x2 - x1) <= abs(y2 - y1):
|
||||
return
|
||||
if x1 > x2:
|
||||
self.page = min(self.page + 1, 2)
|
||||
else:
|
||||
self.page = max(self.page - 1, 0)
|
||||
|
||||
|
||||
class FakeClock:
|
||||
"""测试用时钟:sleep 只推进虚拟时间,不真的等待。"""
|
||||
|
||||
@@ -1171,6 +1220,44 @@ class PddCollectParserTest(unittest.TestCase):
|
||||
self.assertEqual(data["dimensions"][1]["key"], "size")
|
||||
self.assertEqual(data["dimensions"][1]["name"], "套餐")
|
||||
|
||||
def test_horizontal_packages_are_scanned_from_left_to_right_without_clicks(self):
|
||||
device = HorizontalPackageDevice()
|
||||
service = PddCollectService(
|
||||
PddDeviceService(lambda _serial: device),
|
||||
"USB-001",
|
||||
"client-001",
|
||||
sleeper=lambda _seconds: None,
|
||||
)
|
||||
|
||||
result = service._collect_size_dimension(device)
|
||||
|
||||
self.assertIsNotNone(result)
|
||||
self.assertEqual(result.name, "套餐(7)")
|
||||
self.assertEqual(
|
||||
[value.text for value in result.values],
|
||||
list(device.packages),
|
||||
)
|
||||
self.assertEqual(device.clicks, [])
|
||||
self.assertTrue(
|
||||
all(abs(x2 - x1) > abs(y2 - y1) for x1, y1, x2, y2, _ in device.swipes)
|
||||
)
|
||||
|
||||
def test_package_heading_count_rejects_partial_collection(self):
|
||||
device = HorizontalPackageDevice(expected_count=8)
|
||||
service = PddCollectService(
|
||||
PddDeviceService(lambda _serial: device),
|
||||
"USB-001",
|
||||
"client-001",
|
||||
sleeper=lambda _seconds: None,
|
||||
)
|
||||
|
||||
with self.assertRaises(PddCollectError) as raised:
|
||||
service._collect_size_dimension(device)
|
||||
|
||||
self.assertEqual(raised.exception.code, "PDD_DATA_SPEC_INCOMPLETE")
|
||||
self.assertEqual(raised.exception.diagnostics["expected_count"], 8)
|
||||
self.assertEqual(raised.exception.diagnostics["collected_count"], 7)
|
||||
|
||||
def test_visible_click_is_fallback_when_page_exposes_no_selection_state(self):
|
||||
xml_data = keep_only_one_sku(self.spec_xml)
|
||||
root = ET.fromstring(xml_data)
|
||||
|
||||
Reference in New Issue
Block a user