feat: strengthen design skill and refresh all showcases
Some checks failed
ci / build (push) Has been cancelled
Some checks failed
ci / build (push) Has been cancelled
This commit is contained in:
parent
69e5cc1efd
commit
e09d4efb1c
257 changed files with 8196 additions and 2374 deletions
|
|
@ -769,7 +769,7 @@ defineScenario("철판클럽 공개 기능", "영업 종료 매장 선택 경계
|
|||
await opened.page.click('[data-select-store="yeonnam"]');
|
||||
t.check("목록과 지도 연남 선택", "yeonnam selected in both", await opened.page.evaluate(() => ({ card: document.querySelector('[data-store].is-selected')?.dataset.store, pin: document.querySelector('[data-map-store].is-active')?.dataset.mapStore })), (actual) => actual.card === "yeonnam" && actual.pin === "yeonnam");
|
||||
t.includes("종료 상태 요약", "영업 종료", await textOf(opened.page, "#summary-store-state"));
|
||||
t.check("저장 행동 차단과 이유", "disabled / choose another store", await opened.page.$eval("#save-builder", (element) => ({ disabled: element.disabled, text: element.textContent.trim() })), (actual) => actual.disabled && actual.text.includes("다른 매장"));
|
||||
t.check("가상 매장 안내 행동", "#stores / 가상 매장 안내 보기", await opened.page.$eval("#check-store-link", (element) => ({ href: element.getAttribute("href"), text: element.textContent.trim() })), (actual) => actual.href === "#stores" && actual.text.includes("가상 매장 안내"));
|
||||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
|
|
@ -794,25 +794,24 @@ defineScenario("철판클럽 공개 기능", "매장 검색 빈 결과와 복구
|
|||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
defineScenario("철판클럽 공개 기능", "조합 저장 성공", 3, async (t) => {
|
||||
defineScenario("철판클럽 공개 기능", "조합 결과 즉시 반영과 미저장 안내", 3, async (t) => {
|
||||
const opened = await openChromium(burgerPublic);
|
||||
try {
|
||||
await opened.page.click("#save-builder");
|
||||
const snapshot = await opened.page.evaluate(() => JSON.parse(sessionStorage.getItem("griddle-club-demo-selection")));
|
||||
t.check("현재 탭에 조합 스냅샷 저장", "classic / patty 2 / seongsu", snapshot, (actual) => actual?.flavor === "classic" && actual?.patty === "2" && actual?.store === "seongsu");
|
||||
t.includes("실제 주문 미전송 안내", "실제 주문으로 전송되지 않습니다", await textOf(opened.page, "#save-status"));
|
||||
t.equal("성공 상태 오류 스타일 없음", false, await opened.page.$eval("#save-status", (element) => element.classList.contains("is-error")));
|
||||
await opened.page.select('select[name="onion"]', "extra");
|
||||
t.includes("조합 결과 즉시 반영", "양파 많이", await textOf(opened.page, "#summary-lines"));
|
||||
t.equal("선택 내용은 브라우저에 저장하지 않음", null, await opened.page.evaluate(() => sessionStorage.getItem("griddle-club-demo-selection")));
|
||||
t.includes("주문 미제공 안내", "주문과 결제는 진행되지 않습니다", await textOf(opened.page, ".truth-inline"));
|
||||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
defineScenario("철판클럽 공개 기능", "조합 저장 실패와 입력 보존", 3, async (t) => {
|
||||
const opened = await openChromium(burgerPublic, { query: "?fixture=save-fail" });
|
||||
defineScenario("철판클럽 공개 기능", "선택 결과에서 가상 매장 안내로 이동", 3, async (t) => {
|
||||
const opened = await openChromium(burgerPublic);
|
||||
try {
|
||||
await opened.page.select('select[name="onion"]', "extra");
|
||||
await opened.page.click("#save-builder");
|
||||
t.includes("저장 실패 안내", "남기지 못했어요", await textOf(opened.page, "#save-status"));
|
||||
t.equal("저장 실패 오류 스타일", true, await opened.page.$eval("#save-status", (element) => element.classList.contains("is-error")));
|
||||
t.check("실패 뒤 조합과 저장소 상태", "onion extra retained / no snapshot", await opened.page.evaluate(() => ({ onion: document.querySelector('select[name="onion"]')?.value, stored: sessionStorage.getItem("griddle-club-demo-selection") })), (actual) => actual.onion === "extra" && actual.stored === null);
|
||||
await opened.page.click("#check-store-link");
|
||||
await opened.page.waitForFunction(() => window.location.hash === "#stores");
|
||||
t.equal("가상 매장 안내 앵커 이동", "#stores", await opened.page.evaluate(() => window.location.hash));
|
||||
t.ok("가상 매장 안내 섹션이 보임", await visible(opened.page, "#stores"));
|
||||
t.equal("이동 뒤에도 선택 내용을 저장하지 않음", null, await opened.page.evaluate(() => sessionStorage.getItem("griddle-club-demo-selection")));
|
||||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
|
|
@ -932,7 +931,7 @@ defineScenario("철판클럽 가맹 기능", "문의 준비 실패와 재시도"
|
|||
await opened.page.click("#demo-consent");
|
||||
await opened.page.click("#submit-inquiry");
|
||||
await new Promise((resolve) => setTimeout(resolve, 520));
|
||||
t.includes("제출 실패 이유", "바꾸지 못했어요", await textOf(opened.page, "#submit-state"));
|
||||
t.includes("제출 실패 이유", "확인할 수 없어요", await textOf(opened.page, "#submit-state"));
|
||||
t.check("재시도 버튼 복구", "enabled / 다시 시도하기", await opened.page.$eval("#submit-inquiry", (element) => ({ disabled: element.disabled, text: element.textContent.trim() })), (actual) => !actual.disabled && actual.text === "다시 시도하기");
|
||||
t.check("실패 뒤 입력과 단계 보존", "step 3 / name retained", await opened.page.evaluate(() => ({ step: document.querySelector(".form-step.is-current")?.dataset.step, name: document.querySelector("#demo-name")?.value })), (actual) => actual.step === "3" && actual.name === "예시점주");
|
||||
} finally { await closePage(opened.page); }
|
||||
|
|
@ -946,14 +945,14 @@ defineScenario("한남자리 관리자 기능", "초기 선택과 조사관 동
|
|||
const row = document.querySelector('[data-queue-row].is-selected');
|
||||
return { id: row?.dataset.id, selected: row?.getAttribute("aria-selected") };
|
||||
}), (actual) => actual.id === "DEMO-HJ-101" && actual.selected === "true");
|
||||
t.check("조사관 제목과 식별자 동기화", "한남 생활권 정원 주거 / DEMO-HJ-101", await opened.page.evaluate(() => ({
|
||||
t.check("상세 정보 제목과 식별자 동기화", "한남 생활권 정원 주거 / 자료번호 101", await opened.page.evaluate(() => ({
|
||||
title: document.querySelector("[data-inspector-title]")?.textContent.trim(),
|
||||
id: document.querySelector("[data-inspector-id]")?.textContent.trim(),
|
||||
})), (actual) => actual.title === "한남 생활권 정원 주거" && actual.id.startsWith("DEMO-HJ-101"));
|
||||
t.check("초기 대기열 원장", "6 rows / 6개 예시", await opened.page.evaluate(() => ({
|
||||
})), (actual) => actual.title === "한남 생활권 정원 주거" && actual.id.startsWith("자료번호 101"));
|
||||
t.check("초기 대기열 원장", "6 rows / 6건", await opened.page.evaluate(() => ({
|
||||
rows: document.querySelectorAll("[data-queue-row]").length,
|
||||
count: document.querySelector("[data-result-count]")?.textContent.trim(),
|
||||
})), (actual) => actual.rows === 6 && actual.count === "6개 예시");
|
||||
})), (actual) => actual.rows === 6 && actual.count === "6건");
|
||||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
|
|
@ -993,10 +992,10 @@ defineScenario("한남자리 관리자 기능", "행 선택 전환", 3, async (t
|
|||
previous: document.querySelector('[data-queue-row][data-id="DEMO-HJ-101"]')?.getAttribute("aria-selected"),
|
||||
selectedCount: document.querySelectorAll("[data-queue-row].is-selected").length,
|
||||
})), (actual) => actual.next === "true" && actual.previous === "false" && actual.selectedCount === 1);
|
||||
t.check("선택 제목과 상태 조사관 반영", "한강 가까운 복층 주거 / 쇼케이스 공개", await opened.page.evaluate(() => ({
|
||||
t.check("선택 제목과 상태 상세 정보 반영", "한강 가까운 복층 주거 / 예시 공개", await opened.page.evaluate(() => ({
|
||||
title: document.querySelector("[data-inspector-title]")?.textContent.trim(),
|
||||
status: document.querySelector("[data-inspector-status]")?.textContent.trim(),
|
||||
})), (actual) => actual.title === "한강 가까운 복층 주거" && actual.status === "쇼케이스 공개");
|
||||
})), (actual) => actual.title === "한강 가까운 복층 주거" && actual.status === "예시 공개");
|
||||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
|
|
@ -1006,10 +1005,10 @@ defineScenario("한남자리 관리자 기능", "검색 일치 결과", 3, async
|
|||
await setValue(opened.page, "[data-queue-search]", "남산");
|
||||
t.equal("검색 결과 한 행", 1, await opened.page.$$eval("[data-queue-row]:not(.is-hidden)", (rows) => rows.length));
|
||||
t.equal("검색 결과 식별자", "DEMO-HJ-105", await opened.page.$eval("[data-queue-row]:not(.is-hidden)", (row) => row.dataset.id));
|
||||
t.check("검색 결과 수와 빈 상태", "1개 예시 / empty hidden", await opened.page.evaluate(() => ({
|
||||
t.check("검색 결과 수와 빈 상태", "1건 / empty hidden", await opened.page.evaluate(() => ({
|
||||
count: document.querySelector("[data-result-count]")?.textContent.trim(),
|
||||
empty: document.querySelector("[data-queue-empty]")?.hidden,
|
||||
})), (actual) => actual.count === "1개 예시" && actual.empty);
|
||||
})), (actual) => actual.count === "1건" && actual.empty);
|
||||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
|
|
@ -1017,11 +1016,11 @@ defineScenario("한남자리 관리자 기능", "검색 빈 상태와 초기화
|
|||
const opened = await openChromium(estateAdmin);
|
||||
try {
|
||||
await setValue(opened.page, "[data-queue-search]", "없는 매물");
|
||||
t.check("검색 빈 상태 원인 안내", "0개 예시 / 현재 조건", await opened.page.evaluate(() => ({
|
||||
t.check("검색 빈 상태 원인 안내", "0건 / 현재 조건", await opened.page.evaluate(() => ({
|
||||
count: document.querySelector("[data-result-count]")?.textContent.trim(),
|
||||
title: document.querySelector("[data-empty-title]")?.textContent.trim(),
|
||||
visible: !document.querySelector("[data-queue-empty]")?.hidden,
|
||||
})), (actual) => actual.count === "0개 예시" && actual.visible && actual.title.includes("현재 조건"));
|
||||
})), (actual) => actual.count === "0건" && actual.visible && actual.title.includes("현재 조건"));
|
||||
t.equal("빈 검색에서 보이는 행 없음", 0, await opened.page.$$eval("[data-queue-row]:not(.is-hidden)", (rows) => rows.length));
|
||||
await opened.page.click("[data-reset-filter]");
|
||||
t.check("필터 초기화로 전체 복구", "blank / all / 6 rows", await opened.page.evaluate(() => ({
|
||||
|
|
@ -1039,7 +1038,7 @@ defineScenario("한남자리 관리자 기능", "검수 필요 상태 필터", 3
|
|||
const result = await opened.page.$$eval("[data-queue-row]:not(.is-hidden)", (rows) => rows.map((row) => row.dataset.id));
|
||||
t.equal("검수 필요 결과 수", 2, result.length);
|
||||
t.check("검수 필요 식별자 집합", "DEMO-HJ-101, DEMO-HJ-106", result, (actual) => actual.join(",") === "DEMO-HJ-101,DEMO-HJ-106");
|
||||
t.equal("상태 필터 결과 문구", "2개 예시", await textOf(opened.page, "[data-result-count]"));
|
||||
t.equal("상태 필터 결과 문구", "2건", await textOf(opened.page, "[data-result-count]"));
|
||||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
|
|
@ -1077,12 +1076,12 @@ defineScenario("한남자리 관리자 기능", "강제 빈 대기열과 복구"
|
|||
try {
|
||||
await opened.page.select("[data-state-simulator]", "empty");
|
||||
t.ok("강제 빈 대기열 노출", await visible(opened.page, "[data-queue-empty]"));
|
||||
t.includes("강제 빈 상태 설명", "아직 접수된", await textOf(opened.page, "[data-empty-title]"));
|
||||
t.includes("강제 빈 상태 설명", "아직 표시할", await textOf(opened.page, "[data-empty-title]"));
|
||||
await opened.page.select("[data-state-simulator]", "normal");
|
||||
t.check("정상 선택으로 빈 상태 해제", "empty hidden / 6개 예시", await opened.page.evaluate(() => ({
|
||||
t.check("정상 선택으로 빈 상태 해제", "empty hidden / 6건", await opened.page.evaluate(() => ({
|
||||
empty: document.querySelector("[data-queue-empty]")?.hidden,
|
||||
count: document.querySelector("[data-result-count]")?.textContent.trim(),
|
||||
})), (actual) => actual.empty && actual.count === "6개 예시");
|
||||
})), (actual) => actual.empty && actual.count === "6건");
|
||||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
|
|
@ -1125,11 +1124,11 @@ defineScenario("한남자리 관리자 기능", "버전 충돌 저장 실패와
|
|||
try {
|
||||
await opened.page.select("[data-state-simulator]", "conflict");
|
||||
await opened.page.$eval("[data-simulate-save]", (button) => button.click());
|
||||
t.equal("충돌 저장 실패 배너", "버전 충돌로 저장하지 않았습니다.", await textOf(opened.page, "[data-banner-title]"));
|
||||
t.equal("충돌 저장 실패 배너", "최신 자료와 차이가 있어 저장하지 않았습니다.", await textOf(opened.page, "[data-banner-title]"));
|
||||
t.includes("충돌 저장 실패 라이브 안내", "저장하지 않았습니다", await textOf(opened.page, "[data-admin-live]"));
|
||||
await opened.page.select("[data-state-simulator]", "normal");
|
||||
await opened.page.$eval("[data-simulate-save]", (button) => button.click());
|
||||
t.includes("정상 재시도는 외부 저장 없음", "실제 저장하지 않았습니다", await textOf(opened.page, "[data-admin-live]"));
|
||||
t.includes("정상 재시도는 외부 저장 없음", "실제로 저장되거나 전송되지는 않습니다", await textOf(opened.page, "[data-admin-live]"));
|
||||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
|
|
@ -1204,7 +1203,7 @@ defineScenario("한남자리 관리자 기능", "AI 주장 검토 완료", 3, as
|
|||
badge: document.querySelector("#inspector-ai .status-badge")?.textContent.trim(),
|
||||
pass: document.querySelector("#inspector-ai .status-badge")?.classList.contains("status-pass"),
|
||||
})), (actual) => actual.disabled && actual.text === "수정 후 승인됨" && actual.badge === "수정 후 승인" && actual.pass);
|
||||
t.includes("AI 검토 라이브 안내", "데모 외부에는 게시하지 않았습니다", await textOf(opened.page, "[data-admin-live]"));
|
||||
t.includes("AI 검토 라이브 안내", "실제 광고에는 사용되지 않습니다", await textOf(opened.page, "[data-admin-live]"));
|
||||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
|
|
@ -1224,7 +1223,7 @@ defineScenario("한남자리 관리자 기능", "새 예시 초안 생성", 3, a
|
|||
title: document.querySelector("[data-inspector-title]")?.textContent.trim(),
|
||||
price: document.querySelector("[data-basic-grid] dd")?.textContent.trim(),
|
||||
count: document.querySelector("[data-result-count]")?.textContent.trim(),
|
||||
})), (actual) => actual.title === "제목 없는 새 예시 초안" && actual.price === "미선택" && actual.count === "7개 예시");
|
||||
})), (actual) => actual.title === "제목 없는 새 항목" && actual.price === "미선택" && actual.count === "7건");
|
||||
} finally { await closePage(opened.page); }
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue