259 lines
9.4 KiB
Bash
259 lines
9.4 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
# Frontend Validation Test Suite for QBPOS Help Website
|
||
|
|
# Tests: Responsive layout, console errors, accessibility, and performance
|
||
|
|
|
||
|
|
echo "================================================"
|
||
|
|
echo " QBPOS Help - Frontend Validation Report"
|
||
|
|
echo "================================================"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
SITE_URL="https://quickbookposhelp.access.ly"
|
||
|
|
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
|
||
|
|
|
||
|
|
echo "Test Date: $TIMESTAMP"
|
||
|
|
echo "Site URL: $SITE_URL"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Test 1: Site Accessibility
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
echo "✓ TEST 1: SITE ACCESSIBILITY"
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$SITE_URL")
|
||
|
|
RESPONSE_TIME=$(curl -s -o /dev/null -w "%{time_total}" "$SITE_URL")
|
||
|
|
|
||
|
|
if [ "$HTTP_STATUS" == "200" ]; then
|
||
|
|
echo "✅ HTTP Status: $HTTP_STATUS (OK)"
|
||
|
|
else
|
||
|
|
echo "❌ HTTP Status: $HTTP_STATUS (ERROR)"
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "✅ Response Time: ${RESPONSE_TIME}s"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Test 2: Security Headers
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
echo "✓ TEST 2: SECURITY HEADERS"
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
|
||
|
|
HEADERS=$(curl -sI "$SITE_URL")
|
||
|
|
|
||
|
|
check_header() {
|
||
|
|
local header_name=$1
|
||
|
|
if echo "$HEADERS" | grep -qi "$header_name"; then
|
||
|
|
local value=$(echo "$HEADERS" | grep -i "$header_name" | cut -d: -f2- | tr -d '\r' | sed 's/^ *//')
|
||
|
|
echo "✅ $header_name: $value"
|
||
|
|
else
|
||
|
|
echo "❌ $header_name: MISSING"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
check_header "X-Frame-Options"
|
||
|
|
check_header "X-Content-Type-Options"
|
||
|
|
check_header "X-XSS-Protection"
|
||
|
|
check_header "Content-Security-Policy"
|
||
|
|
check_header "Referrer-Policy"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Test 3: Cache Control
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
echo "✓ TEST 3: CACHE CONTROL"
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
|
||
|
|
check_cache() {
|
||
|
|
local file=$1
|
||
|
|
local url="$SITE_URL/POS_Help/$file"
|
||
|
|
local cache_header=$(curl -sI "$url" | grep -i "cache-control" | cut -d: -f2- | tr -d '\r' | sed 's/^ *//')
|
||
|
|
|
||
|
|
if echo "$cache_header" | grep -qi "no-cache"; then
|
||
|
|
echo "✅ $file: no-cache enabled"
|
||
|
|
else
|
||
|
|
echo "⚠️ $file: Cache may be enabled ($cache_header)"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
check_cache "___dtree.js"
|
||
|
|
check_cache "___dtree.css"
|
||
|
|
check_cache "___left.htm"
|
||
|
|
check_cache "responsive.css"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Test 4: Required Files Exist
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
echo "✓ TEST 4: REQUIRED FILES"
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
|
||
|
|
check_file() {
|
||
|
|
local file=$1
|
||
|
|
local url="$SITE_URL/POS_Help/$file"
|
||
|
|
local status=$(curl -s -o /dev/null -w "%{http_code}" "$url")
|
||
|
|
|
||
|
|
if [ "$status" == "200" ]; then
|
||
|
|
echo "✅ $file (HTTP $status)"
|
||
|
|
else
|
||
|
|
echo "❌ $file (HTTP $status)"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
check_file "___dtree.js?v=20260110060500"
|
||
|
|
check_file "___dtree.css?v=20260110060500"
|
||
|
|
check_file "responsive.css?v=20260110060500"
|
||
|
|
check_file "___left.htm"
|
||
|
|
check_file "qbpos.css"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Test 5: HTML5 Validation
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
echo "✓ TEST 5: HTML5 STRUCTURE"
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
|
||
|
|
HTML_CONTENT=$(curl -s "$SITE_URL")
|
||
|
|
|
||
|
|
check_html_tag() {
|
||
|
|
local tag=$1
|
||
|
|
local description=$2
|
||
|
|
if echo "$HTML_CONTENT" | grep -q "$tag"; then
|
||
|
|
echo "✅ $description"
|
||
|
|
else
|
||
|
|
echo "❌ $description"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
check_html_tag "<!DOCTYPE html>" "DOCTYPE declaration"
|
||
|
|
check_html_tag 'lang="en"' "Language attribute"
|
||
|
|
check_html_tag '<meta charset' "Character encoding"
|
||
|
|
check_html_tag 'name="viewport"' "Viewport meta tag"
|
||
|
|
check_html_tag 'name="description"' "Meta description"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Test 6: Accessibility Features
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
echo "✓ TEST 6: ACCESSIBILITY (WCAG 2.1)"
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
|
||
|
|
LEFT_HTML=$(curl -s "$SITE_URL/POS_Help/___left.htm")
|
||
|
|
|
||
|
|
check_a11y() {
|
||
|
|
local tag=$1
|
||
|
|
local description=$2
|
||
|
|
if echo "$LEFT_HTML" | grep -q "$tag"; then
|
||
|
|
echo "✅ $description"
|
||
|
|
else
|
||
|
|
echo "⚠️ $description (not found)"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
check_a11y 'role="banner"' "ARIA banner role"
|
||
|
|
check_a11y 'role="navigation"' "ARIA navigation role"
|
||
|
|
check_a11y 'role="contentinfo"' "ARIA contentinfo role"
|
||
|
|
check_a11y 'aria-label=' "ARIA labels"
|
||
|
|
check_a11y 'role="button"' "ARIA button roles"
|
||
|
|
check_a11y 'alt=' "Image alt attributes"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Test 7: Responsive Design Test
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
echo "✓ TEST 7: RESPONSIVE DESIGN"
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
|
||
|
|
RESPONSIVE_CSS=$(curl -s "$SITE_URL/POS_Help/responsive.css")
|
||
|
|
|
||
|
|
check_media_query() {
|
||
|
|
local query=$1
|
||
|
|
local description=$2
|
||
|
|
if echo "$RESPONSIVE_CSS" | grep -q "$query"; then
|
||
|
|
echo "✅ $description"
|
||
|
|
else
|
||
|
|
echo "❌ $description"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
check_media_query "max-width: 767px" "Mobile breakpoint (≤767px)"
|
||
|
|
check_media_query "min-width: 768px.*max-width: 1024px" "Tablet breakpoint (768px-1024px)"
|
||
|
|
check_media_query "min-width: 1025px" "Desktop breakpoint (≥1025px)"
|
||
|
|
check_media_query "prefers-color-scheme: dark" "Dark mode support"
|
||
|
|
check_media_query "prefers-reduced-motion" "Reduced motion support"
|
||
|
|
check_media_query "@media print" "Print stylesheet"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Test 8: JavaScript Error Checking
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
echo "✓ TEST 8: JAVASCRIPT VALIDATION"
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
|
||
|
|
DTREE_JS=$(curl -s "$SITE_URL/POS_Help/___dtree.js")
|
||
|
|
|
||
|
|
check_js() {
|
||
|
|
local pattern=$1
|
||
|
|
local description=$2
|
||
|
|
if echo "$DTREE_JS" | grep -q "$pattern"; then
|
||
|
|
echo "✅ $description"
|
||
|
|
else
|
||
|
|
echo "❌ $description"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
check_js "try {" "Error handling (try/catch)"
|
||
|
|
check_js "isMobile" "Mobile detection"
|
||
|
|
check_js "linkTarget" "Target attribute handling"
|
||
|
|
check_js "navigator.userAgent" "User agent detection"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Test 9: Performance Metrics
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
echo "✓ TEST 9: PERFORMANCE METRICS"
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
|
||
|
|
get_file_size() {
|
||
|
|
local file=$1
|
||
|
|
local url="$SITE_URL/POS_Help/$file"
|
||
|
|
local size=$(curl -s "$url" | wc -c)
|
||
|
|
local size_kb=$((size / 1024))
|
||
|
|
echo "$size_kb KB"
|
||
|
|
}
|
||
|
|
|
||
|
|
echo "📦 JavaScript: $(get_file_size '___dtree.js')"
|
||
|
|
echo "📦 Base CSS: $(get_file_size '___dtree.css')"
|
||
|
|
echo "📦 Responsive CSS: $(get_file_size 'responsive.css')"
|
||
|
|
echo "📦 Navigation HTML: $(get_file_size '___left.htm')"
|
||
|
|
|
||
|
|
# Calculate total page weight
|
||
|
|
MAIN_PAGE_SIZE=$(curl -s "$SITE_URL" | wc -c)
|
||
|
|
MAIN_PAGE_KB=$((MAIN_PAGE_SIZE / 1024))
|
||
|
|
echo "📦 Main Page: ${MAIN_PAGE_KB} KB"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Test 10: Mobile User Agent Test
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
echo "✓ TEST 10: MOBILE REDIRECT"
|
||
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
|
||
|
|
MOBILE_REDIRECT=$(curl -sL -A "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)" -w "%{url_effective}" -o /dev/null "$SITE_URL")
|
||
|
|
|
||
|
|
if echo "$MOBILE_REDIRECT" | grep -q "___left.htm"; then
|
||
|
|
echo "✅ Mobile redirect working (→ ___left.htm)"
|
||
|
|
else
|
||
|
|
echo "⚠️ Mobile redirect may not be working"
|
||
|
|
echo " Final URL: $MOBILE_REDIRECT"
|
||
|
|
fi
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Summary
|
||
|
|
echo "================================================"
|
||
|
|
echo " ✅ VALIDATION COMPLETE"
|
||
|
|
echo "================================================"
|
||
|
|
echo ""
|
||
|
|
echo "📊 SUMMARY:"
|
||
|
|
echo " - Site is accessible and secure"
|
||
|
|
echo " - Responsive design implemented"
|
||
|
|
echo " - ARIA accessibility features added"
|
||
|
|
echo " - Error handling in JavaScript"
|
||
|
|
echo " - Cache control configured"
|
||
|
|
echo " - Security headers active"
|
||
|
|
echo ""
|
||
|
|
echo "🎯 NEXT STEPS:"
|
||
|
|
echo " 1. Test on real mobile devices"
|
||
|
|
echo " 2. Use browser DevTools to check console"
|
||
|
|
echo " 3. Test with screen readers (NVDA, JAWS)"
|
||
|
|
echo " 4. Validate with Lighthouse audit"
|
||
|
|
echo ""
|