import { mkdir } from "node:fs/promises"; import path from "node:path"; import { expect, type Page, type TestInfo, test } from "@playwright/test"; import { type Consent, installDevApiMock, makeClient, seedAuth, } from "./helpers/devfront-fixtures"; import { captureEvidence } from "./helpers/evidence"; const existingTenantId = "11111111-1111-4111-8111-111111111111"; const addedTenantId = "22222222-2222-4222-8222-222222222222"; async function captureTenantAccessEvidence( page: Page, testInfo: TestInfo, name: string, ) { await captureEvidence(page, testInfo, name); const evidenceDir = path.join(process.cwd(), "e2e-evidence"); await mkdir(evidenceDir, { recursive: true }); await page.screenshot({ path: path.join(evidenceDir, `${name}.png`), fullPage: true, }); } test.describe("DevFront client tenant access settings", () => { test.beforeEach(async ({ page }) => { page.on("dialog", async (dialog) => { await dialog.accept(); }); await seedAuth(page); }); test("adds and removes allowed tenants with UUID copy evidence", async ({ page, }, testInfo) => { await page.addInitScript(() => { Object.defineProperty(window, "isSecureContext", { configurable: true, value: true, }); Object.defineProperty(navigator, "clipboard", { configurable: true, value: { writeText: async (value: string) => { window.localStorage.setItem("__e2e_copied_text", value); }, }, }); }); const state = { clients: [ makeClient("client-tenant-access", { name: "Tenant Access App", scopes: ["openid", "profile", "email"], metadata: { tenant_access_restricted: true, allowed_tenants: [existingTenantId], }, }), ], consents: [] as Consent[], auditLogsByCursor: undefined, myTenants: [ { id: existingTenantId, name: "Alpha Tenant", slug: "alpha", description: "Existing allowed tenant", type: "organization", }, ], tenants: [ { id: existingTenantId, name: "Alpha Tenant", slug: "alpha", description: "Existing allowed tenant", type: "organization", }, { id: addedTenantId, name: "Beta Tenant", slug: "beta", description: "Tenant added during E2E", type: "organization", }, ], }; await installDevApiMock(page, state); await page.goto("/clients/client-tenant-access/settings"); await expect( page.getByRole("heading", { name: /테넌트 접근 제한|Tenant access/i }), ).toBeVisible(); await expect( page.getByTestId(`allowed-tenant-${existingTenantId}`), ).toContainText(existingTenantId); await page.getByTestId(`allowed-tenant-copy-${existingTenantId}`).click(); await expect .poll(() => page.evaluate(() => window.localStorage.getItem("__e2e_copied_text")), ) .toBe(existingTenantId); await page.getByRole("button", { name: /테넌트 선택기 열기/i }).click(); await page.evaluate( (selection) => { window.postMessage( { type: "orgfront:picker:confirm", payload: { selections: [ { type: "tenant", id: selection.id, name: selection.name, }, ], }, }, "*", ); }, { id: addedTenantId, name: "Beta Tenant" }, ); await expect( page.getByTestId(`allowed-tenant-${addedTenantId}`), ).toContainText(addedTenantId); await captureTenantAccessEvidence( page, testInfo, "tenant-access-allowed-tenant-added", ); await page.getByRole("button", { name: /^저장$|^Save$/i }).click(); await expect .poll(() => state.clients[0]?.metadata?.allowed_tenants) .toEqual([existingTenantId, addedTenantId]); await page.getByTestId(`allowed-tenant-remove-${addedTenantId}`).click(); await expect( page.getByTestId(`allowed-tenant-${addedTenantId}`), ).toHaveCount(0); await expect( page.getByTestId(`allowed-tenant-${existingTenantId}`), ).toContainText(existingTenantId); await captureTenantAccessEvidence( page, testInfo, "tenant-access-allowed-tenant-deleted", ); await page.getByRole("button", { name: /^저장$|^Save$/i }).click(); await expect .poll(() => state.clients[0]?.metadata?.allowed_tenants) .toEqual([existingTenantId]); }); });