평가 및 화면 구조 정리
This commit is contained in:
parent
1248ae8ca4
commit
391639c1de
44 changed files with 5816 additions and 4501 deletions
|
|
@ -329,6 +329,108 @@ test.describe("teacher console", () => {
|
|||
await expectNoHorizontalOverflow(page);
|
||||
});
|
||||
|
||||
test("saves persona studio list rows as structured arrays @single-run", async ({ page }) => {
|
||||
type PersonaDraftSavePayload = {
|
||||
ccd: { automatic_thought: string[] };
|
||||
code: string;
|
||||
difficulty: string;
|
||||
display_name: string;
|
||||
is_synthetic: boolean;
|
||||
source_provenance: unknown;
|
||||
theory_target: string;
|
||||
triggers: { forbidden: string[]; sore_spots: string[] };
|
||||
};
|
||||
let savedPayload: PersonaDraftSavePayload | null = null;
|
||||
|
||||
await signInAsTeacher(page);
|
||||
await page.route("**/api/personas", (route) => {
|
||||
if (route.request().method() !== "GET") return route.fallback();
|
||||
return route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify([]) });
|
||||
});
|
||||
await page.route("**/api/personas/review", (route) => {
|
||||
if (route.request().method() !== "GET") return route.fallback();
|
||||
return route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify([]) });
|
||||
});
|
||||
await page.route("**/api/personas/drafts", async (route) => {
|
||||
if (route.request().method() !== "POST") return route.fallback();
|
||||
savedPayload = route.request().postDataJSON() as PersonaDraftSavePayload;
|
||||
await route.fulfill({
|
||||
status: 201,
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({
|
||||
persona_id: "00000000-0000-0000-0000-000000000703",
|
||||
code: savedPayload.code,
|
||||
version: 1,
|
||||
status: "draft",
|
||||
display_name: savedPayload.display_name,
|
||||
difficulty: savedPayload.difficulty,
|
||||
theory_target: savedPayload.theory_target,
|
||||
source_provenance: savedPayload.source_provenance,
|
||||
is_synthetic: savedPayload.is_synthetic,
|
||||
created_at: "2026-06-28T00:00:00Z",
|
||||
approved_at: null,
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto("/teach/personas");
|
||||
await page.getByLabel("표시 이름").fill("항목형 페르소나");
|
||||
|
||||
await page.getByRole("tab", { name: "임상" }).click();
|
||||
const automaticThoughts = page.locator(".ps-list-field").filter({ hasText: "자동사고" });
|
||||
await automaticThoughts.getByRole("textbox", { name: "자동사고 1", exact: true }).fill("삭제될 자동사고");
|
||||
await automaticThoughts.getByRole("button", { name: "항목 추가" }).click();
|
||||
await automaticThoughts.getByRole("textbox", { name: "자동사고 2", exact: true }).fill("남길 자동사고");
|
||||
await automaticThoughts.getByRole("button", { name: "자동사고 1 삭제" }).click();
|
||||
|
||||
await page.getByRole("tab", { name: "안전" }).click();
|
||||
const forbidden = page.locator(".ps-list-field").filter({ hasText: "상담자 금기" });
|
||||
await forbidden.getByRole("textbox", { name: "상담자 금기 1", exact: true }).fill("네가 예민한 거라고 단정");
|
||||
|
||||
await page.getByRole("button", { name: "초안 저장" }).click();
|
||||
await expect(page.getByText("P1 v1 초안을 저장했습니다.")).toBeVisible();
|
||||
|
||||
expect(savedPayload).toBeTruthy();
|
||||
expect(savedPayload?.ccd.automatic_thought).toEqual(["남길 자동사고"]);
|
||||
expect(savedPayload?.triggers.forbidden).toEqual(["네가 예민한 거라고 단정"]);
|
||||
expect(savedPayload?.triggers.sore_spots).toEqual([]);
|
||||
await expectNoHorizontalOverflow(page);
|
||||
});
|
||||
|
||||
test("renders persona prompt preview as labeled sections without raw JSON @single-run", async ({ page }) => {
|
||||
await signInAsTeacher(page);
|
||||
await page.route("**/api/personas", (route) => {
|
||||
if (route.request().method() !== "GET") return route.fallback();
|
||||
return route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify([]) });
|
||||
});
|
||||
await page.route("**/api/personas/review", (route) => {
|
||||
if (route.request().method() !== "GET") return route.fallback();
|
||||
return route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify([]) });
|
||||
});
|
||||
|
||||
await page.goto("/teach/personas");
|
||||
await page.getByLabel("표시 이름").fill("프롬프트 검토 페르소나");
|
||||
await page.getByRole("tab", { name: "임상" }).click();
|
||||
const automaticThoughts = page.locator(".ps-list-field").filter({ hasText: "자동사고" });
|
||||
await automaticThoughts.getByRole("textbox", { name: "자동사고 1", exact: true }).fill("말하면 더 이상하게 볼 거야");
|
||||
await page.getByRole("tab", { name: "안전" }).click();
|
||||
const forbidden = page.locator(".ps-list-field").filter({ hasText: "상담자 금기" });
|
||||
await forbidden.getByRole("textbox", { name: "상담자 금기 1", exact: true }).fill("네가 예민한 거라고 단정");
|
||||
|
||||
await page.getByRole("tab", { name: "프롬프트" }).click();
|
||||
const promptPreview = page.getByLabel("프롬프트 미리보기");
|
||||
await expect(promptPreview.getByRole("heading", { name: /L1 페르소나 카드/ })).toBeVisible();
|
||||
await expect(promptPreview.getByText("자동사고")).toBeVisible();
|
||||
await expect(promptPreview.getByText("말하면 더 이상하게 볼 거야")).toBeVisible();
|
||||
await expect(promptPreview.getByText("상담자 금기")).toBeVisible();
|
||||
await expect(promptPreview.getByText("네가 예민한 거라고 단정")).toBeVisible();
|
||||
await expect(promptPreview.getByRole("textbox")).toHaveCount(0);
|
||||
await expect(promptPreview).not.toContainText('"automatic_thought"');
|
||||
await expect(promptPreview).not.toContainText('"forbidden"');
|
||||
await expect(promptPreview).not.toContainText("{");
|
||||
await expectNoHorizontalOverflow(page);
|
||||
});
|
||||
|
||||
test("archives an approved persona from persona studio without layout drift @single-run", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
const personaId = "00000000-0000-0000-0000-000000000702";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue