fix: 兼容非滚动面板静态尺码采集 (#177)

This commit is contained in:
chengma
2026-08-12 10:32:01 +08:00
parent e72462b3d8
commit 2088bc3ea6
2 changed files with 118 additions and 0 deletions
+50
View File
@@ -1858,6 +1858,11 @@ class PddCollectService:
"PDD_DATA_SPEC_INCOMPLETE",
f"无法建立第二规格续页上下文:{size_name}",
)
static_dimension = self._non_scrollable_second_dimension(
xml_data, initial_size_dimension
)
if static_dimension is not None:
return static_dimension
continuation = self._build_second_dimension_context(
xml_data, initial_size_dimension
)
@@ -1958,6 +1963,51 @@ class PddCollectService:
tuple(DimensionValue(text, available) for text, available in sizes.items()),
)
def _non_scrollable_second_dimension(
self,
xml_data: str | bytes,
dimension: SpecDimension,
) -> Optional[SpecDimension]:
"""强证据确认非滚动面板时,返回当前树中的完整第二规格。"""
root = _parse_xml(xml_data)
region, _ = self._second_dimension_region(root, dimension)
if region is not None:
return None
parents = {child: parent for parent in root.iter() for child in parent}
if _find_non_scrollable_spec_panel(root, parents) is None:
return None
values: dict[str, bool] = {}
for value in dimension.values:
option_text = self._second_dimension_option_text(value.text)
if option_text is None:
continue
values[option_text] = values.get(option_text, False) or value.available
expected_count = self._dimension_expected_count(dimension.name)
if expected_count is not None and len(values) < expected_count:
raise PddCollectError(
"PDD_DATA_SPEC_INCOMPLETE",
f"{dimension.name}应有 {expected_count} 个选项,实际只采到 {len(values)} 个",
{
"dimension_name": dimension.name,
"expected_count": expected_count,
"collected_count": len(values),
},
)
if not values:
return None
return SpecDimension(
"size",
dimension.name,
tuple(
DimensionValue(text, available)
for text, available in values.items()
),
)
def _move_second_dimension_to_start(
self, device: Any, xml_data: str
) -> tuple[str, bool]:
+68
View File
@@ -813,6 +813,74 @@ class PddCollectParserTest(unittest.TestCase):
[item.name for item in result.dimensions],
)
def test_collects_static_sizes_from_non_scrollable_submit_hint_panel(self):
device = FakeCollectDevice(self.home_xml, self.submit_hint_spec_xml)
device.opened_url = (
"https://mobile.yangkeduo.com/goods.html?goods_id=123"
)
device.panel_open = True
service = PddCollectService(
PddDeviceService(lambda _serial: device),
"USB-001",
"client-001",
sleeper=lambda _seconds: None,
)
dimension = service._collect_size_dimension(device)
self.assertIsNotNone(dimension)
self.assertEqual(dimension.name, "尺码")
self.assertEqual(
[value.text for value in dimension.values],
["M", "L"],
)
self.assertEqual(device.swipes, [])
def test_static_sizes_keep_explicit_count_validation(self):
spec_xml = self.submit_hint_spec_xml.replace(
'text="尺码" bounds=', 'text="尺码(3)" bounds=', 1
)
device = FakeCollectDevice(self.home_xml, spec_xml)
device.opened_url = (
"https://mobile.yangkeduo.com/goods.html?goods_id=123"
)
device.panel_open = True
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"], 3)
self.assertEqual(raised.exception.diagnostics["collected_count"], 2)
def test_static_sizes_require_strong_non_scrollable_panel_evidence(self):
snapshot = parse_spec_panel(self.submit_hint_spec_xml)
dimension = next(
item for item in snapshot.dimensions if item.key == "size"
)
incomplete_evidence_xml = self.submit_hint_spec_xml.replace(
'class="android.widget.EditText"',
'class="android.widget.TextView"',
1,
)
service = PddCollectService(
PddDeviceService(lambda _serial: object()),
"USB-001",
"client-001",
)
result = service._non_scrollable_second_dimension(
incomplete_evidence_xml, dimension
)
self.assertIsNone(result)
def test_isolated_submit_hint_is_not_a_spec_panel(self):
xml_data = """<hierarchy>
<node package="com.xunmeng.pinduoduo"