Skip to content

Commit fcdb42a

Browse files
wip: adding helper for e2e tests
1 parent 57f4708 commit fcdb42a

File tree

1 file changed

+252
-30
lines changed

1 file changed

+252
-30
lines changed

kash.sh

+252-30
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,28 @@ get_semver_patch() {
550550
fi
551551
}
552552

553+
# Generates the markdown anchor corresponding to the given title taking
554+
# markdown flavors into account.
555+
# Expected args:
556+
# 1. the section title
557+
# 2. the markdown flavor (github, gitlab, ...)
558+
normalize_markdown_anchor() {
559+
local SECTION_TITLE="$1"
560+
local MARKDOWN_FLAVOR="$2"
561+
562+
case "$MARKDOWN_FLAVOR" in
563+
github)
564+
echo "$SECTION_TITLE" | tr '/' '-'
565+
;;
566+
gitlab)
567+
echo "$SECTION_TITLE" | tr -d '/'
568+
;;
569+
*)
570+
echo "$SECTION_TITLE"
571+
;;
572+
esac
573+
}
574+
553575
### Git
554576
###
555577

@@ -1623,10 +1645,19 @@ build_docs () {
16231645
end_group "Building docs for $REPOSITORY ..."
16241646
}
16251647

1626-
# Build e2e tests
1648+
### e2e tests
1649+
###
1650+
1651+
# Build the e2e tests container
16271652
# Expected arguments
1628-
# 1. Root directory
1629-
# 2: true to publish result on harbor
1653+
# 1. the app root directory
1654+
# 2. the subdomain where the app is deployed
1655+
# 3: true to publish built container on a registry
1656+
# 4. the registry url, eg. "docker.io"
1657+
# 5. the username to login the registry
1658+
# 6. a file where the password is stored in cleartext
1659+
# 7. the name to give to the built container image
1660+
# 8. the tag to give to the built container image
16301661
build_e2e_tests () {
16311662
local ROOT_DIR="$1"
16321663
local SUBDOMAIN="$2"
@@ -1649,7 +1680,7 @@ build_e2e_tests () {
16491680
local FLAVOR
16501681
FLAVOR=$(get_app_flavor)
16511682

1652-
begin_group "Building $IMAGE_NAME:$IMAGE_TAG ..."
1683+
begin_group "Building $REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG ..."
16531684

16541685
docker login --username "$REGISTRY_USERNAME" --password-stdin "$REGISTRY_URL" < "$REGISTRY_PASSWORD_FILE"
16551686
# DOCKER_BUILDKIT is here to be able to use Dockerfile specific dockerginore (e2e-tests.Dockerfile.dockerignore)
@@ -1669,53 +1700,244 @@ build_e2e_tests () {
16691700

16701701
docker logout "$REGISTRY_URL"
16711702

1672-
end_group "Building $IMAGE_NAME:$IMAGE_TAG ..."
1703+
end_group "Building $REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG ..."
16731704
}
16741705

16751706
# Run e2e tests
1676-
# Specific error handling: set -uo pipefail to bypass errors
16771707
# Expected arguments
1678-
# 1. Root directory
1708+
# 1. the app root directory
16791709
# 2: the app name
1680-
# 3: the slack webhook apps
16811710
run_e2e_tests () {
16821711
local ROOT_DIR="$1"
16831712
local APP="$2"
1684-
local SLACK_WEBHOOK_APPS="$3"
1685-
1686-
## Run tests & redirect output to a log file
1687-
##
1713+
local TESTS_RESULTS="$ROOT_DIR/test/run/chrome"
16881714

16891715
# Chrome
1690-
mkdir -p "$ROOT_DIR/test/run/chrome"
1691-
yarn test:client > "$ROOT_DIR/test/run/chrome/chrome_logs.txt" 2>&1
1692-
local RET_CODE=$?
1716+
mkdir -p "$TESTS_RESULTS"
1717+
yarn test:client 2>&1 | tee "$TESTS_RESULTS/chrome_logs.txt"
16931718

16941719
# Firefox
16951720
# PUPPETEER_PRODUCT=firefox yarn add puppeteer
16961721
# yarn link "@kalisio/kdk" --link-folder /opt/kalisio/yarn-links
16971722
# export BROWSER="firefox"bucket
16981723
# mkdir -p "$ROOT_DIR/test/run/firefox"
1699-
# yarn test:client > "$ROOT_DIR/test/run/chrome/firefox_logs.txt" 2>&1
1724+
return $? # return the exit code of the tests
1725+
}
17001726

1701-
## Upload logs & screenshots to S3
1702-
##
1727+
# Upload e2e tests artefacts to some s3 storage.
1728+
# Expected args:
1729+
# 1. the app root dir
1730+
# 2. the app name
1731+
# 3. the s3 bucket where to upload artefacts (with a rclone remote, like ovh:e2e-test/blabla)
1732+
# 4. the rclone.conf file to use to upload artefacts
1733+
# 5. the file where the upload report will be written (json)
1734+
upload_e2e_tests_artefacts() {
1735+
local ROOT_DIR="$1"
1736+
local APP="$2"
1737+
local S3_BUCKET="$3"
1738+
local RCLONE_CONF="$4"
1739+
local UPLOAD_REPORT_FILE="$5"
1740+
1741+
local TIMESTAMP
1742+
TIMESTAMP="$(date +"%d-%m-%Y")"
1743+
local TESTS_RESULTS_DIR="$ROOT_DIR/test/run/chrome"
1744+
local WORK_DIR="$TMP_DIR/artefacts/$APP/$TIMESTAMP/e2e"
1745+
local REMOTE_DIR="$S3_BUCKET/$APP/$TIMESTAMP/e2e"
1746+
1747+
mkdir -p "$WORK_DIR"
1748+
1749+
# zip the whole tests results folder
1750+
local ZIP_FILE="$WORK_DIR/e2e-artefacts.zip"
1751+
cd "$TESTS_RESULTS_DIR"
1752+
zip -r "$ZIP_FILE" .
1753+
cd ~-
17031754

1704-
local CURRENT_DATE
1705-
CURRENT_DATE=$(date +"%d-%m-%Y")
1706-
local CHROME_LOGS_LINK=""
1707-
local SCREEN_LINK=""
1755+
# keep log file as is
1756+
cp "$TESTS_RESULTS_DIR/logs.txt" "$WORK_DIR/logs.txt"
17081757

1709-
zip -r "$TMP_DIR/screenshots.zip" "$ROOT_DIR/test/run"
1758+
# and keep captures and diffs for failed tests
1759+
local FAILED_TESTS=()
1760+
readarray -d '' DIFF_FILES < <(find "$TESTS_RESULTS_DIR" -type f -name 'diff.*.png' -print0)
1761+
for DIFF_FILE in "${DIFF_FILES[@]}"; do
1762+
local BASE_DIFF_FILE
1763+
BASE_DIFF_FILE="$(basename "$DIFF_FILE")"
1764+
local BASE_CAPTURE_FILE="${BASE_DIFF_FILE#diff.*}"
1765+
local CAPTURE_FILE
1766+
CAPTURE_FILE="$(dirname "$DIFF_FILE")/$BASE_CAPTURE_FILE"
17101767

1711-
rclone copy "$ROOT_DIR/test/run/chrome/chrome_logs.txt" "ovh-s3:/dev/e2e-tests/$APP/$CURRENT_DATE"
1712-
CHROME_LOGS_LINK=$(rclone link "ovh-s3:/dev/e2e-tests/$APP/$CURRENT_DATE/chrome_logs.txt")
1768+
local TEST_DIR
1769+
TEST_DIR="$(realpath -s --relative-to="$TESTS_RESULTS_DIR" "$DIFF_FILE")"
1770+
TEST_DIR="$(dirname "$TEST_DIR")"
1771+
TEST_DIR="$(dirname "$TEST_DIR")"
17131772

1714-
rclone copy "$TMP_DIR/screenshots.zip" "ovh-s3:/dev/e2e-tests/$APP/$CURRENT_DATE"
1715-
SCREEN_LINK=$(rclone link "ovh-s3:/dev/e2e-tests/$APP/$CURRENT_DATE/screenshots.zip")
1773+
local TEST_NAME
1774+
TEST_NAME="$TEST_DIR/${BASE_CAPTURE_FILE%.*}"
17161775

1717-
## Report outcome to slack
1718-
##
1776+
FAILED_TESTS+=("$TEST_NAME")
1777+
1778+
mkdir -p "$WORK_DIR/$TEST_DIR"
1779+
cp "$DIFF_FILE" "$WORK_DIR/$TEST_DIR"
1780+
cp "$CAPTURE_FILE" "$WORK_DIR/$TEST_DIR"
1781+
done
1782+
1783+
rclone --config "$RCLONE_CONF" copy "$TMP_DIR/artefacts" "$S3_BUCKET"
1784+
1785+
rm -fR "$WORK_DIR"
1786+
1787+
# now generate public http links
1788+
local ARTEFACTS_LINK
1789+
ARTEFACTS_LINK="$(rclone --config "$RCLONE_CONF" link "$REMOTE_DIR/e2e-artefacts.zip")"
1790+
local LOGS_LINK
1791+
LOGS_LINK="$(rclone --config "$RCLONE_CONF" link "$REMOTE_DIR/logs.txt")"
1792+
1793+
printf '{ "app": "%s", "timestamp": "%s", "artefacts": "%s", "logs": "%s", "num_failed": "%d", "failed": [' "$APP" "$TIMESTAMP" "$ARTEFACTS_LINK" "$LOGS_LINK" "${#FAILED_TESTS[@]}" > "$UPLOAD_REPORT_FILE"
1794+
1795+
local COMMA=""
1796+
for TEST_NAME in "${FAILED_TESTS[@]}"; do
1797+
local CAPTURE_LINK
1798+
CAPTURE_LINK="$(rclone --config "$RCLONE_CONF" link "$REMOTE_DIR/$TEST_NAME.png")"
1799+
local DIFF_FILE
1800+
DIFF_FILE="$(dirname "$TEST_NAME")/diff.$(basename "$TEST_NAME").png"
1801+
local DIFF_LINK
1802+
DIFF_LINK="$(rclone --config "$RCLONE_CONF" link "$REMOTE_DIR/$DIFF_FILE")"
1803+
printf '%s { "name": "%s", "capture": "%s", "diff": "%s" }' "$COMMA" "$TEST_NAME" "$CAPTURE_LINK" "$DIFF_LINK" >> "$UPLOAD_REPORT_FILE"
1804+
COMMA=","
1805+
done
1806+
1807+
printf " ] }" >> "$UPLOAD_REPORT_FILE"
1808+
}
1809+
1810+
# Generates a markdown report file from the upload report file
1811+
# generated by the upload_e2e_tests_artefacts function.
1812+
# Expected args:
1813+
# 1. the same upload report file used in upload_e2e_tests_artefacts
1814+
# 2. the file where to write the markdown report
1815+
# 3. the flavor to use for the markdown (see normalize_markdown_anchor)
1816+
generate_e2e_tests_markdown_report() {
1817+
local UPLOAD_REPORT_FILE="$1"
1818+
local MD_REPORT_FILE="$2"
1819+
local MD_FLAVOR="$3"
1820+
1821+
local APP
1822+
APP=$(get_json_value "$UPLOAD_REPORT_FILE" "app")
1823+
local TIMESTAMP
1824+
TIMESTAMP=$(get_json_value "$UPLOAD_REPORT_FILE" "timestamp")
1825+
local ARTEFACTS_LINK
1826+
ARTEFACTS_LINK=$(get_json_value "$UPLOAD_REPORT_FILE" "artefacts")
1827+
local LOGS_LINK
1828+
LOGS_LINK=$(get_json_value "$UPLOAD_REPORT_FILE" "logs")
1829+
local NUM_FAILED
1830+
NUM_FAILED=$(get_json_value "$UPLOAD_REPORT_FILE" "num_failed")
1831+
1832+
printf "# [%s] (e2e run from %s)\n\n" "$(echo "$APP" | tr '[:lower:]' '[:upper:]')" "$TIMESTAMP" > "$MD_REPORT_FILE"
1833+
printf "[All artefacts](%s), [logs](%s)\n\n" "$ARTEFACTS_LINK" "$LOGS_LINK" >> "$MD_REPORT_FILE"
1834+
1835+
if (( NUM_FAILED == 0 )); then
1836+
printf "> [!TIP]\n> All tests have passed\n" >> "$MD_REPORT_FILE"
1837+
else
1838+
printf "> [!CAUTION]\n> **%d** tests have failed\n" "$NUM_FAILED" >> "$MD_REPORT_FILE"
1839+
1840+
local SECTIONS=()
1841+
for (( i = 0; i < NUM_FAILED; ++i )); do
1842+
local TEST_NAME
1843+
TEST_NAME=$(get_json_value "$UPLOAD_REPORT_FILE" "failed[$i].name")
1844+
printf "> - [%s](#%s)\n" "$TEST_NAME" "$(normalize_markdown_anchor "$TEST_NAME" "$MD_FLAVOR")" >> "$MD_REPORT_FILE"
17191845

1720-
slack_e2e_report "$APP" "$RET_CODE" "$SLACK_WEBHOOK_APPS" "$CHROME_LOGS_LINK" "$SCREEN_LINK"
1846+
local CAPTURE_LINK
1847+
CAPTURE_LINK=$(get_json_value "$UPLOAD_REPORT_FILE" "failed[$i].capture")
1848+
local DIFF_LINK
1849+
DIFF_LINK=$(get_json_value "$UPLOAD_REPORT_FILE" "failed[$i].diff")
1850+
1851+
read -r -d '' SECTION <<EOF
1852+
## $TEST_NAME
1853+
Captured file | Diff file
1854+
--------------|----------
1855+
![Captured file]($CAPTURE_LINK) | ![Diff file]($DIFF_LINK)
1856+
1857+
EOF
1858+
1859+
SECTIONS+=("$SECTION")
1860+
done
1861+
1862+
printf "\n" >> "$MD_REPORT_FILE"
1863+
1864+
for SECTION in "${SECTIONS[@]}"; do
1865+
printf "%s\n" "$SECTION" >> "$MD_REPORT_FILE"
1866+
done
1867+
fi
1868+
}
1869+
1870+
# Add and commit the e2e tests report in a git repository.
1871+
# Expected args:
1872+
# 1. the same upload report file as upload_e2e_tests_artefacts
1873+
# 2. the report file to add to the repo
1874+
# 3. the repository url to use to clone and push (must be able to push!)
1875+
# 4. a folder in which the report will be moved
1876+
push_e2e_tests_report_to_git_repo() {
1877+
local UPLOAD_FILE="$1"
1878+
local REPORT_FILE="$2"
1879+
local REPOSITORY_URL="$3"
1880+
local REPORTS_BASE="$4"
1881+
1882+
local APP
1883+
APP=$(get_json_value "$UPLOAD_FILE" "app")
1884+
local TIMESTAMP
1885+
TIMESTAMP=$(get_json_value "$UPLOAD_FILE" "timestamp")
1886+
1887+
local WORK_DIR
1888+
WORK_DIR="$(mktemp -d -p "$TMP_DIR" push.XXXXXX)"
1889+
1890+
# Clone repo to a temp location
1891+
git clone --depth 1 "$REPOSITORY_URL" "$WORK_DIR"
1892+
# Copy report
1893+
local REPORT_DIR="$WORK_DIR"
1894+
[[ "$REPORTS_BASE" != "" ]] && REPORT_DIR="$REPORT_DIR/$REPORTS_BASE"
1895+
REPORT_DIR="$REPORT_DIR/$APP/$TIMESTAMP"
1896+
mkdir -p "$REPORT_DIR"
1897+
1898+
cp "$REPORT_FILE" "$REPORT_DIR"
1899+
cd "$WORK_DIR"
1900+
git add --all
1901+
git -c user.name="CI bot" -c user.email="[email protected]" commit --message "ci: e2e tests report from $TIMESTAMP"
1902+
git push origin
1903+
cd ~-
1904+
1905+
rm -fR "$WORK_DIR"
1906+
}
1907+
1908+
# Take all steps to run e2e test and push results to a git repository. Binary artefacts
1909+
# are uploaded on an s3 bucket.
1910+
# Expected args:
1911+
# 1. the app root dir
1912+
# 2. the app name
1913+
# 3. the s3 bucket where to upload binary artefacts
1914+
# 4. the rclone.conf file to use with rclone
1915+
# 5. the git repository url where we'll push the final report (must be able to push!)
1916+
# 6. a folder in which the report will be moved
1917+
run_and_publish_e2e_tests_to_git_repo() {
1918+
local ROOT_DIR="$1"
1919+
local APP="$2"
1920+
local S3_BUCKET="$3"
1921+
local RCLONE_CONF="$4"
1922+
local REPOSITORY_URL="$5"
1923+
local REPORTS_BASE="$6"
1924+
1925+
run_e2e_tests "$ROOT_DIR" "$APP"
1926+
1927+
local MD_FLAVOR
1928+
[[ "$REPOSITORY_URL" = *gitlab* ]] && MD_FLAVOR="gitlab"
1929+
[[ "$REPOSITORY_URL" = *github* ]] && MD_FLAVOR="github"
1930+
1931+
local UPLOAD_REPORT_FILE="$TMP_DIR/e2e-upload-report.json"
1932+
local MD_REPORT_FILE="$TMP_DIR/e2e.md"
1933+
1934+
upload_e2e_tests_artefacts \
1935+
"$ROOT_DIR" "$APP" \
1936+
"$S3_BUCKET" "$RCLONE_CONF" \
1937+
"$UPLOAD_REPORT_FILE"
1938+
generate_e2e_tests_markdown_report \
1939+
"$UPLOAD_REPORT_FILE" "$MD_REPORT_FILE" "$MD_FLAVOR"
1940+
push_e2e_tests_report_to_git_repo \
1941+
"$UPLOAD_REPORT_FILE" "$MD_REPORT_FILE" \
1942+
"$REPOSITORY_URL" "$REPORTS_BASE"
17211943
}

0 commit comments

Comments
 (0)