#!/bin/bash # e2e-helpers.sh — Shared validation functions for E2E regression tests set -euo pipefail # Counters PASS=0 FAIL=0 WARN=0 SUITE_NAME="" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' init_suite() { SUITE_NAME="$1" PASS=0 FAIL=0 WARN=0 echo -e "${BLUE}═══════════════════════════════════════${NC}" echo -e "${BLUE} E2E Suite: $SUITE_NAME${NC}" echo -e "${BLUE}═══════════════════════════════════════${NC}" echo "" } pass() { PASS=$((PASS + 1)) echo -e " ${GREEN}PASS${NC} $1" } fail() { FAIL=$((FAIL + 1)) echo -e " ${RED}FAIL${NC} $1" } warn() { WARN=$((WARN + 1)) echo -e " ${YELLOW}WARN${NC} $1" } print_summary() { local total=$((PASS + FAIL)) echo "" echo -e "${BLUE}───────────────────────────────────────${NC}" echo -e " ${SUITE_NAME}: ${PASS}/${total} PASS, ${FAIL} FAIL, ${WARN} WARN" echo -e "${BLUE}───────────────────────────────────────${NC}" echo "" return $FAIL } # --- Assertions --- assert_has_section() { local file="$1" local header="$2" local description="${3:-Section: $header}" if grep -qE "^#{1,4} .*${header}" "$file"; then pass "$description" else fail "$description — header '$header' not found" fi } assert_min_lines() { local file="$1" local min="$2" local description="${3:-Minimum $min lines}" local count count=$(wc -l < "$file" | tr -d ' ') if [ "$count" -ge "$min" ]; then pass "$description ($count lines)" else fail "$description — only $count lines (min: $min)" fi } assert_encoding_ok() { local file="$1" local description="${2:-UTF-8 encoding valid}" # Check for common broken UTF-8 sequences if file "$file" | grep -qi "utf-8\|ascii\|unicode"; then pass "$description" else fail "$description — encoding not UTF-8/ASCII" fi } assert_no_ascii_approximation() { local file="$1" local description="${2:-No ASCII approximation of Norwegian chars}" # Check for ae/oe/aa used where æ/ø/å should be (Norwegian words) # Only flag common Norwegian words that should have æøå local violations=0 for pattern in '\bvaere\b' '\bfoerste\b' '\bhoey\b' '\bgjoere\b' '\baarlig\b' '\bsaerlig\b' '\bnoedvendig\b'; do if grep -qiE "$pattern" "$file" 2>/dev/null; then violations=$((violations + 1)) fi done if [ "$violations" -eq 0 ]; then pass "$description" else fail "$description — $violations ASCII approximation patterns found" fi } assert_scores_in_range() { local file="$1" local description="${2:-Scores in X/5 format within range}" # Match X/5 or X.X/5 patterns and verify range local bad_scores=0 while IFS= read -r match; do local score="${match%%/*}" score=$(echo "$score" | tr -d ' ') # Check if it's a valid number between 0 and 5 if echo "$score" | grep -qE '^[0-5](\.[0-9]+)?$'; then : else bad_scores=$((bad_scores + 1)) fi done < <(grep -oE '[0-9]+\.?[0-9]*/5' "$file" 2>/dev/null || true) local total_scores total_scores=$(grep -cE '[0-9]+\.?[0-9]*/5' "$file" 2>/dev/null || echo "0") if [ "$total_scores" -gt 0 ] && [ "$bad_scores" -eq 0 ]; then pass "$description ($total_scores scores found)" elif [ "$total_scores" -eq 0 ]; then fail "$description — no X/5 scores found" else fail "$description — $bad_scores out-of-range scores" fi } assert_has_nok_amounts() { local file="$1" local min="${2:-1}" local description="${3:-NOK amounts present}" local count count=$(grep -cE '([0-9]+[.,]?[0-9]*(M|K)\s*NOK|[0-9]+\s*NOK|NOK\s*[0-9]+|[0-9]+\s*000\s*NOK)' "$file" 2>/dev/null || echo "0") if [ "$count" -ge "$min" ]; then pass "$description ($count found)" else fail "$description — only $count NOK amounts (min: $min)" fi } assert_min_tables() { local file="$1" local min="$2" local description="${3:-Minimum $min markdown tables}" # Count lines starting with | that contain | somewhere after the first char (table rows) local table_separators table_separators=$(grep -cE '^\|.*\|.*\|' "$file" 2>/dev/null || echo "0") # Rough estimate: each table has header + separator + at least 1 row = 3 lines minimum local estimated_tables=$((table_separators / 3)) if [ "$estimated_tables" -ge "$min" ]; then pass "$description (~$estimated_tables tables)" else fail "$description — only ~$estimated_tables tables (min: $min)" fi } assert_matches_pattern() { local file="$1" local pattern="$2" local description="${3:-Pattern match: $pattern}" if grep -qE "$pattern" "$file"; then pass "$description" else fail "$description" fi } assert_has_dimensions() { local file="$1" local min="$2" local description="${3:-Minimum $min security dimensions}" local count count=$(grep -cE '^\| .+ \| [0-9]+\.?[0-9]*/5' "$file" 2>/dev/null || echo "0") if [ "$count" -ge "$min" ]; then pass "$description ($count dimensions)" else fail "$description — only $count dimensions (min: $min)" fi }