(data: ScreenshotDiffResult)
| 498 | } |
| 499 | |
| 500 | function formatScreenshotDiffHints(data: ScreenshotDiffResult): string[] { |
| 501 | const hints: string[] = []; |
| 502 | const clusters = data.ocr?.movementClusters ?? []; |
| 503 | for (const cluster of clusters.slice(0, 2)) { |
| 504 | hints.push( |
| 505 | `text movement cluster: ${formatQuotedList(cluster.texts)} dx=${formatRange(cluster.xRange)}px ` + |
| 506 | `dy=${formatRange(cluster.yRange)}px`, |
| 507 | ); |
| 508 | } |
| 509 | |
| 510 | const controlDeltas = (data.nonTextDeltas ?? []) |
| 511 | .filter((delta) => ['icon', 'toggle', 'chevron'].includes(delta.likelyKind)) |
| 512 | .slice(0, 3); |
| 513 | if (controlDeltas.length > 0) { |
| 514 | hints.push(`non-text controls: ${controlDeltas.map(formatNonTextHint).join('; ')}`); |
| 515 | } |
| 516 | |
| 517 | const boundaryDeltas = (data.nonTextDeltas ?? []) |
| 518 | .filter((delta) => delta.likelyKind === 'separator') |
| 519 | .slice(0, 2); |
| 520 | if (boundaryDeltas.length > 0) { |
| 521 | hints.push(`non-text boundaries: ${boundaryDeltas.map(formatNonTextHint).join('; ')}`); |
| 522 | } |
| 523 | |
| 524 | return hints.slice(0, 6); |
| 525 | } |
| 526 | |
| 527 | function formatNonTextHint(delta: { |
| 528 | likelyKind: string; |
no test coverage detected
searching dependent graphs…