| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 | #!/bin/bash# This script runs a visual regression test on all the images# generated from OSMD samples (npm run generate:current and npm run generate:blessed)##   inspired by and adapted from Vexflow's visual regression tests.## Prerequisites: ImageMagick## On OSX:   $ brew install imagemagick# On Linux: $ apt-get install imagemagick## Usage:###  First generate the known good or previous state PNG images you want to compare to, e.g. the develop branch or last release:#    (Server has to be running for this: npm start)##    npm run generate:blessed##  Make changes in OSMD, then generate your new images:##    npm run generate:current##  Run the regression tests against the blessed images in visual_regression/blessed.##    npm run test:visual#    # npm will navigate to the base folder automatically##    # or: (this should be done from the main OSMD folder)#    # sh test/Util/visual_regression.sh [imageBaseFolder] [sampleShellPrefix]#    #    example: sh test/Util/visual_regression.sh ./visual_regression OSMD_function_test_#    #        will run visual regression tests for all images matching OSMD_function_test_*.png.##  Check visual_regression/diff/results.txt for results. This file is sorted#  by PHASH difference (most different files on top.) The composite diff#  images for failed tests (i.e., PHASH > 1.0) are stored in visual_regression/diff.##  (If you are satisfied with the differences, copy *.png from visual_regression/current#  into visual_regression/blessed, and submit your change (TODO))# PNG viewer on OSX. Switch this to whatever your system uses.# VIEWER=open# Show images over this PHASH threshold.# 0.01 is probably too low, but a good first pass.# 0.0001 catches for example a repetition ending not having a down line at the end (see Saltarello bar 10) (0.001 doesn't catch this)THRESHOLD=0.0001# Set up Directories#   It does not matter where this script is executed, as long as these folders are given correctly (and blessed/current have png images set up correctly)BUILDFOLDER=./visual_regressionif [ "$1" != "" ]then  BUILDFOLDER=$1fiBLESSED=$BUILDFOLDER/blessedCURRENT=$BUILDFOLDER/currentDIFF=$BUILDFOLDER/diff# diff also acts as the temp folder here, unlike in Vexflow, where it is current.# it would be nice to have a tmp folder (for temporary files), but we'd want to delete the folder entirely, and we'd better not risk using rm -rf in a script# All results are stored here.RESULTS=$DIFF/results.txtWARNINGS=$DIFF/warnings.txt# If no prefix is provided, test all images.if [ "$2" == "" ]then  files=*.pngelse  files=$2*.png  echo "image filter (shell): $files"fi## Sanity checks: some simple checks that the script can run correctly (doesn't validate pngs)folderWarningStringMsg="Exiting without running visual regression tests."totalCurrentImages=`ls -1 $CURRENT/$files | wc -l | xargs` # xargs trims spaceif [ $? -ne 0 ] || [ "$totalCurrentImages" -lt 1 ] # $? returns the exit code of the previous command (ls). (0 is success)then  echo Missing images in $CURRENT.  echo Please run \"npm run generate:current\"  exit 1fitotalBlessedImages=`ls -1 $BLESSED/$files | wc -l | xargs`if [ $? -ne 0 ] || [ "$totalBlessedImages" -lt 1 ]then  echo Missing images in $BLESSED.  echo Please run \"npm run generate:blessed\"  exit 1fi# check that #currentImages == #blessedImages (will continue anyways)if [ ! "$totalCurrentImages" -eq "$totalBlessedImages" ]then  echo "Warning: Number of current images ($totalCurrentImages) is not the same as blessed images ($totalBlessedImages). Continuing anyways.\n"else  echo "Found $totalCurrentImages current and $totalBlessedImages blessed png files (not tested if valid). Continuing.\n"fi# ----------------- end of sanity checks -----------------mkdir -p $DIFFif [ -e "$RESULTS" ]then  rm $DIFF/*fitouch $RESULTStouch $RESULTS.fails#   this shouldn't be named .fail because we have a *.fail shell match further below, which will loop endlessly if files are in the same folder (diff).touch $WARNINGS# Number of simultaneous jobsnproc=$(sysctl -n hw.physicalcpu 2> /dev/null || nproc)if [ -n "$NPROC" ]; then  nproc=$NPROCfitotal=`ls -l $BLESSED/$files | wc -l | sed 's/[[:space:]]//g'`echo "Running $total tests with threshold $THRESHOLD (nproc=$nproc)..."function ProgressBar {    let _progress=(${1}*100/${2}*100)/100    let _done=(${_progress}*4)/10    let _left=40-$_done    _fill=$(printf "%${_done}s")    _empty=$(printf "%${_left}s")    printf "\rProgress : [${_fill// /#}${_empty// /-}] ${_progress}%%"}function diff_image() {  local image=$1  local name=`basename $image .png`  local blessed=$BLESSED/$name.png  local current=$CURRENT/$name.png  local diff=$DIFF/$name.png-temp  if [ ! -e "$current" ]  then    echo " Warning: $name.png missing in $CURRENT. Skipped." >$diff.warn    #((total--))    return  fi  if [ ! -e "$blessed" ]  then    echo " Warning: $name.png doesn't exist in $BLESSED. Skipped." >$diff.warn    #((total--))    return  fi  cp $blessed $diff-a.png  cp $current $diff-b.png  # Calculate the difference metric and store the composite diff image.  local hash=`compare -metric PHASH -highlight-color '#ff000050' $diff-b.png $diff-a.png $diff-diff.png 2>&1`  local isGT=`echo "$hash > $THRESHOLD" | bc -l`  if [ "$isGT" == "1" ]  then    # Add the result to results.txt    echo $name $hash >$diff.fail    # Threshold exceeded, save the diff and the original, current    cp $diff-diff.png $DIFF/$name.png    cp $diff-a.png $DIFF/$name'_'Blessed.png    cp $diff-b.png $DIFF/$name'_'Current.png    echo    echo "Test: $name"    echo "  PHASH value exceeds threshold: $hash > $THRESHOLD"    echo "  Image diff stored in $DIFF/$name.png"    # $VIEWER "$diff-diff.png" "$diff-a.png" "$diff-b.png"    # echo 'Hit return to process next image...'    # read  else    echo $name $hash >$diff.pass  fi  rm -f $diff-a.png $diff-b.png $diff-diff.png}function wait_jobs () {  local n=$1  while [[ "$(jobs -r | wc -l)" -ge "$n" ]] ; do     # echo ===================================== && jobs -lr     # wait the oldest job.     local pid_to_wait=`jobs -rp | head -1`     # echo wait $pid_to_wait     wait $pid_to_wait  &> /dev/null  done}count=0for image in $CURRENT/$filesdo  count=$((count + 1))  ProgressBar ${count} ${total}  wait_jobs $nproc  diff_image $image &donewaitcat $DIFF/*.warn 1>$WARNINGS 2>/dev/nullrm -f $DIFF/*.warn## Check for files newly built that are not yet blessed.for image in $CURRENT/$filesdo  name=`basename $image .png`  blessed=$BLESSED/$name.png  current=$CURRENT/$name.pngdonenum_warnings=`cat $WARNINGS | wc -l`cat $DIFF/*.fail 1>$RESULTS.fails 2>/dev/nullnum_fails=`cat $RESULTS.fails | wc -l`rm -f  $DIFF/*.fail# Sort results by PHASHsort -r -n -k 2 $RESULTS.fails >$RESULTSsort -r -n -k 2 $DIFF/*.pass 1>>$RESULTS 2>/dev/nullrm -f $DIFF/*.pass $RESULTS.failsechoecho Results stored in $DIFF/results.txtecho All images with a difference over threshold, $THRESHOLD, areecho available in $DIFF, sorted by perceptual hash.echoif [ "$num_warnings" -gt 0 ]then  echo  echo "You have $num_warnings warning(s):"  cat $WARNINGSfiif [ "$num_fails" -gt 0 ]then  echo "You have $num_fails fail(s):"  head -n $num_fails $RESULTSelse  echo "Success - All diffs under threshold!"fi
 |