A lesson site for the lab (session cookie, one-time addresses, a second origin, a request log) and real right-clicks on its words and on a JPEG, a PNG, a transparent PNG, a one-time picture, another site's, a blob:, a WebP, a canvas, a linked picture, a broken one, and Cancel. Each is judged on the job CUPS kept — where and how large, no other ink — and on the site log: nothing was fetched again. The clipboard is the teacher's afterwards. Black and white: a colourful lesson turned back and forth five times on page 2, a worksheet, a picture at 50% top left, a page full of pictures, back to Color, and Cancel. Every grey preview is grey pixel for pixel and the job is byte-for-byte the file shown, through pxlmono. The three 0.2.6.2 black-and-white scenarios now wait for the grey file before Print, as a teacher has to. 343 checks, none failing. Co-Authored-By: Claude Opus 5.5 <[email protected]>
386 lines
20 KiB
Bash
Executable File
386 lines
20 KiB
Bash
Executable File
#!/bin/bash
|
|
# Does Wonder Ink print — and does a job really reach CUPS?
|
|
#
|
|
# The lab's CUPS gets an "Elmer" built from Elmer's own PPD and options,
|
|
# writing to a file instead of socket://10.10.0.155:9100, so every job
|
|
# goes through the same filters the real printer's jobs do and none can
|
|
# reach a printer. A second queue refuses jobs, to show a teacher is told.
|
|
#
|
|
# Each scenario runs the INSTALLED classroom-wonderink under a real
|
|
# QtWebEngine (offscreen), presses the preview's buttons, and is then
|
|
# judged by CUPS's own record of what it was given.
|
|
#
|
|
# tools/lab/wonderink-print-check [SCENARIO...]
|
|
set -uo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
NAME="${LAB_NAME:-classroom-v2-lab}"
|
|
COMMAND="${WONDERINK:-/usr/local/bin/classroom-wonderink}"
|
|
|
|
lab() { docker exec -i "$NAME" bash -c "$1"; }
|
|
|
|
# Not /tmp: in the Plasma lab /tmp is a tmpfs, and docker cp writes into
|
|
# the layer underneath it, where nothing can see the file. Measured — the
|
|
# first run there "failed" every scenario for exactly that reason.
|
|
RIG=/opt/wonderink-check/wonderink-print-rig.py
|
|
lab 'mkdir -p /opt/wonderink-check'
|
|
docker cp "$ROOT/tools/lab/wonderink-print-rig.py" "$NAME:$RIG" >/dev/null
|
|
MEASURE=/opt/wonderink-check/wonderink-picture-measure.py
|
|
docker cp "$ROOT/tools/lab/wonderink-picture-measure.py" "$NAME:$MEASURE" >/dev/null
|
|
SITE=/opt/wonderink-check/wonderink-lesson-site.py
|
|
SITE_LOG=/opt/wonderink-check/site.log
|
|
docker cp "$ROOT/tools/lab/wonderink-lesson-site.py" "$NAME:$SITE" >/dev/null
|
|
lab "chmod -R a+rX /opt/wonderink-check && test -r $RIG" || {
|
|
echo "could not put the rig in the lab" >&2
|
|
exit 1
|
|
}
|
|
|
|
# The church's printer network is fenced off inside the lab. Checked, not
|
|
# assumed: a lab job must never be able to reach the real Elmer.
|
|
lab 'ip route replace blackhole 10.10.0.0/16 2>/dev/null
|
|
! timeout 3 bash -c "exec 3<>/dev/tcp/10.10.0.155/9100" 2>/dev/null' || {
|
|
echo "REFUSING TO CONTINUE: the real Elmer is reachable from the lab" >&2
|
|
exit 1
|
|
}
|
|
|
|
lab '
|
|
set -e
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
command -v lpadmin >/dev/null && command -v pdftoppm >/dev/null || \
|
|
apt-get install -y -qq cups cups-client poppler-utils >/dev/null 2>&1
|
|
dpkg -s foomatic-db-compressed-ppds >/dev/null 2>&1 || \
|
|
apt-get install -y -qq foomatic-db-compressed-ppds cups-filters ghostscript >/dev/null 2>&1
|
|
grep -q "^FileDevice Yes" /etc/cups/cups-files.conf || echo "FileDevice Yes" >> /etc/cups/cups-files.conf
|
|
pkill -x cupsd || true; sleep 1; /usr/sbin/cupsd; sleep 1
|
|
cupsctl --debug-logging
|
|
: > /var/log/cups/error_log
|
|
mkdir -p /var/lab-print && chown lp /var/lab-print
|
|
driver="foomatic-db-compressed-ppds:0/ppd/foomatic-ppd/Generic-PCL_6_PCL_XL_Printer-pxlcolor.ppd"
|
|
for q in $(lpstat -e 2>/dev/null); do lpadmin -x "$q"; done
|
|
lpadmin -p Elmer -E -v file:///var/lab-print/elmer.pxl -m "$driver" \
|
|
-D "LAB STAND-IN for Elmer: its PPD, a file for a printer" \
|
|
-o PrintoutMode=Normal -o ColorModel=Color 2>/dev/null
|
|
lpadmin -d Elmer
|
|
lpadmin -p Refusing -E -v file:///dev/null -m "$driver" -D "LAB: refuses jobs" 2>/dev/null
|
|
cupsreject Refusing
|
|
id teacher >/dev/null 2>&1 || useradd -m teacher
|
|
install -d -o teacher -m 700 /tmp/teacher-rt
|
|
# An inline PDF, served the way a site shows one rather than sends it. Its
|
|
# own port and directory: a lab often has another test server on 8088.
|
|
mkdir -p /opt/wonderink-check/www
|
|
# CUPS keeps what it was given, so a check can compare the submitted
|
|
# file with the one the preview showed, byte for byte.
|
|
cupsctl PreserveJobFiles=Yes
|
|
' || { echo "could not prepare the lab's CUPS" >&2; exit 1; }
|
|
|
|
lab "test -f /opt/wonderink-check/www/ark-wide.webp || \
|
|
QT_QPA_PLATFORM=offscreen QTWEBENGINE_CHROMIUM_FLAGS='--no-sandbox --disable-gpu' \
|
|
python3 $MEASURE make /opt/wonderink-check/www; \
|
|
chmod -R a+r /opt/wonderink-check/www; test -f /opt/wonderink-check/www/ark-wide.webp" || {
|
|
echo "could not make the test pictures" >&2
|
|
exit 1
|
|
}
|
|
|
|
# Started detached. A background process started inside a docker exec
|
|
# dies with it in the Plasma lab, whose PID 1 is systemd.
|
|
lab 'pgrep -f "[h]ttp.server 8089" >/dev/null' || \
|
|
docker exec -d -w /opt/wonderink-check/www "$NAME" python3 -m http.server 8089
|
|
|
|
# The signed-in lesson with pictures in it, restarted each run so that its
|
|
# one-time addresses start unused.
|
|
lab "pkill -f '[w]onderink-lesson-site.py' ; : > $SITE_LOG; chmod a+rw $SITE_LOG"
|
|
docker exec -d "$NAME" python3 "$SITE" /opt/wonderink-check/www 8094 8095 "$SITE_LOG"
|
|
lab 'for _ in $(seq 20); do curl -s -o /dev/null http://127.0.0.1:8094/login && exit 0; sleep 0.3; done; exit 1' || {
|
|
echo "the lesson site did not start" >&2
|
|
exit 1
|
|
}
|
|
|
|
passed=0
|
|
failed=0
|
|
|
|
judge() {
|
|
if eval "$2"; then
|
|
printf ' \033[32mPASS\033[0m %s\n' "$1"
|
|
passed=$((passed + 1))
|
|
else
|
|
printf ' \033[31mFAIL\033[0m %s\n' "$1"
|
|
failed=$((failed + 1))
|
|
fi
|
|
}
|
|
|
|
# Runs one scenario; leaves its output in $out and the jobs it caused in $jobs.
|
|
run() {
|
|
local before
|
|
before=$(lab 'lpstat -W all -o 2>/dev/null | wc -l')
|
|
out=$(lab "su teacher -c 'cd /tmp; XDG_RUNTIME_DIR=/tmp/teacher-rt QT_QPA_PLATFORM=offscreen \
|
|
QTWEBENGINE_CHROMIUM_FLAGS=\"--no-sandbox --disable-gpu\" \
|
|
timeout 120 python3 $RIG $COMMAND $1 2>&1'; echo \"exit=\$?\"")
|
|
sleep 3
|
|
jobs=$(lab "lpstat -W all -o | tail -n +$((before + 1)) | awk '{print \$1}' | tr '\n' ' '")
|
|
job_options() { lab "grep -E '\\[Job ${1#*-}\\] argv\\[(4|5)\\]' /var/log/cups/error_log"; }
|
|
job_device() { lab "grep -E '\\[Job ${1#*-}\\]' /var/log/cups/error_log | grep -oE 'sDEVICE=[a-z]+' | sort -u"; }
|
|
}
|
|
|
|
count() { wc -w <<< "$jobs"; }
|
|
# The file CUPS was handed for a job, kept by PreserveJobFiles.
|
|
spool_file() { local id="${1%% *}"; printf '/var/spool/cups/d%05d-001' "${id##*-}"; }
|
|
said() { grep -q -- "$1" <<< "$out"; }
|
|
# Every line of the rig's output that starts with WORD.
|
|
lines() { grep -o -- "$1.*" <<< "$out"; }
|
|
# Is every page of a PDF in the lab grey? {"pages", "spreads", "gray"}
|
|
colour_of() { lab "python3 $MEASURE colour $1"; }
|
|
is_gray() { python3 -c 'import json,sys; sys.exit(0 if json.loads(sys.argv[1])["gray"] else 1)' "$1"; }
|
|
# What the lesson site was asked for after the right-click.
|
|
fetched_since() {
|
|
local since
|
|
since=$(grep -o 'since=[0-9.]*' <<< "$out" | head -1 | cut -d= -f2)
|
|
lab "python3 -c 'import json,sys; print(sum(1 for l in open(\"$SITE_LOG\") if json.loads(l)[\"t\"] > float(sys.argv[1])))' ${since:-0}"
|
|
}
|
|
teacher_text_kept() { said "CLIPBOARD \"TEACHER'S TEXT, John 3:16\""; }
|
|
# picture layout, measured on the page CUPS kept: judges its own lines.
|
|
judge_layout() { # FILE_DIMS SIZE POSITION PAPER FILL COLOUR
|
|
local dims=$1 size=$2 position=$3 paper=$4 fill=$5 color=$6 spool result
|
|
spool=$(spool_file "$jobs")
|
|
judge "CUPS was given exactly the page the preview showed" \
|
|
"[[ -n '$spool' ]] && lab 'cmp -s /tmp/rig-out/preview.pdf $spool'"
|
|
result=$(lab "python3 $MEASURE measure $spool $dims $size $position $paper $fill")
|
|
field() { python3 -c "import json,sys; print(json.loads(sys.argv[1])[sys.argv[2]])" "$result" "$1"; }
|
|
judge "the paper is turned the way asked ($paper): $(field page)" \
|
|
'[[ "$(field page_landscape)" == "$(field wanted_landscape)" ]]'
|
|
judge "the picture is where and as large as asked, within 3 points (off by $(field off_by_points))" \
|
|
'[[ "$(field off_by_points)" != None ]] && (( $(field off_by_points) <= 3 ))'
|
|
judge "no ink anywhere else on the page — no bars ($(field ink_outside_picture) pixels)" \
|
|
'[[ "$(field ink_outside_picture)" == 0 ]]'
|
|
if [[ "$fill" == fill ]]; then
|
|
# The mark is in the picture's left fifth, which filling a
|
|
# portrait page with a wide picture cuts off. That is what the
|
|
# control says it does; the fit scenarios prove it happens only
|
|
# when asked.
|
|
judge "Fill cut the edges off, as it says it will" '(( $(field pink_pixels) == 0 ))'
|
|
elif [[ "$color" == gray ]]; then
|
|
judge "the corner mark is on the paper, in grey — nothing cut off" '[[ "$(field mark_inked)" == True ]]'
|
|
judge "and the page is grey, as the preview showed (colour spread $(field colour_spread))" \
|
|
'(( $(field colour_spread) == 0 ))'
|
|
judge "and it went in black and white, by the driver's own option" \
|
|
'[[ "$(job_options $jobs)" == *ColorModel=Grayscale* && "$(job_device $jobs)" == *pxlmono* ]]'
|
|
else
|
|
judge "the pink corner mark is on the paper — nothing cut off" '(( $(field pink_pixels) > 0 ))'
|
|
fi
|
|
}
|
|
exited_cleanly() { said 'exit=0' && ! said 'Traceback' && ! said 'Segmentation' && ! said 'Aborted'; }
|
|
|
|
# Where a picture goes, measured on the page CUPS was given:
|
|
# picture:FILE:SIZE:POSITION:PAPER:FILL[:gray]
|
|
PICTURES=(
|
|
picture:ark-wide.png:100:centre:auto:fit
|
|
picture:ark-wide.png:100:centre:portrait:fit
|
|
picture:ark-wide.png:50:top-left:auto:fit
|
|
picture:ark-tall.png:100:centre:auto:fit
|
|
picture:ark-tall.png:33:bottom-right:portrait:fit
|
|
picture:ark-wide.png:100:centre:portrait:fill
|
|
picture:ark-wide.jpg:75:right:auto:fit:gray
|
|
picture:ark-clear.png:50:top:auto:fit
|
|
picture:ark-wide.png:50:top-left:auto:fit:gray
|
|
)
|
|
|
|
# Black and white shown as it prints, and Color again (0.2.6.3).
|
|
COLOURS=(bw-web bw-pdf bw-colour-again bw-cancel)
|
|
|
|
# Right-click in a signed-in lesson (0.2.6.3):
|
|
# rclick-image:ELEMENT:SIZE:POSITION[:gray], the elements in
|
|
# wonderink-lesson-site.py.
|
|
RIGHT_CLICKS=(
|
|
rclick-page
|
|
rclick-page-gray
|
|
rclick-image:private-jpg:50:top-left
|
|
rclick-image:private-png:100:centre
|
|
rclick-image:clear:50:top-left
|
|
rclick-image:once:100:centre
|
|
rclick-image:cross:75:right
|
|
rclick-image:blob:100:centre
|
|
rclick-image:webp:100:centre
|
|
rclick-image:canvas:100:centre
|
|
rclick-image:linked:33:bottom-right
|
|
rclick-image:private-jpg:50:top-left:gray
|
|
rclick-broken
|
|
rclick-cancel
|
|
)
|
|
|
|
scenarios=("$@")
|
|
[[ ${#scenarios[@]} -gt 0 ]] || scenarios=(web pdf pdf-options pdf-viewer-button inline
|
|
options bad-range broken cancel page-closes-itself close-window page-prints-again repeat
|
|
dark-page "${PICTURES[@]}" "${COLOURS[@]}" "${RIGHT_CLICKS[@]}")
|
|
|
|
# The inline scenario needs a PDF to serve; the worksheet scenario writes one.
|
|
lab 'test -f /opt/wonderink-check/www/ark.pdf' || { run pdf >/dev/null; lab 'cp "/home/teacher/Downloads/Wonder Ink/Colour the Ark.pdf" /opt/wonderink-check/www/ark.pdf; chmod a+r /opt/wonderink-check/www/ark.pdf'; }
|
|
|
|
for scenario in "${scenarios[@]}"; do
|
|
echo "$scenario"
|
|
run "$scenario"
|
|
|
|
judge "Wonder Ink did not crash, and exited by itself" exited_cleanly
|
|
|
|
# The preview has to SHOW the page, not merely count it. A preview
|
|
# that printed the right thing while showing a blank was what the
|
|
# first version of this check let through.
|
|
if said 'PREVIEW '; then
|
|
judge "the preview drew the page it will print" "! grep 'PREVIEW ' <<< \"\$out\" | grep -q 'shown=False'"
|
|
fi
|
|
|
|
case "$scenario" in
|
|
web)
|
|
judge "the preview showed the lesson, 3 Letter pages, Elmer chosen" \
|
|
"said \"pages=3 printers=\\['Elmer', 'Refusing'\\] paper=Letter\""
|
|
judge "one job reached CUPS" '[[ $(count) -eq 1 ]]'
|
|
judge "Elmer's filters printed it in colour" '[[ "$(job_device $jobs)" == *pxlcolor* ]]'
|
|
judge "and nothing was left behind" "said 'scratch_left=\\[\\]'" ;;
|
|
pdf|pdf-viewer-button)
|
|
judge "the preview showed the worksheet's own 2 pages" "said 'pages=2'"
|
|
judge "one job reached CUPS" '[[ $(count) -eq 1 ]]' ;;
|
|
pdf-options)
|
|
judge "one job" '[[ $(count) -eq 1 ]]'
|
|
judge "page 2 only, three copies" \
|
|
'[[ "$(job_options $jobs)" == *"argv[4]=\"3\""* && "$(job_options $jobs)" == *page-ranges=2* ]]'
|
|
judge "in black and white, by the driver's own option" \
|
|
'[[ "$(job_options $jobs)" == *ColorModel=Grayscale* && "$(job_device $jobs)" == *pxlmono* ]]' ;;
|
|
inline)
|
|
judge "the inline PDF was recognised" "said \"mime='application/pdf'\""
|
|
judge "and opened as a worksheet tab" "said 'current_is_pdf=True'"
|
|
judge "one job reached CUPS" '[[ $(count) -eq 1 ]]' ;;
|
|
options)
|
|
judge "pages 2-3, two copies, black and white" \
|
|
'[[ "$(job_options $jobs)" == *page-ranges=2-3* && "$(job_options $jobs)" == *"argv[4]=\"2\""* && "$(job_device $jobs)" == *pxlmono* ]]' ;;
|
|
bad-range)
|
|
judge "a page that does not exist is explained, not printed" "said 'This document has 3 pages'"
|
|
judge "and once corrected, one job" '[[ $(count) -eq 1 ]]' ;;
|
|
broken)
|
|
judge "a refusing printer is reported in CUPS's words" "said 'Refusing did not take the job'"
|
|
judge "and no job is claimed" '[[ $(count) -eq 0 ]] && ! said "NOTIFY Sent"' ;;
|
|
cancel)
|
|
judge "Cancel sends nothing" '[[ $(count) -eq 0 ]]' ;;
|
|
page-closes-itself)
|
|
judge "the preview says the page closed, and cannot print" \
|
|
"said \"status='The page was closed.' print_enabled=False\""
|
|
judge "and sends nothing" '[[ $(count) -eq 0 ]]' ;;
|
|
close-window)
|
|
judge "closing Wonder Ink with the preview open sends nothing" '[[ $(count) -eq 0 ]]' ;;
|
|
page-prints-again)
|
|
judge "a second print request does not open a second preview" "said 'still one preview=True'"
|
|
judge "one job" '[[ $(count) -eq 1 ]]' ;;
|
|
repeat)
|
|
judge "five prints in a row, five jobs" '[[ $(count) -eq 5 ]]' ;;
|
|
dark-page)
|
|
judge "one job" '[[ $(count) -eq 1 ]]'
|
|
spool=$(spool_file "$jobs")
|
|
answer=$(lab "python3 $MEASURE darkness $spool")
|
|
dark=$(python3 -c 'import json,sys; print(json.loads(sys.argv[1])["dark_fraction"])' "$answer")
|
|
ink=$(python3 -c 'import json,sys; print(json.loads(sys.argv[1])["ink_fraction"])' "$answer")
|
|
judge "a black page background does not print (dark: $dark of the page)" \
|
|
"python3 -c 'import sys; sys.exit(0 if $dark < 0.05 else 1)'"
|
|
judge "and its white text still does, darkened ($ink of the page)" \
|
|
"python3 -c 'import sys; sys.exit(0 if $ink > 0.005 else 1)'" ;;
|
|
picture:*)
|
|
IFS=: read -r _ file size position paper fill color <<< "$scenario"
|
|
judge "the picture controls appeared, and none for a page" "said 'PICTURE picture_box=True'"
|
|
judge "the print interface says Color" "said \"labels='Color','Color'\""
|
|
if [[ "$color" == gray ]]; then
|
|
judge "the preview shows it in black and white" "said 'shown_gray=True'"
|
|
fi
|
|
judge "one job reached CUPS" '[[ $(count) -eq 1 ]]'
|
|
dims=$(lab "python3 -c 'from PyQt6.QtGui import QImage; i=QImage(\"/opt/wonderink-check/www/$file\"); print(f\"{i.width()}x{i.height()}\")'" 2>/dev/null)
|
|
judge_layout "$dims" "$size" "$position" "$paper" "$fill" "$color" ;;
|
|
bw-*)
|
|
judge "the preview starts in colour" "said 'COLOUR FIRST shown_gray=False'"
|
|
if [[ "$scenario" != bw-colour-again ]]; then
|
|
judge "Black and white shows a grey page, every time it is chosen" \
|
|
'! lines "want=gray" | grep -qv "shown_gray=True" && lines "want=gray" | grep -q .'
|
|
fi
|
|
if lines "want=colour" | grep -q .; then
|
|
judge "Color shows the colour page again, every time" '! lines "want=colour" | grep -qv "shown_gray=False"'
|
|
fi
|
|
case "$scenario" in
|
|
bw-web)
|
|
judge "turned over and over, it stays on page 2 of 3" '! lines TOGGLE | grep -qv "page=2/3"'
|
|
judge "black and white is made once, and the same file shown each time" \
|
|
'[[ $(lines "want=gray" | grep -o "pdf=[^ ]*" | sort -u | wc -l) -eq 1 ]]'
|
|
judge "and shown again at once (after the first: $(lines 'want=gray' | tail -n +2 | grep -o 'took=[0-9.]*' | tr '\n' ' '))" \
|
|
'! lines "want=gray" | tail -n +2 | grep -o "took=[0-9.]*" | cut -d= -f2 | grep -qv "^0\.[0-4]"'
|
|
judge "one job" '[[ $(count) -eq 1 ]]'
|
|
judge "page 2 only, two copies" \
|
|
'[[ "$(job_options $jobs)" == *page-ranges=2* && "$(job_options $jobs)" == *"argv[4]=\"2\""* ]]'
|
|
judge "in black and white, by the driver's own option" \
|
|
'[[ "$(job_options $jobs)" == *ColorModel=Grayscale* && "$(job_device $jobs)" == *pxlmono* ]]' ;;
|
|
bw-pdf)
|
|
judge "one job" '[[ $(count) -eq 1 ]]'
|
|
judge "in black and white, by the driver's own option" \
|
|
'[[ "$(job_options $jobs)" == *ColorModel=Grayscale* && "$(job_device $jobs)" == *pxlmono* ]]' ;;
|
|
bw-colour-again)
|
|
judge "one job" '[[ $(count) -eq 1 ]]'
|
|
judge "in colour, with no grey option" \
|
|
'[[ "$(job_options $jobs)" != *ColorModel=Grayscale* && "$(job_device $jobs)" == *pxlcolor* ]]' ;;
|
|
bw-cancel)
|
|
judge "Cancel sends nothing" '[[ $(count) -eq 0 ]]'
|
|
judge "and nothing was left behind" "said 'scratch_left=\[\]'" ;;
|
|
esac
|
|
if [[ $(count) -eq 1 ]]; then
|
|
spool=$(spool_file "$jobs")
|
|
judge "CUPS was given exactly the file the preview showed" "lab 'cmp -s /tmp/rig-out/preview.pdf $spool'"
|
|
answer=$(colour_of "$spool")
|
|
if [[ "$scenario" == bw-colour-again ]]; then
|
|
judge "and it is in colour ($answer)" '! is_gray "$answer"'
|
|
else
|
|
judge "and every page of it is grey ($answer)" 'is_gray "$answer"'
|
|
fi
|
|
fi ;;
|
|
rclick-page)
|
|
judge "right-click on the words offers Print page, and not Print image" \
|
|
"said \"MENU .*'Print page…'\" && ! said \"'Print image…'\""
|
|
judge "which prints the lesson page, not a picture" "said 'PREVIEW picture=False'"
|
|
judge "one job" '[[ $(count) -eq 1 ]]'
|
|
judge "CUPS was given exactly the page the preview showed" \
|
|
"lab 'cmp -s /tmp/rig-out/preview.pdf $(spool_file "$jobs")'"
|
|
judge "the teacher's clipboard is untouched" teacher_text_kept ;;
|
|
rclick-page-gray)
|
|
judge "a lesson page full of pictures turns grey in the preview ($(lines 'GRAY PAGE' | grep -o 'took=[0-9.]*'))" \
|
|
"said 'GRAY PAGE .*shown_gray=True'"
|
|
judge "one job" '[[ $(count) -eq 1 ]]'
|
|
spool=$(spool_file "$jobs")
|
|
judge "CUPS was given exactly the file the preview showed" "lab 'cmp -s /tmp/rig-out/preview.pdf $spool'"
|
|
answer=$(colour_of "$spool")
|
|
judge "and every page of it is grey ($answer)" 'is_gray "$answer"'
|
|
judge "in black and white, by the driver's own option" \
|
|
'[[ "$(job_options $jobs)" == *ColorModel=Grayscale* && "$(job_device $jobs)" == *pxlmono* ]]' ;;
|
|
rclick-image:*)
|
|
IFS=: read -r _ element size position color <<< "$scenario"
|
|
judge "right-click on the picture offers Print image and Print page" \
|
|
"said \"MENU .*'Print image…', 'Print page…'\""
|
|
judge "Print image opens the picture layout" "said 'PICTURE picture_box=True'"
|
|
judge "named for the lesson it came from" "said \"title='Picture from Picture lesson'\""
|
|
judge "nothing was fetched again to get it ($(fetched_since) requests)" '[[ $(fetched_since) -eq 0 ]]'
|
|
judge "the teacher's clipboard is theirs again" teacher_text_kept
|
|
if [[ "$color" == gray ]]; then
|
|
judge "the preview shows it in black and white" "said 'shown_gray=True'"
|
|
fi
|
|
judge "one job reached CUPS" '[[ $(count) -eq 1 ]]'
|
|
dims=$(grep -o 'image=[0-9]*x[0-9]*' <<< "$out" | head -1 | cut -d= -f2)
|
|
judge_layout "$dims" "$size" "$position" auto fit "$color" ;;
|
|
rclick-broken)
|
|
judge "a picture that never loaded is still offered as a picture" "said \"MENU .*'Print image…'\""
|
|
judge "and the teacher is told it could not be taken, with Print off" \
|
|
"said \"BROKEN status='This picture could not be taken from the page\" && said 'print_enabled=False pages=0 picture=False'"
|
|
judge "the whole page is not printed instead" '[[ $(count) -eq 0 ]]'
|
|
judge "the teacher's clipboard is untouched" teacher_text_kept ;;
|
|
rclick-cancel)
|
|
judge "the picture preview came up" "said 'PREVIEW picture=True'"
|
|
judge "Cancel sends nothing" '[[ $(count) -eq 0 ]]'
|
|
judge "the teacher's clipboard is theirs again" teacher_text_kept
|
|
judge "and nothing was left behind" "said 'scratch_left=\[\]'" ;;
|
|
esac
|
|
|
|
[[ "$failed" -eq 0 ]] || { echo "$out" | tail -15 | sed 's/^/ /'; }
|
|
done
|
|
|
|
echo
|
|
echo "$passed passed, $failed failed"
|
|
[[ "$failed" -eq 0 ]]
|