|
| 1 | +import time |
| 2 | +from playwright.sync_api import sync_playwright |
| 3 | +import urllib.request |
| 4 | +import json |
| 5 | +import ssl |
| 6 | + |
| 7 | +def check_live(): |
| 8 | + # Wait for github pages to build by checking if the sitemap is live |
| 9 | + print("Waiting for GitHub Pages to deploy...") |
| 10 | + ctx = ssl.create_default_context() |
| 11 | + ctx.check_hostname = False |
| 12 | + ctx.verify_mode = ssl.CERT_NONE |
| 13 | + |
| 14 | + max_retries = 30 |
| 15 | + for i in range(max_retries): |
| 16 | + try: |
| 17 | + req = urllib.request.Request("https://techstackglobal.github.io/sitemap.xml", headers={'User-Agent': 'Mozilla/5.0'}) |
| 18 | + res = urllib.request.urlopen(req, context=ctx) |
| 19 | + content = res.read().decode() |
| 20 | + if "<loc>https://techstackglobal.github.io/</loc>" in content: |
| 21 | + print("Deployment detected! Proceeding to UI and Console checks.") |
| 22 | + break |
| 23 | + except Exception as e: |
| 24 | + pass |
| 25 | + |
| 26 | + print(f"Waiting for deployment... ({i+1}/{max_retries})") |
| 27 | + time.sleep(10) |
| 28 | + |
| 29 | + else: |
| 30 | + print("FAIL: Deployment check timed out.") |
| 31 | + return |
| 32 | + |
| 33 | + results = {} |
| 34 | + |
| 35 | + with sync_playwright() as p: |
| 36 | + browser = p.chromium.launch(headless=True) |
| 37 | + # 1. Desktop Check |
| 38 | + desktop_page = browser.new_page(viewport={'width': 1280, 'height': 800}) |
| 39 | + console_errors = [] |
| 40 | + desktop_page.on("console", lambda msg: console_errors.append(msg.text) if msg.type == "error" else None) |
| 41 | + |
| 42 | + try: |
| 43 | + r = desktop_page.goto("https://techstackglobal.github.io/", wait_until="networkidle") |
| 44 | + results["Homepage desktop"] = "OK" if r.ok else "FAIL" |
| 45 | + |
| 46 | + # Check H1 visibility and header overlap |
| 47 | + h1 = desktop_page.locator("h1") |
| 48 | + header = desktop_page.locator("header") |
| 49 | + h1_box = h1.bounding_box() |
| 50 | + header_box = header.bounding_box() |
| 51 | + if h1_box and header_box and h1_box["y"] > header_box["y"] + header_box["height"]: |
| 52 | + results["H1 visible"] = "OK" |
| 53 | + else: |
| 54 | + results["H1 visible"] = "FAIL (Obscured or not found)" |
| 55 | + |
| 56 | + # Meta & OG tags |
| 57 | + has_meta = desktop_page.evaluate("""() => { |
| 58 | + return !!document.querySelector('meta[name="description"]') && |
| 59 | + !!document.querySelector('meta[property="og:title"]') && |
| 60 | + !!document.querySelector('meta[property="og:image"]'); |
| 61 | + }""") |
| 62 | + results["Meta & OG present"] = "OK" if has_meta else "FAIL" |
| 63 | + |
| 64 | + # CTA check |
| 65 | + cta = desktop_page.locator(".cta-box") |
| 66 | + results["CTA check"] = "OK" if cta.is_visible() and desktop_page.locator(".cta-box form button").is_visible() else "FAIL" |
| 67 | + |
| 68 | + # Console errors |
| 69 | + results["Console errors"] = "OK" if len(console_errors) == 0 else f"FAIL ({console_errors})" |
| 70 | + except Exception as e: |
| 71 | + results["Homepage desktop"] = f"FAIL ({e})" |
| 72 | + |
| 73 | + # 2. Mobile Emulated Check |
| 74 | + mobile_page = browser.new_page(viewport={'width': 375, 'height': 667}) |
| 75 | + try: |
| 76 | + mobile_page.goto("https://techstackglobal.github.io/", wait_until="networkidle") |
| 77 | + results["Homepage mobile"] = "OK" |
| 78 | + |
| 79 | + # Check horizontal overflow |
| 80 | + overflow = mobile_page.evaluate("""() => { |
| 81 | + return document.documentElement.scrollWidth > window.innerWidth; |
| 82 | + }""") |
| 83 | + results["No horizontal overflow"] = "FAIL (Overflow detected)" if overflow else "OK" |
| 84 | + except Exception as e: |
| 85 | + results["Homepage mobile"] = f"FAIL ({e})" |
| 86 | + |
| 87 | + browser.close() |
| 88 | + |
| 89 | + # Check robots.txt |
| 90 | + try: |
| 91 | + req = urllib.request.Request("https://techstackglobal.github.io/robots.txt", headers={'User-Agent': 'Mozilla/5.0'}) |
| 92 | + res = urllib.request.urlopen(req, context=ctx) |
| 93 | + rb = res.read().decode() |
| 94 | + if "Allow: /" in rb and "sitemap.xml" in rb: |
| 95 | + results["robots.txt"] = "OK" |
| 96 | + else: |
| 97 | + results["robots.txt"] = "FAIL" |
| 98 | + except Exception: |
| 99 | + results["robots.txt"] = "FAIL" |
| 100 | + |
| 101 | + # Check OG Image loads |
| 102 | + try: |
| 103 | + req = urllib.request.Request("https://techstackglobal.github.io/assets/og-image.jpg", headers={'User-Agent': 'Mozilla/5.0'}) |
| 104 | + res = urllib.request.urlopen(req, context=ctx) |
| 105 | + results["OG image loads"] = "OK" if res.status == 200 else "FAIL" |
| 106 | + except Exception: |
| 107 | + results["OG image loads"] = "FAIL" |
| 108 | + |
| 109 | + results["sitemap.xml"] = "OK" |
| 110 | + |
| 111 | + for k, v in results.items(): |
| 112 | + print(f"{k}: {v}") |
| 113 | + |
| 114 | +check_live() |
0 commit comments