Files
Aislo/resources/tester/test_device_drawer.py
T

201 lines
9.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""☰ 서랍 · 위 줄 걷기(PLAN_기기대응 6 · 7 · `app_shell.ts` · `ui_template_workflow_layout.ts`) — 실제 브라우저.
① 휴대폰 · 로그인 뒤 B 쪽 = 위 줄 걷힘(본문 위 끝 0) · ☰ 는 위 왼쪽 모서리(폭 36 · 손가락 높이 44) · 떠 있는 진행 판 없음
② ☰ 서랍 = 왼쪽에서 열림 · ☰ 는 서랍 위에 그대로 · 로고 · 홈 ─ 진행 단계 ─ 메뉴 ─ 언어 · 테마 · 로그인 · 터치 모드 차례
진행 단계는 진행 판의 **그 요소**(한 벌) · 지금 단계 강조 그대로 · 닫으면 제자리(진행 판)로 돌아감 · 단계 누름 = 이동 + 서랍 닫힘
③ 휴대폰 · 공개 쪽(A01) = 위 줄 그대로(본문 위 끝 64) · ☰ 는 위 줄 오른쪽
④ 데스크탑(1440 · 마우스) · 로그인 뒤 B 쪽 = 위 줄 걷힘 · ☰ 왼쪽 위 36×36 · 진행 판 없음 · 위 줄 항목이 모두 서랍에 · Esc 로 닫힘
⑤ 데스크탑 · 공개 쪽(A01) = 위 줄 그대로 · ☰ 없음
⑥ (352-4) 좌측 패널이 펼쳐진 동안 ☰ 는 제목 줄 앞 칸에 든 모양(테두리 · 바탕 · 그림자 없음 · 자리 8,8 그대로)
· 접으면 떠 있는 단추 · 서랍 첫 줄 로고 우측 · 프로젝트 이름 우측 끝 — 글로 봄(서버 없이)
"""
import json
import sys
from pathlib import Path
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parent))
import test_device_audit as audit # noqa: E402
OUTLET_TOP = "Math.round(document.getElementById('app-outlet').getBoundingClientRect().top)"
GROUPS = "[...document.querySelectorAll('.app-drawer > *')].map(e => e.className)"
BURGER = (
"(() => { const r = document.querySelector('.app-burger').getBoundingClientRect();"
" return [Math.round(r.left), Math.round(r.top), Math.round(r.width), Math.round(r.height),"
" Math.round(r.right)]; })()"
)
TITLE_ROW_CY = (
"(() => { const r = document.querySelector("
"'.ui-workflow-overlay__panel--title > .ui-workflow-overlay__header').getBoundingClientRect();"
" return Math.round(r.top + r.height / 2); })()"
)
PROGRESS_HIDDEN = (
"!document.querySelector('.ui-workflow-overlay__panel--progress').getClientRects().length"
)
LABELS = (
"(sel) => [...document.querySelectorAll(sel)].map(b => b.textContent.trim()).filter(Boolean)"
)
def _ctx(browser, cred, size):
spec = audit.SIZES[size]
ctx = browser.new_context(
viewport=spec["viewport"], has_touch=spec["touch"], is_mobile=spec["touch"]
)
audit._login(ctx, cred)
pid = audit._project_id(ctx)
ctx.add_init_script(f"localStorage.setItem('frd_current_project_id', {json.dumps(pid)})")
return ctx
@pytest.mark.skipif(not audit._server_up(), reason="sub1 화면 서버(5174) 꺼짐")
def test_drawer_holds_steps_and_header_folds():
from playwright.sync_api import sync_playwright
cred = json.loads((audit.ROOT / "tmp" / "aislo_cred.json").read_text(encoding="utf-8"))
with sync_playwright() as p:
browser = p.chromium.launch(channel="msedge", headless=True)
page = _ctx(browser, cred, "phone_390x844_touch").new_page()
audit._open(page, "b07-design-detail")
# ①
assert page.evaluate(OUTLET_TOP) == 0
burger = page.evaluate(BURGER)
assert burger[:4] == [8, 8, 36, 44], burger
assert page.evaluate(PROGRESS_HIDDEN)
# ②
page.evaluate(
"window.__steps = document.querySelector('.ui-workflow-overlay__panel--progress .ui-workflow-layout__steps')"
)
page.evaluate("document.querySelector('.app-burger').click()")
assert (
page.evaluate(
"Math.round(document.querySelector('.app-drawer').getBoundingClientRect().left)"
)
== 0
)
assert page.evaluate( # ☰ 는 서랍 위에서 그대로 눌림(다시 누르면 닫힘)
"document.elementFromPoint(26, 30) === document.querySelector('.app-burger')"
)
groups = page.evaluate(GROUPS)
order = [
next((k for k in ("brand", "steps", "site", "touch") if k in c), "settings")
for c in groups
]
assert order == ["brand", "steps", "site", "settings"], groups
assert page.evaluate(
"document.querySelector('.app-drawer__steps').firstElementChild === window.__steps"
)
active = page.evaluate(
"document.querySelector('.app-drawer__steps .ui-workflow-layout__step.is-active')?.textContent"
)
assert active and "상세" in active, active
# 378-1: 홈페이지 메뉴 = 접힘 기본 · summary 누름 = 펼침 + 서랍 열린 채 · 서랍 폭 < 패널 · 바탕 ≠ 패널
site = "document.querySelector('.app-drawer__site')"
assert page.evaluate(f"!{site}.open")
page.evaluate(f"{site}.querySelector('summary').click()")
assert page.evaluate(f"{site}.open")
assert page.evaluate(
"document.querySelector('.app-header').classList.contains('is-drawer-open')"
)
page.evaluate(f"{site}.querySelector('summary').click()")
assert page.evaluate(f"!{site}.open")
widths = page.evaluate(
"[document.querySelector('.app-drawer'),"
" document.querySelector('.ui-workflow-overlay__panel--title')]"
".map(e => Math.round(e.getBoundingClientRect().width))"
)
assert widths[0] <= 240 and widths[0] < widths[1], widths
bgs = page.evaluate(
"[document.querySelector('.app-drawer'),"
" document.querySelector('.ui-workflow-overlay__panel--title')]"
".map(e => getComputedStyle(e).backgroundColor)"
)
assert bgs[0] != bgs[1], bgs
page.evaluate("document.querySelector('.app-drawer__scrim').click()") # 닫기 = 제자리
assert page.evaluate(
"window.__steps.closest('.ui-workflow-overlay__panel--progress') !== null"
)
page.evaluate("document.querySelector('.app-burger').click()")
page.evaluate(
"[...document.querySelectorAll('.app-drawer__steps .ui-workflow-layout__step.is-enabled')]"
".find(b => b.textContent.includes('수량')).click()"
)
page.wait_for_function("location.hash.includes('b08-quantity')", timeout=10000)
assert not page.evaluate(
"document.querySelector('.app-header')?.classList.contains('is-drawer-open')"
)
# ③
audit._open(page, "a01-home")
assert page.evaluate(OUTLET_TOP) == 64
assert page.evaluate(BURGER)[4] >= 390 - 16
# ④
desk = _ctx(browser, cred, audit.DESKTOP).new_page()
audit._open(desk, "b07-design-detail")
assert desk.evaluate(OUTLET_TOP) == 0
assert desk.evaluate(BURGER)[:4] == [8, 8, 36, 36]
assert desk.evaluate(PROGRESS_HIDDEN)
# 389-1: ☰ 중심 = 좌측 패널 제목 줄 중심
assert desk.evaluate(TITLE_ROW_CY) == 26
head_nav = desk.evaluate(LABELS, ".app-nav button")
head_actions = desk.evaluate(LABELS, ".app-actions button")
assert head_nav and head_actions
desk.click(".app-burger")
assert desk.evaluate(LABELS, ".app-drawer__nav button") == head_nav
drawer_all = desk.evaluate(LABELS, ".app-drawer button")
assert all(label in drawer_all for label in head_actions), (head_actions, drawer_all)
assert desk.evaluate(
"document.querySelector('.app-drawer__steps .ui-workflow-layout__step.is-active') !== null"
)
desk.keyboard.press("Escape")
assert not desk.evaluate(
"document.querySelector('.app-header').classList.contains('is-drawer-open')"
)
# ⑤
audit._open(desk, "a01-home")
assert desk.evaluate(OUTLET_TOP) == 64
assert not desk.evaluate("document.querySelector('.app-burger').getClientRects().length")
browser.close()
def test_352_4_burger_in_panel_title_row_text():
root = Path(__file__).resolve().parents[2]
shell = (root / "A00_Common/app_shell.ts").read_text(encoding="utf-8")
open_panel = (
"html.is-bm-route:has(.ui-workflow-overlay__panel--title:not(.is-collapsed)) .app-burger {"
)
assert open_panel in shell # 패널 펼침 = 제목 줄에 든 모양
body = shell.split(open_panel, 1)[1].split("}", 1)[0]
for line in ("border-color: transparent;", "background: transparent;", "box-shadow: none;"):
assert line in body
# 자리(8,8 · 36)는 그대로 — 접으면 아래 기본 규칙(떠 있는 단추)으로 돌아감
base = shell.split("html.is-bm-route .app-burger {", 1)[1].split("}", 1)[0]
assert "position: fixed;" in base and "left: var(--spacing-8);" in base
# 389-1: 마우스 제목 줄 높이 = 8×2 + ☰ 높이(36) = 52 → 중심 26 = ☰ 중심
overlay_css = (root / "ui_template/ui_template_overlay.css").read_text(encoding="utf-8")
title_row = overlay_css.split(
"html.is-bm-route .ui-workflow-overlay__panel--title > .ui-workflow-overlay__header {", 1
)[1].split("}", 1)[0]
assert "min-height: calc(var(--spacing-8) * 2 + var(--app-burger-w));" in title_row
# 389-2: 서랍 8/12 체계 — 묶음 사이 12 + 선 + 12 · 로고 줄 = ☰ 높이 가운데
assert (
"gap: var(--spacing-12);" in shell.split(".app-header.is-drawer-open .app-drawer {", 1)[1]
)
assert "padding-top: var(--spacing-12);" in shell.split(".app-drawer__group + ", 1)[1]
assert (
"min-height: var(--app-burger-w);"
in shell.split("html.is-bm-route .app-drawer__brand {", 1)[1]
)
assert "align-self: flex-end" not in shell
# 378-1: 프로젝트 화면 서랍 오른쪽 가장자리 = 강조색 2 px
assert "border-right: 2px solid var(--color-accent);" in shell
overlay = (root / "ui_template/ui_template_overlay.css").read_text(encoding="utf-8")
project = overlay.split(".ui-workflow-overlay__project {", 1)[1].split("}", 1)[0]
assert "margin-left: auto;" in project