fix: 兼容非滚动面板静态尺码采集 (#177)
This commit is contained in:
@@ -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]:
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user