Merge remote-tracking branch 'origin/sub_laptop_4' into main_laptop_1 — 588 단축키 등록부 · UI_Edit 충돌(sub1 고르기 · 속성 판 + sub4 keyIs) 양쪽 살림
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
* CAD 설정 배선(PLAN 332-3) — ☰ [설정] 휠 확대 방향 · 내 별칭(`A00_Common/input_prefs.ts`).
|
||||
* 휠 = 기본 밂(앞으로 굴리면 확대 · 오토캐드 · 337) · 당김 저장 뒤 뒤집힘 · 핀치는 늘 벌리면 확대.
|
||||
* 별칭 = 명령 이름 > 내 별칭 > 기본 별칭 · 저장 즉시 따름.
|
||||
* 바꾼 키(588-3) = 새 키만 먹음 · 옛 키는 안 먹음 · 한글 자판도 자판 자리로.
|
||||
* 옮기기 버튼(588-4) = 오른쪽을 고르면 오른쪽 끌기로 화면 옮김 · 기본(가운데)이면 오른쪽 끌기는 안 옮김.
|
||||
* 실행: cd B07_DesignDetail/openwebcad && npx vitest run --dir ../../resources/tester/cad input-prefs-cad
|
||||
*/
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
@@ -11,7 +13,12 @@ import {
|
||||
matchCommandPrefixes,
|
||||
resolveCommandInput,
|
||||
} from "../../../B07_DesignDetail/openwebcad/src/commands/registry";
|
||||
import { getActiveToolActor } from "../../../B07_DesignDetail/openwebcad/src/state";
|
||||
import {
|
||||
getActiveToolActor,
|
||||
getPanStartLocation,
|
||||
getScreenCanvasDrawController,
|
||||
getSnapEnabled,
|
||||
} from "../../../B07_DesignDetail/openwebcad/src/state";
|
||||
import { initApplication } from "../../../B07_DesignDetail/openwebcad/test/helpers/init-application";
|
||||
|
||||
const store = new Map<string, string>();
|
||||
@@ -96,3 +103,64 @@ describe("내 별칭", () => {
|
||||
expect(getActiveToolActor()?.getSnapshot()?.context.type).toBe("RECTANGLE");
|
||||
});
|
||||
});
|
||||
|
||||
describe("바꾼 키(588-3)", () => {
|
||||
const key = (controller: ReturnType<typeof initApplication>, extra: Partial<KeyboardEvent>) =>
|
||||
controller.handleKeyStroke({
|
||||
key: "",
|
||||
code: "",
|
||||
keyCode: 0,
|
||||
isComposing: false,
|
||||
shiftKey: false,
|
||||
ctrlKey: false,
|
||||
altKey: false,
|
||||
metaKey: false,
|
||||
repeat: false,
|
||||
target: null,
|
||||
preventDefault: vi.fn(),
|
||||
stopPropagation: vi.fn(),
|
||||
...extra,
|
||||
} as unknown as KeyboardEvent);
|
||||
|
||||
it("스냅 F3 → Ctrl+Q — 새 키(한글 자판 「ㅂ」)만 켜고 끔 · F3 안 먹음", () => {
|
||||
const controller = initApplication();
|
||||
const before = getSnapEnabled();
|
||||
key(controller, { key: "F3", code: "F3" });
|
||||
expect(getSnapEnabled()).toBe(!before);
|
||||
savePrefs({ keys: { "cad.snap": ["Ctrl+Q"] } });
|
||||
key(controller, { key: "F3", code: "F3" });
|
||||
expect(getSnapEnabled()).toBe(!before);
|
||||
key(controller, { key: "ㅂ", code: "KeyQ", ctrlKey: true });
|
||||
expect(getSnapEnabled()).toBe(before);
|
||||
});
|
||||
});
|
||||
|
||||
describe("옮기기 버튼(588-4)", () => {
|
||||
const mouse = (button: number, x: number, y = 100) =>
|
||||
({
|
||||
button,
|
||||
clientX: x,
|
||||
clientY: y,
|
||||
shiftKey: false,
|
||||
ctrlKey: false,
|
||||
target: null,
|
||||
preventDefault: vi.fn(),
|
||||
stopPropagation: vi.fn(),
|
||||
}) as unknown as MouseEvent;
|
||||
const rightDrag = (controller: ReturnType<typeof initApplication>) => {
|
||||
const before = getScreenCanvasDrawController().getScreenOffset().clone();
|
||||
controller.handleMouseDown(mouse(2, 100));
|
||||
controller.handleMouseMove(mouse(2, 160));
|
||||
controller.handleMouseUp(mouse(2, 160));
|
||||
const after = getScreenCanvasDrawController().getScreenOffset();
|
||||
return Math.hypot(after.x - before.x, after.y - before.y);
|
||||
};
|
||||
|
||||
it("기본(가운데) = 오른쪽 끌기 안 옮김 · 오른쪽 고름 = 옮김 · 놓으면 끝", () => {
|
||||
const controller = initApplication();
|
||||
expect(rightDrag(controller)).toBe(0);
|
||||
savePrefs({ panButton: "right" });
|
||||
expect(rightDrag(controller)).toBeGreaterThan(0);
|
||||
expect(getPanStartLocation()).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -82,6 +82,7 @@ globalThis.ResizeObserver = class {
|
||||
const viewWindow = load(path.join(ROOT, "common_util", "common_util_view_window.ts"));
|
||||
const wheelMod = load(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Profile_Wheel.ts"), {
|
||||
"../common_util/common_util_view_window": viewWindow,
|
||||
"../A00_Common/input_prefs": load(path.join(ROOT, "A00_Common", "input_prefs.ts")),
|
||||
});
|
||||
const viewport = load(path.join(ROOT, "A00_Common", "design", "design_profile_viewport.ts"), {
|
||||
"../../B05_Profile/B05_Profile_UI_Profile_Wheel": wheelMod,
|
||||
|
||||
@@ -36,6 +36,11 @@ global.Element = Element;
|
||||
|
||||
const stubs = {
|
||||
"../A00_Common/touch_bridge": { wheelZoomsIn: () => true },
|
||||
"../A00_Common/input_prefs": {
|
||||
isPanButton: (b) => b === 1,
|
||||
PAN_MOVE_PX: 4,
|
||||
swallowNextMenu() {},
|
||||
},
|
||||
"../B04_PreProcess/B04_PreProcess_UI_MapRender": {
|
||||
computeMaxScale: () => 10,
|
||||
lonLatToScreen: () => ({ x: 0, y: 0 }),
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/* PLAN 588 지킴 헬퍼 — 단축키 등록부(`A00_Common/key_registry.ts`) · CAD 묶음 · 찾기(`app_settings_find.ts`)
|
||||
* 를 그 자리에서 트랜스파일해 Node 로 돌림. 가짜 localStorage 로 바꾼 키를 넣어 봄.
|
||||
* 결과 = 표준출력 JSON 한 벌. 짝 = `test_588_key_registry.py`. */
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
|
||||
|
||||
const ROOT = path.join(__dirname, "..", "..");
|
||||
const mods = {};
|
||||
function load(rel) {
|
||||
const js = ts.transpileModule(fs.readFileSync(path.join(ROOT, rel), "utf8"), {
|
||||
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
|
||||
}).outputText;
|
||||
const box = { exports: {} };
|
||||
const req = (p) => mods[path.basename(p)] ?? {};
|
||||
new Function("exports", "module", "require", js)(box.exports, box, req);
|
||||
return (mods[path.basename(rel, ".ts")] = box.exports);
|
||||
}
|
||||
load("A00_Common/input_prefs.ts");
|
||||
load("A00_Common/key_shortcut.ts");
|
||||
load("B07_DesignDetail/openwebcad/src/ribbon/ribbon.config.ts");
|
||||
const reg = load("A00_Common/key_registry.ts");
|
||||
const find = load("A00_Common/app_settings_find.ts");
|
||||
const catalog = require(
|
||||
path.join(ROOT, "B07_DesignDetail/openwebcad/src/commands/command-catalog.json"),
|
||||
);
|
||||
|
||||
const store = new Map();
|
||||
globalThis.localStorage = { getItem: (k) => (store.has(k) ? store.get(k) : null) };
|
||||
const setKeys = (keys) => store.set(mods.input_prefs.INPUT_PREFS_KEY, JSON.stringify({ keys }));
|
||||
|
||||
const ev = (key, code, extra = {}) => ({
|
||||
key,
|
||||
code,
|
||||
ctrlKey: false,
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
...extra,
|
||||
});
|
||||
const out = {};
|
||||
|
||||
// ① CAD 묶음 · 찾기
|
||||
const groups = find.cadCommandGroups(catalog.map((c) => c.id));
|
||||
out.groups = groups.map((g) => ({ label: g.label, n: g.ids.length }));
|
||||
out.groupIds = groups.flatMap((g) => g.ids);
|
||||
out.other = groups.find((g) => !g.label)?.ids ?? [];
|
||||
const hits = (q) =>
|
||||
catalog.filter((c) => find.matchesFind(q, [c.id, c.label, ...c.aliases])).map((c) => c.id);
|
||||
out.find = {
|
||||
sun: hits("선"),
|
||||
L: hits("L"),
|
||||
sunPl: hits("선 pl"),
|
||||
blank: hits(" ").length,
|
||||
none: hits("zzqq"),
|
||||
};
|
||||
|
||||
// ② 키 글
|
||||
out.chord = {
|
||||
hangulCtrlZ: reg.chordOf(ev("ㅋ", "KeyZ", { ctrlKey: true })),
|
||||
ctrlShiftZ: reg.chordOf(ev("Z", "KeyZ", { ctrlKey: true, shiftKey: true })),
|
||||
meta: reg.chordOf(ev("z", "KeyZ", { metaKey: true })),
|
||||
space: reg.chordOf(ev(" ", "Space")),
|
||||
shiftOnly: reg.chordOf(ev("Shift", "ShiftLeft", { shiftKey: true })),
|
||||
process: reg.chordOf(ev("Process", "")),
|
||||
f3: reg.chordOf(ev("F3", "F3")),
|
||||
shiftDigit: reg.chordOf(ev("!", "Digit1", { ctrlKey: true, shiftKey: true })),
|
||||
arrow: reg.chordOf(ev("ArrowUp", "ArrowUp", { shiftKey: true })),
|
||||
label: reg.keyLabel("Shift+ArrowUp"),
|
||||
};
|
||||
|
||||
// ③ 판정 — 기본 · 바꾼 키 · 못 바꾸는 줄은 바꾼 값 무시
|
||||
const del = ev("Delete", "Delete");
|
||||
out.keyIs = {
|
||||
delDefault: reg.keyIs(del, "plan.delete"),
|
||||
hangulUndo: reg.keyIs(ev("ㅋ", "KeyZ", { ctrlKey: true }), "plan.undo"),
|
||||
};
|
||||
setKeys({ "plan.delete": ["Ctrl+D"], "all.escape": ["Q"] });
|
||||
out.keyIs.delAfter = reg.keyIs(del, "plan.delete");
|
||||
out.keyIs.ctrlDAfter = reg.keyIs(ev("ㅇ", "KeyD", { ctrlKey: true }), "plan.delete");
|
||||
out.keyIs.fixedIgnored = reg.actionKeys("all.escape");
|
||||
out.keyIs.cadAction = reg.keyAction(ev("F7", "F7"), "cad");
|
||||
store.clear();
|
||||
|
||||
// ④ 겹침 검사
|
||||
const chk = (keys) => reg.checkKeys(keys);
|
||||
out.check = {
|
||||
none: chk({}),
|
||||
sameScope: chk({ "plan.delete": ["Ctrl+Z"] }),
|
||||
withAll: chk({ "plan.delete": ["Escape"] }),
|
||||
withLoupe: chk({ "plan.delete": ["Z"] }),
|
||||
otherPage: chk({ "plan.delete": ["F3"] }),
|
||||
reserved: chk({ "plan.delete": ["F5"] }),
|
||||
cadLetter: chk({ "cad.snap": ["Q"] }),
|
||||
cadShiftLetter: chk({ "cad.snap": ["Shift+Q"] }),
|
||||
cadCtrl: chk({ "cad.snap": ["Ctrl+Q"] }),
|
||||
samePage: chk({ "b05.undo": ["Enter"] }),
|
||||
swap: chk({ "plan.undo": ["Ctrl+Y"], "plan.redo": ["Ctrl+Z"] }),
|
||||
both: chk({ "plan.drawFinish": ["F2"], "plan.drawBack": ["F2"] }),
|
||||
};
|
||||
|
||||
// ⑤ 등록부 꼴
|
||||
out.actions = reg.KEY_ACTIONS.map((a) => ({
|
||||
id: a.id,
|
||||
scope: a.scope,
|
||||
keys: a.keys,
|
||||
fixed: !!a.fixed,
|
||||
}));
|
||||
out.scopes = Object.keys(reg.KEY_SCOPES);
|
||||
process.stdout.write(JSON.stringify(out));
|
||||
@@ -137,7 +137,7 @@ def test_되돌리기_배선_자유지정_먼저():
|
||||
panel = _read("B05_Profile/B05_Profile_UI_Profile_Panel_Tools.ts")
|
||||
assert 'tools.mode() === "free" ? (free.undo(), freeView.redraw()) : history.undo()' in panel
|
||||
assert 'tools.mode() === "free" ? free.canUndo() : history.canUndo()' in panel
|
||||
keys = panel[panel.index('isCtrlKey(event, "z") || isCtrlKey(event, "y")') :]
|
||||
keys = panel[panel.index('if (redo || keyIs(event, "b05.undo")) {') :] # 588-3 등록부
|
||||
free_at = keys.index('if (tools.mode() === "free") {')
|
||||
assert (
|
||||
free_at < keys.index("history.undo()")
|
||||
@@ -159,7 +159,7 @@ def test_도구줄_직선화_오른쪽_자유지정():
|
||||
def test_적용은_직선화와_같은_길_키_배선():
|
||||
panel = _read("B05_Profile/B05_Profile_UI_Profile_Panel_Tools.ts")
|
||||
assert "apply: (next) => ctx.applyEdits(next)" in panel
|
||||
assert 'tools.mode() === "free" && free.key(key)' in panel
|
||||
assert 'tools.mode() === "free" && freeKey && free.key(freeKey)' in panel
|
||||
profile = _read("A00_Common/design/design_profile.ts")
|
||||
# applyEdits = 캐시(store.replace) + 되돌리기 기록 — 자동저장 없음
|
||||
assert "store.replace(next);\n history.record();" in profile
|
||||
|
||||
@@ -47,7 +47,7 @@ def test_Ctrl_Z_는_사진첩_한_줄(out):
|
||||
|
||||
def test_종단도_Ctrl_Z_줄이_사진첩_하나():
|
||||
tools = _read("B05_Profile/B05_Profile_UI_Profile_Panel_Tools.ts")
|
||||
at = tools.index('if (isCtrlKey(event, "z") || isCtrlKey(event, "y")) {')
|
||||
at = tools.index('if (redo || keyIs(event, "b05.undo")) {') # 588-3 등록부
|
||||
assert (
|
||||
"undoOwner" not in tools and "history.undo()" in tools[at : at + 600]
|
||||
) # 367-3 자유지정 분기 앞에 섬
|
||||
|
||||
@@ -57,7 +57,7 @@ def test_다시하기는_앞으로(out) -> None:
|
||||
def test_단축키는_사진첩_한_곳():
|
||||
tools = (ROOT / "B05_Profile/B05_Profile_UI_Profile_Panel_Tools.ts").read_text(encoding="utf-8")
|
||||
assert "undoOwner" not in tools
|
||||
assert 'isCtrlKey(event, "y")' in tools and "setPageHistory(history)" in tools
|
||||
assert 'keyIs(event, "b05.redo")' in tools and "setPageHistory(history)" in tools # 588-3
|
||||
plan = (ROOT / "B05_Profile/B05_Profile_UI_RouteEdit_History.ts").read_text(encoding="utf-8")
|
||||
assert '"keydown"' not in plan
|
||||
assert not (ROOT / "B05_Profile/B05_Profile_UI_RouteEdit_UndoOwner.ts").exists()
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
"""PLAN 588 — 단축키 등록부 · 겹침 판정 · CAD 리본 묶음 · 찾기 (요구 445 C2 · C3).
|
||||
|
||||
· 등록부 = `A00_Common/key_registry.ts` — ☰ [설정] 표가 여기서 그려짐 · 바꿀 수 있는 줄은 코드가 부름
|
||||
· 키 글 = 한글 자판에서도 자판 자리로(Ctrl+ㅋ = Ctrl+Z) · 바꾼 키만 먹음 · 못 바꾸는 줄은 바꾼 값 무시
|
||||
· 겹침 = 같은 화면 자리끼리 · 「모든 화면」과 · 브라우저 몫 · CAD 글자 단독 — 다른 화면끼리는 같은 키 됨
|
||||
· CAD 묶음 = 리본 탭 › 패널 · 154 명령이 꼭 한 묶음 · 기타 여섯(리본에 없음)
|
||||
짝: `helper_588_key_registry.cjs`(실제 TS 를 Node 로 돌림).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
|
||||
HERE = os.path.dirname(__file__)
|
||||
ROOT = os.path.join(HERE, "..", "..")
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
not os.path.isdir(os.path.join(ROOT, "config", "node_modules")),
|
||||
reason="프론트엔드 의존성 미설치",
|
||||
)
|
||||
|
||||
|
||||
def _read(rel: str) -> str:
|
||||
with open(os.path.join(ROOT, rel), encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def r() -> dict:
|
||||
proc = subprocess.run( # noqa: S603 — 고정 실행 파일
|
||||
["node", os.path.join(HERE, "helper_588_key_registry.cjs")],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
timeout=60,
|
||||
)
|
||||
assert proc.returncode == 0, proc.stderr
|
||||
return json.loads(proc.stdout)
|
||||
|
||||
|
||||
def test_CAD_154_명령_꼭_한_묶음_기타_여섯(r):
|
||||
ids = r["groupIds"]
|
||||
assert len(ids) == 154 and len(set(ids)) == 154
|
||||
assert sorted(r["other"]) == ["LAYER", "PLACETABLE", "RECOVER", "REDO", "TOAREA", "UNDO"]
|
||||
assert r["groups"][0]["label"] == "홈 › 그리기"
|
||||
assert r["groups"][-1]["label"] == "" # 기타 이름은 화면 글(locale)
|
||||
|
||||
|
||||
def test_찾기_낱말_모두_대소문자_무시(r):
|
||||
f = r["find"]
|
||||
assert {"LINE", "PLINE"} <= set(f["sun"]) and {"LINE", "PLINE"} <= set(f["L"])
|
||||
assert "PLINE" in f["sunPl"] and "LINE" not in f["sunPl"] # 낱말 모두
|
||||
assert f["blank"] == 154 and f["none"] == []
|
||||
|
||||
|
||||
def test_키_글_한글_자판_안전(r):
|
||||
c = r["chord"]
|
||||
assert c["hangulCtrlZ"] == "Ctrl+Z"
|
||||
assert c["ctrlShiftZ"] == "Ctrl+Shift+Z"
|
||||
assert c["meta"] == "Ctrl+Z"
|
||||
assert c["space"] == "Space"
|
||||
assert c["shiftOnly"] == "" and c["process"] == ""
|
||||
assert c["f3"] == "F3"
|
||||
assert c["shiftDigit"] == "Ctrl+Shift+1"
|
||||
assert c["arrow"] == "Shift+ArrowUp" and c["label"] == "Shift+↑"
|
||||
|
||||
|
||||
def test_바꾼_키만_먹음_못_바꾸는_줄은_무시(r):
|
||||
k = r["keyIs"]
|
||||
assert k["delDefault"] is True and k["hangulUndo"] is True
|
||||
assert k["delAfter"] is False and k["ctrlDAfter"] is True
|
||||
assert k["fixedIgnored"] == ["Escape"]
|
||||
assert k["cadAction"] == "cad.grid"
|
||||
|
||||
|
||||
def test_겹침_판정(r):
|
||||
c = r["check"]
|
||||
assert c["none"] == {}
|
||||
assert c["sameScope"] == {"plan.delete": "dup"}
|
||||
assert c["withAll"] == {"plan.delete": "dup"}
|
||||
assert c["withLoupe"] == {"plan.delete": "dup"}
|
||||
assert c["otherPage"] == {} # D03 과 CAD 는 다른 화면
|
||||
assert c["reserved"] == {"plan.delete": "reserved"}
|
||||
assert c["cadLetter"] == {"cad.snap": "letter"}
|
||||
assert c["cadShiftLetter"] == {"cad.snap": "letter"}
|
||||
assert c["cadCtrl"] == {}
|
||||
assert c["samePage"] == {"b05.undo": "dup"} # B05 · B06 한 페이지 — 횡단 Enter 와 겹침
|
||||
assert c["swap"] == {} # 서로 바꿈은 됨
|
||||
assert c["both"] == {"plan.drawFinish": "dup", "plan.drawBack": "dup"}
|
||||
|
||||
|
||||
def test_등록부_꼴(r):
|
||||
ids = [a["id"] for a in r["actions"]]
|
||||
assert len(ids) == len(set(ids))
|
||||
for a in r["actions"]:
|
||||
assert a["scope"] in r["scopes"] and a["keys"]
|
||||
assert a["id"].startswith(a["scope"] + ".")
|
||||
|
||||
|
||||
# 바꿀 수 있는 줄 = 코드가 실제로 부름(등록부에만 있고 안 먹는 키 없음)
|
||||
WIRED = {
|
||||
"b05": "B05_Profile/B05_Profile_UI_Profile_Panel_Tools.ts",
|
||||
"profile": "B05_Profile/B05_Profile_UI_Profile_Panel_Tools.ts",
|
||||
"plan": "D03_PlanAnalysis",
|
||||
"cad": "B07_DesignDetail/openwebcad/src/inputController",
|
||||
}
|
||||
|
||||
|
||||
def _sources(rel: str) -> str:
|
||||
full = os.path.join(ROOT, rel)
|
||||
if os.path.isfile(full):
|
||||
return _read(rel)
|
||||
names = sorted(n for n in os.listdir(full) if n.endswith(".ts"))
|
||||
return "\n".join(_read(os.path.join(rel, n)) for n in names)
|
||||
|
||||
|
||||
def test_바꿀_수_있는_줄은_배선됨(r):
|
||||
for a in r["actions"]:
|
||||
if a["fixed"]:
|
||||
continue
|
||||
src = _sources(WIRED[a["scope"]])
|
||||
assert f'"{a["id"]}"' in src or f"'{a['id']}'" in src, a["id"]
|
||||
|
||||
|
||||
def test_손글_안내_지움_표는_등록부():
|
||||
assert "App_Settings_Keys_" not in _read("ui_template/ui_template_locale_common.ts")
|
||||
assert "App_Settings_Keys_" not in _read("A00_Common/app_settings.ts")
|
||||
|
||||
|
||||
# 588-4 — 화면 옮기기 자리는 모두 설정 버튼을 따름(가운데 고정 판정이 남지 않음)
|
||||
PAN_SITES = [
|
||||
"B05_Profile/B05_Profile_UI_RouteEdit_Input.ts", # B05 · B06 겹침 평면 · D03 지도
|
||||
"B07_DesignDetail/openwebcad/src/inputController/input-controller.ts",
|
||||
"A00_Common/b_svg_zoom_pan.ts",
|
||||
"B04_PreProcess/B04_PreProcess_UI_MapViewer.ts",
|
||||
"B04_PreProcess/B04_PreProcess_UI_Camera.ts",
|
||||
"B05_Profile/B05_Profile_UI_Drainage_Interact.ts",
|
||||
"B05_Profile/B05_Profile_UI_Profile_Wheel.ts",
|
||||
"B08_Quantity/B08_Quantity_UI_Milestone_Diagram.ts",
|
||||
"M02_MasterTemplete/DataFlow/M02_DF_Diagram.ts",
|
||||
"M02_MasterTemplete/M02_MasterTemplete_Labor_Diagram.ts",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("rel", PAN_SITES)
|
||||
def test_옮기기_자리는_설정_버튼(rel):
|
||||
src = _read(rel)
|
||||
assert "isPanButton(" in src or "isAuxPanButton(" in src, rel
|
||||
Reference in New Issue
Block a user