fix: Gateway 화면에서 raw 프로필 ID 노출을 제거한다
불변 profileName은 라우팅과 저장 경계에 유지하고 사용자 출력은 공통 표시명을 사용한다. 기본 인스턴스 suffix를 숨기고 비기본 인스턴스만 사람이 읽을 수 있게 구분한다.
This commit is contained in:
@@ -131,6 +131,9 @@ const installFixture = async (page: Page) => {
|
||||
profiles: [
|
||||
{
|
||||
profileName: 'che:default',
|
||||
profile: 'che',
|
||||
instanceKey: 'default',
|
||||
displayName: '체',
|
||||
requiresKakaoVerification: true,
|
||||
kakaoVerified: false,
|
||||
accessAllowed: true,
|
||||
@@ -219,15 +222,16 @@ test('operates OAuth grace and scheduled deletion with reasoned audit history',
|
||||
await page.getByRole('button', { name: /접근 · 권한/ }).click();
|
||||
await expect(page.getByRole('option', { name: /Profile 전체 운영/ })).toHaveCount(0);
|
||||
await expect(page.getByRole('option', { name: /Profile 실행 관리/ })).toHaveCount(1);
|
||||
await expect(page.getByRole('cell', { name: 'che:default' })).toBeVisible();
|
||||
await expect(page.getByRole('cell', { name: '체' })).toBeVisible();
|
||||
await expect(page.getByText('che:default', { exact: true })).toHaveCount(0);
|
||||
await page.screenshot({ path: testInfo.outputPath('gateway-admin-account-controls-desktop.png'), fullPage: true });
|
||||
await page.getByPlaceholder('권한·제재·복구·탈퇴 조치 사유 (필수)').fill('본인 확인 처리 중');
|
||||
await page.getByLabel('특수 접근 만료 시각').fill('2026-08-20T00:00');
|
||||
await page.getByPlaceholder('che 또는 che:2 (쉼표 구분, 비우면 전체)').fill('che');
|
||||
await page.getByRole('checkbox', { name: '체' }).check();
|
||||
await page.getByPlaceholder('권한·제재·복구·탈퇴 조치 사유 (필수)').fill('휴대폰 분실 임시 복구');
|
||||
await page.getByRole('button', { name: '특수 접근 부여', exact: true }).click();
|
||||
await expect(page.getByText('특수 접근 자격을 부여했습니다.').first()).toBeVisible();
|
||||
await expect(page.getByText(/RECOVERY · che/)).toBeVisible();
|
||||
await expect(page.getByText(/RECOVERY · 체/)).toBeVisible();
|
||||
await page.screenshot({ path: testInfo.outputPath('gateway-admin-special-access-granted.png'), fullPage: true });
|
||||
|
||||
const gracePanel = page.getByRole('heading', { name: 'Kakao 인증 유예' }).locator('..');
|
||||
|
||||
@@ -165,6 +165,7 @@ const installFixture = async (
|
||||
profileName: 'hwe:default',
|
||||
profile: 'hwe',
|
||||
instanceKey: 'default',
|
||||
displayName: '훼',
|
||||
currentScenario: options.currentScenario === undefined ? '1010' : options.currentScenario,
|
||||
meta: {},
|
||||
},
|
||||
@@ -177,6 +178,7 @@ const installFixture = async (
|
||||
profileName: 'hwe:default',
|
||||
profile: 'hwe',
|
||||
instanceKey: 'default',
|
||||
displayName: '훼',
|
||||
currentScenario: options.currentScenario === undefined ? '1010' : options.currentScenario,
|
||||
scenario: options.currentScenario ?? 'default',
|
||||
apiPort: 15015,
|
||||
@@ -542,7 +544,7 @@ test('directs profile deployment to the selected server version tab', async ({ p
|
||||
const tabAndHeaderGeometry = await Promise.all([
|
||||
tabs.evaluate((element) => element.getBoundingClientRect().top),
|
||||
page
|
||||
.getByText('서버 ID: hwe:default · 인스턴스: default', { exact: true })
|
||||
.getByText('현재 시나리오: 1010', { exact: true })
|
||||
.evaluate((element) => element.getBoundingClientRect().top),
|
||||
]);
|
||||
expect(tabAndHeaderGeometry[0]).toBeLessThan(tabAndHeaderGeometry[1]);
|
||||
|
||||
@@ -48,6 +48,7 @@ const installGatewayFixture = async (page: Page, roles: string[]) => {
|
||||
profileName: 'hwe:2',
|
||||
profile: 'hwe',
|
||||
instanceKey: '2',
|
||||
displayName: '환상서버 [2]',
|
||||
currentScenario: '1010',
|
||||
scenario: '1010',
|
||||
status: 'RUNNING',
|
||||
@@ -68,6 +69,7 @@ const installGatewayFixture = async (page: Page, roles: string[]) => {
|
||||
profileName: 'hwe:2',
|
||||
profile: 'hwe',
|
||||
instanceKey: '2',
|
||||
displayName: '환상서버 [2]',
|
||||
currentScenario: '1010',
|
||||
meta: { korName: '환상서버' },
|
||||
},
|
||||
@@ -306,23 +308,26 @@ test('keeps mobile account actions on clean rows for users and administrators',
|
||||
const adminLink = adminPage.getByRole('link', { name: '관리자 페이지' });
|
||||
const baseBackground = await adminLink.evaluate((element) => getComputedStyle(element).backgroundColor);
|
||||
await adminLink.hover();
|
||||
await expect.poll(() => adminLink.evaluate((element) => getComputedStyle(element).backgroundColor)).not.toBe(
|
||||
baseBackground
|
||||
);
|
||||
await expect
|
||||
.poll(() => adminLink.evaluate((element) => getComputedStyle(element).backgroundColor))
|
||||
.not.toBe(baseBackground);
|
||||
await adminLink.focus();
|
||||
await expect(adminLink).toBeFocused();
|
||||
await adminPage.screenshot({ path: testInfo.outputPath('gateway-account-actions-admin-500px.png'), fullPage: true });
|
||||
await adminPage.screenshot({
|
||||
path: testInfo.outputPath('gateway-account-actions-admin-500px.png'),
|
||||
fullPage: true,
|
||||
});
|
||||
|
||||
await adminPage.setViewportSize({ width: 390, height: 844 });
|
||||
const adminNarrowGeometry = await measureAccountActions(adminPage);
|
||||
expect(adminNarrowGeometry.documentWidth).toBe(adminNarrowGeometry.viewportWidth);
|
||||
expect(adminNarrowGeometry.items[0]?.top).toBeCloseTo(adminNarrowGeometry.items[1]?.top ?? 0, 0);
|
||||
expect(adminNarrowGeometry.items[2]?.top).toBeCloseTo(
|
||||
(adminNarrowGeometry.items[1]?.bottom ?? 0) + 16,
|
||||
0
|
||||
);
|
||||
expect(adminNarrowGeometry.items[2]?.top).toBeCloseTo((adminNarrowGeometry.items[1]?.bottom ?? 0) + 16, 0);
|
||||
expect(adminNarrowGeometry.items.every(({ scrollWidth, clientWidth }) => scrollWidth <= clientWidth)).toBe(true);
|
||||
await adminPage.screenshot({ path: testInfo.outputPath('gateway-account-actions-admin-390px.png'), fullPage: true });
|
||||
await adminPage.screenshot({
|
||||
path: testInfo.outputPath('gateway-account-actions-admin-390px.png'),
|
||||
fullPage: true,
|
||||
});
|
||||
|
||||
await adminPage.setViewportSize({ width: 360, height: 800 });
|
||||
const adminSmallGeometry = await measureAccountActions(adminPage);
|
||||
|
||||
@@ -71,6 +71,7 @@ const profile = (runtimeRunning: boolean, resetDefaults?: Record<string, unknown
|
||||
profileName: 'che:default',
|
||||
profile: 'che',
|
||||
instanceKey: 'default',
|
||||
displayName: '천하서버',
|
||||
currentScenario: '2',
|
||||
scenario: '2',
|
||||
apiPort: 15003,
|
||||
@@ -200,6 +201,7 @@ const installFixture = async (page: Page, state: FixtureState) => {
|
||||
profileName: 'che:default',
|
||||
profile: 'che',
|
||||
instanceKey: 'default',
|
||||
displayName: '천하서버',
|
||||
currentScenario: '2',
|
||||
meta: { korName: '천하서버' },
|
||||
},
|
||||
@@ -639,7 +641,7 @@ test('separates branch and commit semantics and submits a reset from the dedicat
|
||||
await expect(page.getByText('초기화 작업을 등록했습니다.').first()).toBeVisible();
|
||||
await expect(page.getByTestId('operations-table')).toContainText('시나리오 초기화');
|
||||
await expect(page.getByTestId('profile-operation-log-panel')).toBeVisible();
|
||||
await expect(page.getByTestId('profile-operation-log')).toContainText('che:default 구성 요소를 빌드합니다.');
|
||||
await expect(page.getByTestId('profile-operation-log')).toContainText('천하서버 구성 요소를 빌드합니다.');
|
||||
await expect(page.getByTestId('profile-operation-log')).toContainText('시나리오 초기 데이터 생성을 완료했습니다.');
|
||||
await expect(page.getByTestId('profile-operation-log-status')).toContainText('SUCCEEDED');
|
||||
const operationTable = page.getByTestId('operations-table');
|
||||
@@ -652,7 +654,8 @@ test('separates branch and commit semantics and submits a reset from the dedicat
|
||||
await detailsToggle.click();
|
||||
await expect(detailsToggle).toHaveAttribute('aria-expanded', 'true');
|
||||
const operationDetail = operationTable.getByTestId('operation-detail');
|
||||
await expect(operationDetail).toContainText('che:default');
|
||||
await expect(operationDetail).toContainText('천하서버');
|
||||
await expect(operationDetail).not.toContainText('che:default');
|
||||
await expect(operationDetail).toContainText('0123456789abcdef0123456789abcdef01234567');
|
||||
await expect(operationDetail).toContainText('admin');
|
||||
const operationTableGeometry = await page.getByTestId('operations-table').evaluate((table) => {
|
||||
@@ -807,7 +810,7 @@ test('separates DB-preserving profile deployment from DB reset', async ({ page }
|
||||
await expect(page.getByText('DB 보존 배포 작업을 등록했습니다.').first()).toBeVisible();
|
||||
await expect(page.getByTestId('operations-table')).toContainText('버전 업데이트');
|
||||
await expect(page.getByTestId('profile-operation-log-panel')).toBeVisible();
|
||||
await expect(page.getByTestId('profile-operation-log')).toContainText('che:default 구성 요소를 빌드합니다.');
|
||||
await expect(page.getByTestId('profile-operation-log')).toContainText('천하서버 구성 요소를 빌드합니다.');
|
||||
await expect(page.getByTestId('profile-operation-log')).toContainText('game-frontend build complete');
|
||||
await expect(page.getByTestId('profile-operation-log-status')).toContainText('SUCCEEDED');
|
||||
expect(state.requestBodies.some((entry) => entry.operation === 'admin.operations.requestDeploy')).toBe(true);
|
||||
@@ -834,7 +837,7 @@ test('submits a separately authorized destructive game cancellation on desktop a
|
||||
|
||||
await page.goto('admin/servers/che%3Adefault/cancel');
|
||||
await expect(page).toHaveURL(/\/gateway\/admin\/servers\/che%3Adefault\/cancel$/);
|
||||
await expect(page.getByRole('heading', { name: 'che:default 게임 취소' })).toBeVisible();
|
||||
await expect(page.getByRole('heading', { name: '천하서버 게임 취소' })).toBeVisible();
|
||||
await expect(page.getByRole('link', { name: '게임 취소', exact: true })).toHaveAttribute('aria-current', 'page');
|
||||
await expect(page.getByRole('link', { name: '시나리오 초기화', exact: true })).toHaveCount(0);
|
||||
await expect(page.getByTestId('request-game-cancellation')).toBeDisabled();
|
||||
@@ -843,7 +846,7 @@ test('submits a separately authorized destructive game cancellation on desktop a
|
||||
await page.getByTestId('cancellation-general-mode').selectOption('RETAIN');
|
||||
await page.getByTestId('cancellation-retention-percent').fill('35');
|
||||
await page.getByTestId('cancellation-reason').fill('잘못된 시나리오로 개장함');
|
||||
await page.getByTestId('cancellation-confirmation').fill('che:default');
|
||||
await page.getByTestId('cancellation-confirmation').fill('천하서버 게임 취소');
|
||||
const cancelButton = page.getByTestId('request-game-cancellation');
|
||||
await expect(cancelButton).toBeEnabled();
|
||||
await cancelButton.hover();
|
||||
@@ -1348,10 +1351,11 @@ test('renders the stable server identity without exposing the default suffix as
|
||||
const navigation = page.getByRole('navigation', { name: '관리자 메뉴' });
|
||||
const profileLink = navigation.getByRole('link', { name: '천하서버' });
|
||||
await expect(profileLink).toBeVisible({ timeout: 900 });
|
||||
await expect(profileLink).toHaveAttribute('title', '서버 ID: che:default');
|
||||
await expect(profileLink).toHaveAttribute('title', '천하서버 서버 관리');
|
||||
await expect(navigation).not.toContainText('천하서버 (che:default)');
|
||||
await expect(navigation.getByRole('link', { name: 'Gateway 릴리스' })).toBeVisible({ timeout: 900 });
|
||||
await expect(page.getByText('서버 ID: che:default · 인스턴스: default')).toBeVisible();
|
||||
await expect(page.getByText('서버 ID: che:default · 인스턴스: default')).toHaveCount(0);
|
||||
await expect(page.getByText('천하서버', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('현재 시나리오: 2')).toBeVisible();
|
||||
await profileLink.focus();
|
||||
const desktop = await profileLink.evaluate((element) => {
|
||||
|
||||
@@ -59,6 +59,8 @@ const installFixture = async (page: Page) => {
|
||||
{
|
||||
profileName: 'hwe:default',
|
||||
profile: 'hwe',
|
||||
instanceKey: 'default',
|
||||
displayName: '훼',
|
||||
currentScenario: 'default',
|
||||
status: 'RUNNING',
|
||||
},
|
||||
@@ -93,6 +95,8 @@ test('web push settings are default-off and remain configurable while delivery i
|
||||
const table = page.locator('#notification-table');
|
||||
await expect(table).toBeVisible();
|
||||
await expect(table).toContainText('준비됨 · 운영 비활성');
|
||||
await expect(table).toContainText('훼 · default');
|
||||
await expect(table).not.toContainText('hwe:default');
|
||||
await expect(page.getByRole('button', { name: '이 기기 알림 켜기' })).toBeDisabled();
|
||||
const checkboxes = table.getByRole('checkbox');
|
||||
await expect(checkboxes).toHaveCount(9);
|
||||
|
||||
Reference in New Issue
Block a user