← back to Wine Finder Next

scripts/seo-validator.sh

157 lines

#!/bin/bash

# SEO Validation Script for Wine Membership Platform
# Tests schema markup, metadata, and technical SEO elements

BASE_URL="http://45.61.58.125:7250"
RESULTS_FILE="/tmp/seo_validation_$(date +%Y%m%d_%H%M%S).txt"

echo "=====================================" > "$RESULTS_FILE"
echo "SEO VALIDATION REPORT" >> "$RESULTS_FILE"
echo "Date: $(date)" >> "$RESULTS_FILE"
echo "URL: $BASE_URL/membership" >> "$RESULTS_FILE"
echo "=====================================" >> "$RESULTS_FILE"
echo "" >> "$RESULTS_FILE"

PASSED=0
FAILED=0

# Function to test and log results
test_seo() {
  local test_name="$1"
  local test_command="$2"

  echo -n "Testing: $test_name... "
  if eval "$test_command" > /dev/null 2>&1; then
    echo "PASS" | tee -a "$RESULTS_FILE"
    ((PASSED++))
  else
    echo "FAIL" | tee -a "$RESULTS_FILE"
    ((FAILED++))
  fi
}

echo "=== BASIC CONNECTIVITY ===" >> "$RESULTS_FILE"
test_seo "Server responds to HTTP requests" "curl -f -s $BASE_URL/membership"
test_seo "Membership page loads (200 OK)" "curl -s -o /dev/null -w '%{http_code}' $BASE_URL/membership | grep -q 200"
test_seo "Homepage loads (200 OK)" "curl -s -o /dev/null -w '%{http_code}' $BASE_URL | grep -q 200"
echo "" >> "$RESULTS_FILE"

echo "=== META TAGS ===" >> "$RESULTS_FILE"
PAGE_CONTENT=$(curl -s "$BASE_URL/membership")

test_seo "Title tag present" "echo '$PAGE_CONTENT' | grep -q '<title>'"
test_seo "Title contains 'Tokenized Wine'" "echo '$PAGE_CONTENT' | grep -i '<title>' | grep -q 'Tokenized Wine'"
test_seo "Meta description present" "echo '$PAGE_CONTENT' | grep -q 'meta name=\"description\"'"
test_seo "Meta description under 160 chars" "echo '$PAGE_CONTENT' | grep 'meta name=\"description\"' | grep -oP 'content=\"\K[^\"]*' | awk 'length(\$0) < 160'"
test_seo "Canonical URL present" "echo '$PAGE_CONTENT' | grep -q 'rel=\"canonical\"'"
test_seo "Viewport meta tag present" "echo '$PAGE_CONTENT' | grep -q 'name=\"viewport\"'"
echo "" >> "$RESULTS_FILE"

echo "=== OPEN GRAPH TAGS ===" >> "$RESULTS_FILE"
test_seo "OG title present" "echo '$PAGE_CONTENT' | grep -q 'property=\"og:title\"'"
test_seo "OG description present" "echo '$PAGE_CONTENT' | grep -q 'property=\"og:description\"'"
test_seo "OG image present" "echo '$PAGE_CONTENT' | grep -q 'property=\"og:image\"'"
test_seo "OG type present" "echo '$PAGE_CONTENT' | grep -q 'property=\"og:type\"'"
test_seo "OG URL present" "echo '$PAGE_CONTENT' | grep -q 'property=\"og:url\"'"
echo "" >> "$RESULTS_FILE"

echo "=== TWITTER CARD ===" >> "$RESULTS_FILE"
test_seo "Twitter card type present" "echo '$PAGE_CONTENT' | grep -q 'name=\"twitter:card\"'"
test_seo "Twitter title present" "echo '$PAGE_CONTENT' | grep -q 'name=\"twitter:title\"'"
test_seo "Twitter description present" "echo '$PAGE_CONTENT' | grep -q 'name=\"twitter:description\"'"
echo "" >> "$RESULTS_FILE"

echo "=== STRUCTURED DATA (JSON-LD) ===" >> "$RESULTS_FILE"
test_seo "JSON-LD script present" "echo '$PAGE_CONTENT' | grep -q 'application/ld+json'"
test_seo "Organization schema present" "echo '$PAGE_CONTENT' | grep -q '\"@type\":\"Organization\"'"
test_seo "WebSite schema present" "echo '$PAGE_CONTENT' | grep -q '\"@type\":\"WebSite\"'"
test_seo "FAQPage schema present" "echo '$PAGE_CONTENT' | grep -q '\"@type\":\"FAQPage\"'"
test_seo "Product schema present" "echo '$PAGE_CONTENT' | grep -q '\"@type\":\"Product\"'"
test_seo "BreadcrumbList schema present" "echo '$PAGE_CONTENT' | grep -q '\"@type\":\"BreadcrumbList\"'"
test_seo "HowTo schema present" "echo '$PAGE_CONTENT' | grep -q '\"@type\":\"HowTo\"'"
test_seo "Review schema present" "echo '$PAGE_CONTENT' | grep -q '\"@type\":\"Review\"'"
test_seo "AggregateRating schema present" "echo '$PAGE_CONTENT' | grep -q '\"@type\":\"AggregateRating\"'"
echo "" >> "$RESULTS_FILE"

