| name | sis-verifier |
| description | Verify Streamlit in Snowflake (SiS) app deployment automatically by attaching to chromux's CDP port and driving the cross-origin iframe directly. Use after `snow streamlit deploy` succeeds, BEFORE asking the user to confirm. Detects render errors, exercises buttons via CDP, scrolls iframe content, and validates each checkpoint with screenshots. |
sis-verifier
์๋ํ๋ SiS(Streamlit in Snowflake) ์ฑ ๊ฒ์ฆ ์คํฌ. ๋ฐฐํฌ ํ ์ฌ์ฉ์์๊ฒ "ํ์ธํด์ฃผ์ธ์" ๋ผ๊ณ ๋ฌป๊ธฐ ์ ์ ํธ์ถํ๋ค.
When to Use
ํธ์ถ ํธ๋ฆฌ๊ฑฐ (์ ์กฐ๊ฑด ๋ชจ๋ ๋ง์กฑ):
snow streamlit deploy ๋๋ ๋๋ฑํ SiS ๋ฐฐํฌ ๋ช
๋ น์ด ์ฑ๊ณต
- ๊ฒ์ฆํ ๋ฐ๋ชจ ์๋๋ฆฌ์ค๊ฐ ๋ช
ํํจ (์: ์
๋ ฅ๊ฐ, ํด๋ฆญํ ๋ฒํผ, ํ์ธํ ๊ฒฐ๊ณผ ์์ญ)
- chromux๊ฐ ์ฌ์ฉ ์ค์ธ Chrome ํ๋กํ์ Snowflake ๋ก๊ทธ์ธ ์ํ๊ฐ ์ ์ง๋จ
ํธ์ถํ์ง ๋ง ๊ฒ:
- ์ผ๋ฐ ์น์ฑ (SiS ์๋ Streamlit) โ ๊ทธ๊ฑด ์ผ๋ฐ chromux๋ก ์ถฉ๋ถ
- ๋ก๊ทธ์ธ ํ๋ฉด ์์ฒด ๊ฒ์ฆ โ
logged-in-browser-research ์ฌ์ฉ
- ์ฌ์ฉ์๊ฐ ์ด๋ฏธ ๋ธ๋ผ์ฐ์ ์์ ์ง์ ํ์ธ ์ค
Why this skill exists
SiS ์ฑ์ cross-origin iframe (*.awsapnortheast2.snowflake.app) ์์์ ๋์ํ๋ค. ๋ถ๋ชจ ํ์ด์ง ์
์ฅ์์๋ iframe ์์ DOM์ด ์ฐจ๋จ๋๋ฏ๋ก chromux์ ํ์ค click @ref/fill @ref๋ก๋ ์ธํฐ๋์
๋ถ๊ฐ. ์ํ์ฐฉ์ค๋ก ~30๋ถ ์์ ํจํด๋ค:
- โ
iframe.contentDocument JS ์ ๊ทผ โ cross-origin block
- โ Tab ํค ๋ค๋น๊ฒ์ด์
โ iframe ์์ฒด์๋ ํฌ์ปค์ค ์กํ์ง๋ง ์์ชฝ ์ ํ ์ ๋จ
- โ cliclick ์ขํ ํด๋ฆญ โ AppleScript ๊ถํ + Chrome window OS ์ขํ ๋ณํ ๋ฌธ์
- โ chromux snapshot @ref โ iframe ์์ชฝ์
presentation ๋
ธ๋๋ง ๋
ธ์ถ
ํด๊ฒฐ์ฑ
: CDP๊ฐ ๊ฐ cross-origin iframe์ ๋ณ๊ฐ target์ผ๋ก ๋
ธ์ถํ๋ค. iframe target์ ์ง์ WebSocket attachํ๋ฉด same-origin ํ๊ฒฝ์ด ๋์ด ๋ชจ๋ CDP ๋ช
๋ น์ด ๋์ํ๋ค.
Protocol (CP0~CP7)
| CP | ํญ๋ชฉ | ์๋ ๊ฐ๋ฅ | ๊ฒ์ฆ ๋ฐฉ๋ฒ |
|---|
| CP0 | ์ฑ ๋ก๋ (ํ์ด์ง 200, ํ์ดํ ์ผ์น) | โ
| chromux open + chromux snapshot ํ์ดํ ํ์ธ |
| CP1 | ์
๋ ฅ ํผ ๋ ๋ + ์๋ฌ ๋ฐฐ๋ 0๊ฐ | โ
| screenshot + iframe DOM์์ [role="alert"] count |
| CP2 | ๋ฉ์ธ ์ก์
๋ฒํผ ํด๋ฆญ | โ
| CDP Input.dispatchMouseEvent (iframe target์ attach) |
| CP3 | ๊ฒฐ๊ณผ ์์ญ 1๋จ ๋ ๋ (์: ์ถ์ฒ ๋ฆฌ์คํธ) | โ
| scroll + screenshot + DOM count |
| CP4 | ์ ํ ๊ฐ๋ฅํ ํญ๋ชฉ ํด๋ฆญ | โ
| CDP click ๋์ผ ๋ฐฉ๋ฒ |
| CP5 | ๊ฒฐ๊ณผ ์์ญ 2๋จ ๋ ๋ (์: ์ฐจํธ) | โ
| scroll + screenshot |
| CP6 | LLM/์ธ๋ถ ํธ์ถ ๊ฒฐ๊ณผ (ํ๊ตญ์ด ํ
์คํธ ๋ฑ) | โ
| iframe DOM์์ ๊ฒฐ๊ณผ ํ
์คํธ substring ๊ฒ์ฆ |
| CP7 | ๋ณด์กฐ ์
๋ ฅ์นธ (Mini-Agent ๋ฑ) ๋ ๋ | โ
| scroll + DOM ๊ฒ์ฆ |
๊ฐ ์ฒดํฌํฌ์ธํธ๋ helper ์คํฌ๋ฆฝํธ์ sub-command๋ก ํธ์ถํ๋ค.
Workflow
-
์ธ์
์ค๋น
chromux launch default ๋ก Chrome ๋์ฐ๊ธฐ (์ด๋ฏธ running์ด๋ฉด idempotent)
chromux open <session-name> <app-url> ๋ก SiS ์ฑ ์ด๊ธฐ
chromux wait <session-name> 8000 (SiS iframe ๋ก๋ ์๊ฐ ํ๋ณด)
-
CDP iframe target ๋ฐ๊ฒฌ
cdp_helper.py find โ http://localhost:9310/json ์์ type=iframe + url์ awsapnortheast ํฌํจ๋ target ์ฐพ๊ธฐ
- ์์ผ๋ฉด: ์ถ๊ฐ wait โ ๊ทธ๋๋ ์์ผ๋ฉด SiS๊ฐ ๋ก๋ ์ ๋ ๊ฒ โ CP0 FAIL ๋ณด๊ณ
-
CP0+CP1 (์๋)
chromux screenshot <session> + ์๊ฐ ํ์ธ
cdp_helper.py inspect โ iframe ์ ๋ฒํผ/์
๋ ฅ ์์ ์ขํ ์ธก์ + DOM ์นด์ดํธ
cdp_helper.py errors โ ์๋ฌ ๋ฐฐ๋ (.stAlert, [role="alert"]) ์นด์ดํธ
-
CP2~CP7 (์๋)
- ๋ฒํผ ํด๋ฆญ:
cdp_helper.py inspect ๋ก ์ขํ ์ธก์ โ cdp_helper.py click <x> <y> ๋ก ํด๋ฆญ
- ๊ฒฐ๊ณผ ๋๊ธฐ: ์ฒ๋ฆฌ ์๊ฐ (Forecast/LLM ๋ฑ ๋ฌด๊ฑฐ์ด ํธ์ถ์ ~30s) sleep ํ screenshot
- ์คํฌ๋กค: SiS๋
section.main ์ด scroll ์ปจํ
์ด๋. cdp_helper.py scroll <px> ๋ก scrollTop ์ค์
- DOM ๊ฒ์ฆ:
cdp_helper.py inspect <selector> ๋ก ํน์ element ์กด์ฌ ํ์ธ
-
์คํจ ์
- 1~2ํ ์์ฒด ์์ ์๋ (์ขํ ๋น๋๊ฐ โ ๋ค์ inspect โ ์ ํํ ์ขํ๋ก click)
- ๊ทธ๋๋ ์คํจ โ ์๋ ์ด๋ ฅ๊ณผ ๋ง์ง๋ง screenshot์ ์ฒจ๋ถํด ์ฌ์ฉ์ ๋ณด๊ณ
findings.md ๋๋ ๋๋ฑํ ๋ฐ๊ฒฌ ๋ก๊ทธ์ ํจํด ์ถ๊ฐ
Helper script
cdp_helper.py โ ์ด ์คํฌ ๋๋ ํ ๋ฆฌ์ ๋๋ด. ์ฌ์ฉ ์:
python3 ~/.claude/skills/sis-verifier/cdp_helper.py find
python3 ~/.claude/skills/sis-verifier/cdp_helper.py buttons
python3 ~/.claude/skills/sis-verifier/cdp_helper.py click 724 473
python3 ~/.claude/skills/sis-verifier/cdp_helper.py query "section.main h2"
python3 ~/.claude/skills/sis-verifier/cdp_helper.py scroll 800
python3 ~/.claude/skills/sis-verifier/cdp_helper.py text-contains "AI ๋ถ์ ์์ฝ"
helper๋ chromux 9310 ํฌํธ์ CDP์ ์๋ attach. iframe target์ url substring์ผ๋ก ์๋ณ (๊ธฐ๋ณธ: awsapnortheast).
Dependencies
chromux (์ด๋ฏธ ์ฌ์ฉ ์ค์ธ ํ๊ฒฝ ์ ์ )
- Python 3 +
websocket-client โ ์์ผ๋ฉด pip3 install --user websocket-client (system pip์ --break-system-packages ์ต์
์์)
Gotchas (์ฌ๋ฐ๊ฒฌ ๋น์ฉ ์ ๊ฐ)
| ํจ์ | ์ฆ์ | ํํผ |
|---|
| ๋ถ๋ชจ page WS์ click dispatch | dispatch๋ OK ์๋ต์ด์ง๋ง hit-test ์คํจ (UI ๋ณํ ์์) | iframe target์ WS์ attachํด์ผ ํจ |
| iframe-local ์ขํ โ viewport ์ขํ | ์ขํ ๋น๋๊ฐ | Runtime.evaluate๋ก element rect ์ง์ ์ธก์ |
window.scrollTo ๊ฐ ์ ๋จนํ | scrollY=0 ๊ทธ๋๋ก | Streamlit์ section.main ์ด scroll ์ปจํ
์ด๋ โ ๊ทธ๊ฒ์ scrollTop ์ค์ |
pip3 install websocket-client ๊ฐ audit๋ง ํจ | ImportError ์ง์ | --user ํ๋๊ทธ + --quiet |
cliclick ์ขํ ๋ณํ ์๋ | ์๊ฐ ๋ญ๋น | ์ฌ์ฉ ๊ธ์ง. CDP๊ฐ ๋ ๊น๋ |
| chromux snapshot์ iframe ๋ด๋ถ ์ ๋ณด์ | presentation ๋
ธ๋๋ง | ์ ์. iframe target์ ์ง์ attachํ๋ฉด ๋จ |
| cross-origin iframe target ๋ชป ์ฐพ์ | find ๊ฒฐ๊ณผ ๋น ๋ฐฐ์ด | URL substring ๋ค๋ฅผ ์ ์์ (region๋ณ). ๊ธฐ๋ณธ awsapnortheast, ํ์ ์ ์ธ์ ๋ณ๊ฒฝ |
| ์ฒ์ ํด๋ฆญ์ด ๋น๋๊ฐ (์ขํ ์ถ์ ์ค์ฐจ) | UI ๋ณํ ์์ | inspect๋ก ์ธก์ ํ ์ ํํ ์ขํ ์ฌ์ฉ โ ์ถ์ (686,438) โ ์ธก์ (724,473), 38px ์ค์ฐจ |
Output expectations
์ด ์คํฌ์ ํธ์ถํ ๋ถ๋ชจ ์ปจํ
์คํธ๋ ๋ค์์ ๋ฐ๋๋ค:
## SiS Verification Report
- App URL: ...
- Status: PASS / FAIL
- Checkpoints:
- CP0 โ
load
- CP1 โ
form rendered, 0 errors
- CP2 โ
click main action
- CP3 โ
Step1 result rendered (5 items)
- ...
- Screenshots: /tmp/sis_*.png
- Issues: [if any]
- Next: [user action needed / proceed to next phase]
Lifecycle
์ด ์คํฌ์ ํ ์ธ์
์์ ์ฌ๋ฌ ๋ฒ ํธ์ถ ๊ฐ๋ฅ (์ฌ๋ฐฐํฌ ํ ์ฌ๊ฒ์ฆ). ๋งค๋ฒ ์ chromux session ์ด๋ฆ์ ์ฌ์ฉํ์ง ๋ง๊ณ ๊ฐ์ ์ด๋ฆ ์ฌ์ฌ์ฉ ๊ถ์ฅ (verify ๊ฐ์ ๋จ์ ์ด๋ฆ).
References
references/protocol.md โ ์ฒดํฌํฌ์ธํธ ์์ธ + ๋ฐ๋ชจ ์๋๋ฆฌ์ค ์์
references/troubleshooting.md โ ์๋ ค์ง ์คํจ ํจํด + ํด๊ฒฐ๋ฒ