Last active
July 1, 2021 21:33
-
-
Save joshzcold/d40e7ee47749851b6dda32314b5efab9 to your computer and use it in GitHub Desktop.
Run Selenium Testing and record browser along with testing log. This is geared towards TestNG and Gradle, but there is no reason you can't rip out the video section and use the testing tool of your choice.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# set -x | |
# PS4='+${LINENO}: ' | |
set -euo pipefail | |
IFS=$'\n\t' | |
method="" | |
class="" | |
package="" | |
directory="" | |
test_fail_exit=0 | |
video=false | |
keep_logs=false | |
video_output=$PWD | |
testIndicator="@Test" | |
video_extension=".mp4" | |
xvfb_display="" | |
video_cmds=$(mktemp) | |
function startVideo(){ | |
kill_count=0 | |
while [ ! -f $video_output/$1.log ];do | |
[ "$kill_count" -gt 30 ] && echo "could not get testing log within limit" && exit 1 | |
sleep 1 | |
((kill_count=kill_count+1)) | |
echo $video_output/$1.log $kill_count | |
done | |
if [ -f $video_output/$1.log ];then | |
# start recording video in background | |
echo > $video_cmds | |
set -x | |
tail -f $video_cmds | ffmpeg -f x11grab -y \ | |
-video_size 1920x1080 -hide_banner \ | |
-loglevel error -i :$xvfb_display \ | |
-codec:v libx264 -r 12 \ | |
-vf "drawtext=textfile=$video_output/$1.log \ | |
:fontcolor=white \ | |
:fontsize=18 \ | |
:box=1 \ | |
:[email protected] \ | |
:reload=1 | |
:x=w-tw-20:y=h-th-20" \ | |
$video_output/$1$video_extension | |
set +x | |
else | |
echo "no log file for ffmpeg video recording. skipping video recording" | |
fi | |
} | |
function testCommand(){ | |
# 1. Run gradle with arguments | |
# 2. Tee stdout to tty and to stdin for sed | |
# 3. replace lines >60 with a newline | |
echo "Loading..." > $video_output/$2.log | |
if $video; then | |
set -x | |
./gradlew test $gradle_options --rerun-tasks $1$2 2>&1 | | |
tee >(sed -u -e "s/.\{75\}/&\n/g" >> $video_output/$2.log) | |
set +x | |
else | |
set -x | |
./gradlew test $gradle_options --rerun-tasks $1$2 | |
set +x | |
fi | |
} | |
function testDirectory(){ | |
for f in $(find $directory -name "*.groovy") | |
do | |
package=$(head -1 $f | awk '{print $2}') | |
#xargs removes white space | |
class=$(grep -Po "(?<=class)\s\w+\s" $f | xargs) | |
execute="${package}.${class}" | |
if $video; then | |
withVideo "--tests=" "$execute" | |
else | |
testCommand "--tests=" "$execute" | |
fi | |
done | |
} | |
function withVideo(){ | |
local tmp=$(mktemp) | |
# Ctrl + C kill background jobs | |
trap 'pkill -P $$' TERM INT HUP | |
# -displayfd finds unused display and send it to file descriptor 1 | |
Xvfb -displayfd 1 -screen 0 1920x1080x16 1>$tmp 2>/dev/null & | |
# wait until Xvfb finds a display with output in tmp file | |
# 5 seconds to find a display so we dont infini-loop | |
kill_count=0 | |
while ! grep -qP "\d" $tmp;do | |
[ "$kill_count" -gt 30 ] && echo "Xvfb couldn't get a display within limit" && exit 1 | |
sleep 1 | |
((kill_count=kill_count+1)) | |
echo xvfb: $tmp $kill_count | |
done | |
xvfb_display=$(cat $tmp) | |
mkdir -p $video_output | |
startVideo $2 & | |
# send the "headed" browser to DISPLAY which is headless | |
DISPLAY=":$xvfb_display" testCommand $1 $2 & | |
test_pid=$! | |
# wait and output exit of background process | |
if wait $test_pid; then | |
echo q >> $video_cmds # send ffmpeg exit | |
sleep 2 | |
if ! $keep_logs;then | |
rm -f $video_output/$2.log | |
fi | |
echo | |
echo "Tests succeed, delete video -> $video_output/$2$video_extension" | |
rm -f $video_output/$2$video_extension | |
exit 0 | |
else | |
echo | |
echo "1 or more test failed, keeping -> $video_output/$2$video_extension" | |
echo q >> $video_cmds # send ffmpeg exit | |
sleep 2 | |
if ! $keep_logs;then | |
rm -f $video_output/$2.log | |
fi | |
# kill everything else | |
exit $test_fail_exit | |
fi | |
} | |
function testSuite(){ | |
if $video; then | |
withVideo "-Dsuite=" "$suite" | |
else | |
testCommand "-Dsuite=" "$suite" | |
fi | |
} | |
function testPackage(){ | |
if $video; then | |
withVideo "--tests=" "$package" | |
else | |
testCommand "--tests=" "$package" | |
fi | |
} | |
function testClass() { | |
echo Testing all @Test in class | |
file="$(grep -r -w "class ${class}" | cut -d ":" -f 1 || true)" | |
# Empty Check | |
if [[ -z "$file" ]]; then | |
echo "Error: Couldn't find an exact match" | |
exit 1 | |
fi | |
if [[ $(echo "${file}" | wc -l) -gt 1 ]]; then | |
echo Error: Found more than one file that has that class. exiting | |
exit 1 | |
else | |
package=$(head -1 ${file} | awk '{print $2}') | |
execute="${package}.${class}" | |
echo going to try and run class: ${execute} | |
if $video; then | |
withVideo "--tests=" "$execute" | |
else | |
testCommand "--tests=" "$execute" | |
fi | |
fi | |
} | |
function testMethod() { | |
echo Testing a @Test method within a class | |
file="$(grep -r "${testIndicator}" -A1 | grep -w "${method}" | grep -v "${testIndicator}" | tr -s ' ' | cut -d ' ' -f 1 | awk '{print substr($1, 1, length($1)-1)}' || true)" | |
# Empty Check | |
if [[ -z "$file" ]]; then | |
echo "Error: Couldn't find an exact match" | |
exit 1 | |
fi | |
if [[ $(echo "${file}" | wc -l) -gt 1 ]]; then | |
echo Error: Found more than one file that has that method. exiting | |
exit 1 | |
else | |
class=$(grep "class" ${file} | awk '{print $2}' ) | |
if [[ $(echo "$class" | wc -l) -gt 1 ]]; then | |
echo Error: Found more than one class in file. This script can only work with one class | |
exit 1 | |
else | |
package=$(head -1 ${file} | awk '{print $2}') | |
execute="${package}.${class}.${method}" | |
echo going to try and run method: ${execute} | |
if $video; then | |
withVideo "--tests=" "$execute" | |
else | |
testCommand "--tests=" "$execute" | |
fi | |
fi | |
fi | |
} | |
#=== FUNCTION ================================================================ | |
# NAME: usage | |
# DESCRIPTION: Display usage information. | |
#=============================================================================== | |
function usage () | |
{ | |
echo " | |
===================================================== | |
Wrapper script for easier commandline test operations | |
Finds test classes or methods and resolves the package | |
to pass into build tools like maven or gradle | |
===================================================== | |
Usage : $0 [options] [gradle arguments] | |
Options: | |
-h Display this message | |
-d Run all tests recursivley found in directory | |
-m Search for and run Method Test | |
-l Keep logs from tests | |
-p Put in full package declaration | |
-s Run suite, must be function in build file (build.gradle) | |
-x Exit code on test failure | |
-v Record video (executes test in background) | |
-o Video output directory (will be created) | |
-c Search for and run tests inside of Class | |
Examples: | |
./test.sh -p com.microfocus.sspr.tests.smokeTests.canModule.CanLookup | |
./test.sh -c CanLookup -DinternalSysProp=something | |
./test.sh -m methodInCanLookup | |
# exit with exit code 1 on failure | |
./test.sh -x 1 | |
# Record video to this directory | |
./test.sh -m -v -o /home/me/videos methodInCanLookup" | |
} # ---------- end of function usage ---------- | |
#----------------------------------------------------------------------- | |
# Handle command line arguments | |
#----------------------------------------------------------------------- | |
while getopts "hlvd:s:x:m:c:p:o:" opt; | |
do | |
case $opt in | |
h) | |
usage; exit 0 ;; | |
v) | |
video=true;; | |
l) | |
keep_logs=true;; | |
o) | |
video_output=$OPTARG;; | |
x) | |
test_fail_exit=$OPTARG;; | |
m) | |
method=$OPTARG | |
shift $(($OPTIND - 1)) | |
gradle_options="$@" | |
testMethod; exit 0 ;; | |
c) | |
class=$OPTARG | |
shift $(($OPTIND - 1)) | |
gradle_options="$@" | |
testClass; exit 0 ;; | |
p) | |
package=$OPTARG | |
shift $(($OPTIND - 1)) | |
gradle_options="$@" | |
testPackage; exit 0 ;; | |
s) | |
suite=$OPTARG | |
shift $(($OPTIND - 1)) | |
gradle_options="$@" | |
testSuite; exit 0 ;; | |
d) | |
directory=$OPTARG | |
shift $(($OPTIND - 1)) | |
gradle_options="$@" | |
testDirectory; exit 0 ;; | |
*) echo -e "\n Option does not exist : OPTARG\n" | |
usage; exit 1 ;; | |
esac # --- end of case --- | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Result should look alot like this