echo "=== SEMANTIC HTML ===" >> "$RESULTS_FILE"
test_seo "H1 heading present" "echo '$PAGE_CONTENT' | grep -q '<h1'"
test_seo "H1 contains target keywords" "echo '$PAGE_CONTENT' | grep -i '<h1' | grep -q -E '(tokenized|wine|investment)'"
test_seo "Article tags present" "echo '$PAGE_CONTENT' | grep -q '<article'"
test_seo "Section tags present" "echo '$PAGE_CONTENT' | grep -q '<section'"
test_seo "Nav tag present" "echo '$PAGE_CONTENT' | grep -q '<nav'"
test_seo "Header tag present" "echo '$PAGE_CONTENT' | grep -q '<header'"
test_seo "Footer tag present" "echo '$PAGE_CONTENT' | grep -q '<footer'"
echo "" >> "$RESULTS_FILE"

echo "=== ACCESSIBILITY (ARIA) ===" >> "$RESULTS_FILE"
test_seo "ARIA labels present" "echo '$PAGE_CONTENT' | grep -q 'aria-label'"
test_seo "ARIA roles present" "echo '$PAGE_CONTENT' | grep -q 'role='"
echo "" >> "$RESULTS_FILE"

echo "=== SITEMAP & ROBOTS ===" >> "$RESULTS_FILE"
test_seo "Sitemap accessible" "curl -f -s $BASE_URL/sitemap.xml"
test_seo "Sitemap contains membership page" "curl -s $BASE_URL/sitemap.xml | grep -q '/membership'"
test_seo "Robots.txt accessible" "curl -f -s $BASE_URL/robots.txt"
test_seo "Robots.txt allows indexing" "curl -s $BASE_URL/robots.txt | grep -q 'Allow: /'"
test_seo "Robots.txt references sitemap" "curl -s $BASE_URL/robots.txt | grep -q 'Sitemap:'"
echo "" >> "$RESULTS_FILE"

echo "=== SECURITY HEADERS ===" >> "$RESULTS_FILE"
HEADERS=$(curl -s -I "$BASE_URL/membership")
test_seo "X-Frame-Options header present" "echo '$HEADERS' | grep -q -i 'X-Frame-Options'"
test_seo "X-Content-Type-Options header present" "echo '$HEADERS' | grep -q -i 'X-Content-Type-Options'"
test_seo "Referrer-Policy header present" "echo '$HEADERS' | grep -q -i 'Referrer-Policy'"
echo "" >> "$RESULTS_FILE"

echo "=== PERFORMANCE ===" >> "$RESULTS_FILE"
RESPONSE_TIME=$(curl -o /dev/null -s -w '%{time_total}\n' "$BASE_URL/membership")
test_seo "Page loads under 3 seconds" "echo '$RESPONSE_TIME < 3' | bc -l | grep -q 1"

SIZE=$(curl -s "$BASE_URL/membership" | wc -c)
test_seo "HTML size reasonable (<500KB)" "test $SIZE -lt 500000"
echo "" >> "$RESULTS_FILE"

echo "=== KEYWORD DENSITY ===" >> "$RESULTS_FILE"
TOKENIZED_COUNT=$(echo "$PAGE_CONTENT" | grep -io 'tokenized' | wc -l)
INVESTMENT_COUNT=$(echo "$PAGE_CONTENT" | grep -io 'investment' | wc -l)
WINE_COUNT=$(echo "$PAGE_CONTENT" | grep -io 'wine' | wc -l)

echo "Keyword occurrences:" >> "$RESULTS_FILE"
echo "  - 'tokenized': $TOKENIZED_COUNT" >> "$RESULTS_FILE"
echo "  - 'investment': $INVESTMENT_COUNT" >> "$RESULTS_FILE"
echo "  - 'wine': $WINE_COUNT" >> "$RESULTS_FILE"
test_seo "Target keyword 'tokenized' present" "test $TOKENIZED_COUNT -gt 0"
test_seo "Target keyword 'investment' present" "test $INVESTMENT_COUNT -gt 0"
echo "" >> "$RESULTS_FILE"

echo "=====================================" >> "$RESULTS_FILE"
echo "SUMMARY" >> "$RESULTS_FILE"
echo "=====================================" >> "$RESULTS_FILE"
echo "Tests Passed: $PASSED" >> "$RESULTS_FILE"
echo "Tests Failed: $FAILED" >> "$RESULTS_FILE"
echo "Success Rate: $(echo "scale=2; $PASSED * 100 / ($PASSED + $FAILED)" | bc)%" >> "$RESULTS_FILE"
echo "" >> "$RESULTS_FILE"

if [ $FAILED -eq 0 ]; then
  echo "RESULT: ALL TESTS PASSED ✓" >> "$RESULTS_FILE"
  RESULT="PASS"
else
  echo "RESULT: SOME TESTS FAILED ✗" >> "$RESULTS_FILE"
  RESULT="FAIL"
fi

echo "=====================================" >> "$RESULTS_FILE"

# Display results
cat "$RESULTS_FILE"
echo ""
echo "Full report saved to: $RESULTS_FILE"

# Exit with appropriate code
if [ "$RESULT" = "PASS" ]; then
  exit 0
else
  exit 1
fi