#!/usr/bin/env python3 """Regression for the live-test bugs (Phase 8 follow-up): BUG A Tectonic was invoked with `--synctex 0` -> the `0` is consumed as the INPUT and the real .tex becomes an "unexpected argument", so the PDF never compiles. Fix: minimal `tectonic --outdir --keep-logs `. BUG B content.js stripChrome() read textContent off a DETACHED clone, joining adjacent elements with NO whitespace -> Frankenstein tokens like "engineergreater hyderabad" / "managerzamp". Fix: insert separators. BUG C A jobs LIST / search / recommendations page (title "Top job picks for you") produced junk keywords and a 0% resume. Fix: detect + fail loudly. Deterministic, ASCII-only, no network, no LaTeX engine required. """ import os import re import sys ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, ROOT) _ok = True def check(name, cond, detail=""): global _ok status = "PASS" if cond else "FAIL" if not cond: _ok = False print(f" [{status}] {name}" + (f" {detail}" if detail else "")) return cond def read(rel): with open(os.path.join(ROOT, rel), encoding="utf-8") as f: return f.read() print("=" * 70) print("Phase 8 follow-up: extraction + LaTeX-compile bug fixes") print("=" * 70) # ── BUG A: Tectonic command line ───────────────────────────────────────────── print("[A] Tectonic invocation is well-formed (no --synctex value trap)") from src.latex_resume import _engine_commands cmds = _engine_commands("tectonic", "/tmp/out/resume.tex", "/tmp/out") cmd = cmds[0] check("engine is tectonic", cmd[0] == "tectonic", " ".join(cmd)) check("no --synctex flag", "--synctex" not in cmd) check("no bare numeric positional ('0')", "0" not in cmd) check("input .tex is the final positional", cmd[-1] == "/tmp/out/resume.tex", cmd[-1]) check("--outdir points at the out dir", "--outdir" in cmd and cmd[cmd.index("--outdir") + 1] == "/tmp/out") # ── BUG B: stripChrome inserts whitespace separators ───────────────────────── print("[B] content.js stripChrome separates tokens (no concatenation)") content = read("extension/content.js") check("inserts a separator text node between elements", "createTextNode(' \\n')" in content) check("reads textContent after inserting separators", "clone.textContent" in content) # ── BUG C: non-job / listing-page detection ────────────────────────────────── print("[C] content.js rejects jobs-list / recommendation pages") check("NON_JOB_TITLES table present", "NON_JOB_TITLES" in content) check("'top job picks for you' is blacklisted", "top job picks for you" in content.lower()) check("looksLikeListingJunk() exists", "looksLikeListingJunk" in content) check("flags repeated 'easy apply' rows", "easy apply" in content.lower()) check("sets extraction_reason='not_a_job_posting'", "not_a_job_posting" in content) check("raises the min-JD-length gate to 80", "length < 80" in content) print("[C] popup.js surfaces the not-a-posting reason") popup = read("extension/popup/popup.js") check("popup handles not_a_job_posting", "not_a_job_posting" in popup) # ── Realistic LaTeX injection coverage (no compile needed) ──────────────────── print("[D] Realistic PM LaTeX + JD -> honest keyword coverage") from src.latex_resume import optimize_latex_resume SAMPLE_LATEX = r""" \documentclass{article} \begin{document} \section*{Summary} Product Manager with experience shipping B2B SaaS products, partnering with engineering and design, and running discovery with customers. \section*{Experience} \textbf{Senior Product Manager} \\ Acme SaaS (2021--2024) \begin{itemize} \item Owned the product roadmap for a B2B analytics platform. \item Ran A/B tests and user research to prioritize the backlog. \item Partnered with engineering on go-to-market for two launches. \end{itemize} \end{document} """ JD = ( "We are hiring a Product Manager for our B2B SaaS platform. You will own the " "product roadmap, define product strategy, run user research and discovery, " "prioritize the backlog, partner with engineering and design, lead " "go-to-market, run A/B testing and experimentation, define KPIs and metrics, " "and work with stakeholders. Experience with agile, data analysis, SQL, " "machine learning and generative AI product features is a plus. Strong " "stakeholder management and roadmapping skills required." ) report = optimize_latex_resume( SAMPLE_LATEX, JD, maximum_ats_mode=True, confirmed_terms=[], blocked_terms=[], compile_pdf=False, out_dir=None, job_title="pm", ) pct = int(report.get("pct", 0) or 0) injected = report.get("injected", []) gated = report.get("gated", {}) or {} blocked_injected = [t for t in injected if "blocked" in str(gated.get(t, "")).lower()] print(f" coverage pct = {pct}% injected = {len(injected)} terms") check("coverage >= 85% on a well-matched PM JD (path can reach 90%+)", pct >= 85, f"{pct}%") check("no blocked/fabrication term injected", not blocked_injected, str(blocked_injected)) for fab in ("cissp", "pmp", "cuda", "12+ years"): blob = (report.get("tex", "") or "").lower() check(f"no fabrication term in output: '{fab}'", fab not in blob) # ── Guaranteed PDF fallback + multi-engine resilience ──────────────────────── print("[E] Guaranteed PDF fallback + multi-engine resilience") import tempfile import shutil as _sh from src.latex_resume import render_text_to_pdf, latex_engines_available _tmp = tempfile.mkdtemp() _fb = os.path.join(_tmp, "fb.pdf") _out = render_text_to_pdf( "Jane Doe\nProduct Manager\n\nEXPERIENCE\nOwned the product roadmap.", _fb) check("render_text_to_pdf() produces a non-empty PDF (no LaTeX engine needed)", bool(_out) and os.path.exists(_fb) and os.path.getsize(_fb) > 0, f"{os.path.getsize(_fb) if os.path.exists(_fb) else 0} bytes") _sh.rmtree(_tmp, ignore_errors=True) check("latex_engines_available() returns a list (multi-engine fallback)", isinstance(latex_engines_available(), list)) api = read("api_server.py") check("both LaTeX branches add a pdf_fallback flag", api.count("pdf_fallback") >= 4, f"count={api.count('pdf_fallback')}") check("API fallback uses render_text_to_pdf", "render_text_to_pdf" in api) # ── Panel <-> popup run sync ───────────────────────────────────────────────── print("[F] Side-panel <-> popup run-state sync") check("popup reflects a 'running' change from another surface", "entry.status === 'running'" in popup) check("popup surfaces the pdf_fallback note", "pdf_fallback" in popup) print("-" * 70) print("PASS - extraction junk-guard + tectonic fix + PDF fallback + sync verified" if _ok else "FAIL - see above") sys.exit(0 if _ok else 1)