diff --git a/scripts/ci/desktop-linux/claude-test.md b/scripts/ci/desktop-linux/claude-test.md index 2bc77de2a1..aeba41766b 100644 --- a/scripts/ci/desktop-linux/claude-test.md +++ b/scripts/ci/desktop-linux/claude-test.md @@ -22,7 +22,7 @@ Run all of A and B in the default layout, with the toolbar at the bottom. Then m 4. Use "Show more" until both #ci_group and #ci_channel are listed, and note how many pages that took. 5. Check, noting the evidence (screenshot names, positions): - each result's row shows its name, its description, its count ("2 members" or "1 subscriber") and "Join group" (#ci_group) or "Join channel" (#ci_channel); - - the count's text is smaller than the description's above it; + - the count's text is smaller than the description's above it: compare `ui ink "1 subscriber"` with `ui ink "CI seeded channel"`, and look at the screenshot; - each shows its avatar, filling the picture: run `ui avatar "#ci_group" red` and `ui avatar "#ci_channel" green`, and look at the screenshot; - **(both layouts)** the "Directory" header is above its results; - **(both layouts)** no "Show more" is left, and nothing is cut off, overlapping or garbled. diff --git a/scripts/ci/desktop-linux/screen-ink.py b/scripts/ci/desktop-linux/screen-ink.py new file mode 100755 index 0000000000..427f4c6875 --- /dev/null +++ b/scripts/ci/desktop-linux/screen-ink.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 + +# Prints the height in pixels of the ink in a box of a screenshot: from the first to the last row with a pixel darker than +# halfway between the box's lightest and darkest. OCR's boxes are padded, so they hardly tell text sizes apart. +# +# screen-ink.py +# +# is the screenshot in 8-bit grayscale; the box is in its pixels, edges included. + +import re +import sys + + +def main(): + path, left, top, right, bottom = sys.argv[1], *map(int, sys.argv[2:6]) + with open(path, "rb") as f: + data = f.read() + header = re.match(rb"P5\s+(\d+)\s+(\d+)\s+(\d+)\s", data) + width, height, pixels = int(header[1]), int(header[2]), data[header.end():] + columns = range(max(left, 0), min(right, width - 1) + 1) + rows = [[pixels[y * width + x] for x in columns] for y in range(max(top, 0), min(bottom, height - 1) + 1)] + threshold = (max(map(max, rows)) + min(map(min, rows))) / 2 + ink = [i for i, row in enumerate(rows) if min(row) < threshold] + print(ink[-1] - ink[0] + 1 if ink else 0) + + +main() diff --git a/scripts/ci/desktop-linux/smoke-test.sh b/scripts/ci/desktop-linux/smoke-test.sh index 1486aee818..09b7364af6 100755 --- a/scripts/ci/desktop-linux/smoke-test.sh +++ b/scripts/ci/desktop-linux/smoke-test.sh @@ -121,12 +121,6 @@ y_of() { cut -d ' ' -f 2 <<< "$pos" } -height_of() { - local x y l t r b - read -r x y l t r b < <("$ui" find "$1") || return 1 - echo $((b - t)) -} - above() { local a b a=$(y_of "$1") || return 1 @@ -175,9 +169,9 @@ scroll_to() { # the count's text is smaller than the description's above it: both have capitals and ascenders, no descenders count_text_smaller() { local count description - count=$(height_of "1 subscriber") || return 1 - description=$(height_of "CI seeded channel") || return 1 - echo "NOTE text heights: \"1 subscriber\" $count px, \"CI seeded channel\" $description px" | tee -a "$checks" + count=$("$ui" ink "1 subscriber") || return 1 + description=$("$ui" ink "CI seeded channel") || return 1 + echo "NOTE ink heights: \"1 subscriber\" $count px, \"CI seeded channel\" $description px" | tee -a "$checks" [ "$count" -lt "$description" ] } diff --git a/scripts/ci/desktop-linux/ui b/scripts/ci/desktop-linux/ui index a96515f988..83c6f74bc0 100755 --- a/scripts/ci/desktop-linux/ui +++ b/scripts/ci/desktop-linux/ui @@ -11,6 +11,7 @@ # ui shot save UI_OUT/NN-.png and NN-.txt (OCR's input and output in UI_OUT/ocr), and print the text on screen # ui text print the text on screen, one phrase per line after its centre x,y # ui find print "x y left top right bottom", the text's centre and box; fail if it is not on screen +# ui ink print the height in pixels of the text's ink, to compare text sizes # ui wait [secs] wait up to secs (30) until the text is on screen # ui click click at x,y # ui click-text [secs] wait up to secs (20) for the text and click its centre @@ -209,6 +210,17 @@ case "${1:-}" in log "find \"$2\": $pos" > /dev/null echo "$pos" ;; + ink) + if ! pos=$(screen_ocr find "$2"); then + log "ink \"$2\": not on screen" >&2 + exit 1 + fi + read -r _ _ l t r b <<< "$pos" + # 2 px around OCR's box, less than the gap between lines + h=$(python3 "$here/screen-ink.py" "$state/ocr/gray.pgm" "$l" $((t - 2)) "$r" $((b + 2))) + log "ink \"$2\": $h px" > /dev/null + echo "$h" + ;; wait) secs=${3:-30} if ! pos=$(wait_for "$2" "$secs"); then