Files
C.E.L_Slide_test2/.orchestrator/tmp/post_u3.py
T

53 lines
4.7 KiB
Python

import os
import sys
import requests
body = r"""Executing unit: u3
[Claude #6]
**unit_executed**: u3 — render-one-frame function (open file URL, wait fonts.ready, measure `.slide` via getBoundingClientRect, WebElement.screenshot, return `(w, h, png_path)` or raise)
**files_changed**:
- MOD `D:\ad-hoc\kei\design_agent\scripts\generate_frame_previews.py` (63 → 88 lines per `Measure-Object -Line`; u3 net add = 25 lines, ≤ Stage 2 u3 estimate of 50)
- MOD module-docstring line updated `(u1+u2; …u3-u6)` → `(u1-u3; stale/orphan/manifest added in u4-u6)`
**diff_summary**:
- Added `render_one(driver: Any, row: FrameRow) -> tuple[int, int, Path]` between `_build_driver()` and `main()`. Returns `(w, h, png_path)` on success; raises `FileNotFoundError` if `row.has_index` is False; raises `RuntimeError` if `.slide` not found. Matches Stage 2 u3 contract verbatim.
- **Driver injected** (caller owns lifecycle). u6 will build the driver once and pass it across many `render_one` calls, avoiding per-frame chromedriver startup cost. `_build_driver()` is untouched.
- **Lazy Selenium import**: `from selenium.webdriver.common.by import By` inside the function body, preserving the u2 design (`import generate_frame_previews` must not require selenium at module-import time → keeps u7 smoke-test path open).
- **fonts.ready wait**: `driver.set_script_timeout(15)` + `driver.execute_async_script(...)` that awaits `document.fonts.ready` if present, falling back to `Promise.resolve()`. Synchronous from Python side — function returns only after fonts are loaded.
- **`.slide` measure via getBoundingClientRect**: `driver.execute_script` returns `[Math.round(r.width), Math.round(r.height)]` from `document.querySelector('.slide').getBoundingClientRect()`. No hardcoded slide dimensions — width/height read from the DOM at runtime (RULE 7 satisfied).
- **Window-size derived from bbox**: `driver.set_window_size(w, h)` after measurement, so the WebElement screenshot capture region matches the slide's natural size whatever it is. No `1280` / `720` / `1400` / `900` literal in the script.
- **WebElement.screenshot**: `driver.find_element(By.CSS_SELECTOR, '.slide').screenshot_as_png` → `row.preview_png_path.write_bytes(...)`. Element-scoped capture, not full-page; matches the IMP-13 root-cause salvage anchor (`capture_slide_screenshot` base64 path) better than the runtime pipeline's `driver.save_screenshot` whole-window pattern.
- u1 (`discover` / `FrameRow` / CLI) and u2 (`_build_driver`) **unchanged**. Stale-detect / orphan categorization / manifest writer / coverage report still pending for u4-u6.
**verification**:
- `(Get-Content scripts/generate_frame_previews.py | Measure-Object -Line).Lines` → **88** (u3 add = 25 lines, ≤ 50 guardrail).
- `python scripts/generate_frame_previews.py --dry-run` → `discovered: total=33 with_index_html=20 with_preview_png=4` (unchanged from u1/u2 baseline at commit 56619a0 — u3 does not alter discovery output).
- `$env:PYTHONPATH = '...\scripts'; python -c "import generate_frame_previews as m; print('import_ok', hasattr(m,'_build_driver'), hasattr(m,'discover'), hasattr(m,'render_one'), hasattr(m,'main'))"` → `import_ok True True True True` (lazy-import design preserved; selenium not required at module-import time).
- `Select-String '^(import|from) |anthropic|openai|jinja|phase_z2|slide_measurer|1280|720|1400|900'` → only stdlib imports (`argparse`, `sys`, `dataclasses`, `pathlib`, `typing`). **No** `phase_z2` / `slide_measurer` / 1280 / 720 / 1400 / 900 substring anywhere in the script (including comments and docstrings).
- Scope: only `scripts/generate_frame_previews.py` modified. `git diff --name-only -- src/slide_measurer.py src/phase_z2_pipeline.py Front/vite.config.ts templates/phase_z2/frames tests` → empty (no tracked-file changes outside scope). Untracked `tests/matching/*` are pre-existing files unrelated to IMP-13 (visible in `git status` from session start).
- Manifest path `figma_to_html_agent/blocks/_preview_manifest.json` does not yet exist (confirmed earlier) — expected; written in u6.
**remaining_units**: [u4, u5, u6, u7]
**follow_up_issue_candidates**: none from this unit. (Stage 2 already flagged IMP-04 HTML gap + `data/figma_previews/index.json` parse failure as separate axes.)
rewind_target: continue_same"""
token = os.environ.get("GITEA_TOKEN")
if not token:
print("ERROR: GITEA_TOKEN unset")
sys.exit(1)
resp = requests.post(
"https://gitea.hmac.kr/api/v1/repos/Kyeongmin/C.E.L_Slide_test2/issues/13/comments",
headers={"Authorization": f"token {token}", "Content-Type": "application/json"},
json={"body": body},
timeout=30,
)
print("status", resp.status_code)
print("body[:300]", resp.text[:300])