Merge branch 'main' into feature/gateway-release-progress-20260809
# Conflicts: # app/gateway-frontend/src/views/ServerOperationsView.vue
This commit is contained in:
@@ -323,10 +323,29 @@ test('renders an ignored terminal outcome without calling it applied', async ({
|
||||
await expect(page.getByText(/적용됨|요청 완료/)).toHaveCount(0);
|
||||
});
|
||||
|
||||
test('directs profile deployment to the selected server version tab', async ({ page }) => {
|
||||
test('directs profile deployment to the selected server version tab', async ({ page }, testInfo) => {
|
||||
await installFixture(page);
|
||||
await page.goto('admin/servers');
|
||||
|
||||
const tabs = page.getByTestId('server-profile-tabs');
|
||||
await expect(tabs).toBeVisible();
|
||||
await expect(tabs.getByRole('link', { name: '상태 설정', exact: true })).toHaveAttribute('aria-current', 'page');
|
||||
await expect(page.getByText('버전과 시즌 수명주기', { exact: true })).toHaveCount(0);
|
||||
const versionTab = tabs.getByRole('link', { name: '버전 업데이트', exact: true });
|
||||
const idleTabBackground = await versionTab.evaluate((element) => getComputedStyle(element).backgroundColor);
|
||||
await versionTab.hover();
|
||||
await expect
|
||||
.poll(() => versionTab.evaluate((element) => getComputedStyle(element).backgroundColor))
|
||||
.not.toBe(idleTabBackground);
|
||||
await versionTab.focus();
|
||||
await expect(versionTab).toBeFocused();
|
||||
const tabAndHeaderGeometry = await Promise.all([
|
||||
tabs.evaluate((element) => element.getBoundingClientRect().top),
|
||||
page.getByText('hwe:default (hwe)', { exact: true }).evaluate((element) => element.getBoundingClientRect().top),
|
||||
]);
|
||||
expect(tabAndHeaderGeometry[0]).toBeLessThan(tabAndHeaderGeometry[1]);
|
||||
await page.screenshot({ path: testInfo.outputPath('status-tabs-desktop.png'), fullPage: true });
|
||||
|
||||
const releaseLink = page.getByRole('link', { name: '버전 업데이트', exact: true }).last();
|
||||
await expect(releaseLink).toBeVisible();
|
||||
await expect(releaseLink).toHaveAttribute('href', '/gateway/admin/servers/hwe%3Adefault/version');
|
||||
@@ -339,4 +358,5 @@ test('directs profile deployment to the selected server version tab', async ({ p
|
||||
});
|
||||
expect(linkGeometry.left).toBeGreaterThanOrEqual(0);
|
||||
expect(linkGeometry.right).toBeLessThanOrEqual(linkGeometry.viewportWidth);
|
||||
await page.screenshot({ path: testInfo.outputPath('status-tabs-mobile.png'), fullPage: true });
|
||||
});
|
||||
|
||||
@@ -35,6 +35,9 @@ type FixtureState = {
|
||||
requestBodies: Array<{ operation: string; body: unknown }>;
|
||||
gatewayLogPollCount?: number;
|
||||
capabilities?: Array<{ permission: string; scope: 'GLOBAL' | 'PROFILE'; scopes: string[] }>;
|
||||
profileListDelayMs?: number;
|
||||
profileListRequests?: number;
|
||||
profileListResolved?: boolean;
|
||||
};
|
||||
|
||||
const profile = (runtimeRunning: boolean) => ({
|
||||
@@ -94,6 +97,13 @@ const installFixture = async (page: Page, state: FixtureState) => {
|
||||
await page.route('**/gateway/api/trpc/**', async (route) => {
|
||||
const names = operationNames(route);
|
||||
const body = route.request().postDataJSON() as unknown;
|
||||
if (names.includes('admin.profiles.list')) {
|
||||
state.profileListRequests = (state.profileListRequests ?? 0) + 1;
|
||||
if (state.profileListDelayMs) {
|
||||
await new Promise((resolve) => setTimeout(resolve, state.profileListDelayMs));
|
||||
}
|
||||
state.profileListResolved = true;
|
||||
}
|
||||
const results = names.map((name) => {
|
||||
if (route.request().method() === 'POST') {
|
||||
state.requestBodies.push({ operation: name, body });
|
||||
@@ -267,8 +277,14 @@ test('separates branch and commit semantics and submits a reset from the dedicat
|
||||
await expect(page.getByTestId('server-operations-page')).toBeVisible();
|
||||
await expect(page).toHaveURL(/\/gateway\/admin\/servers\/che%3A2\/scenario$/);
|
||||
await expect(page.getByTestId('source-current')).toBeChecked();
|
||||
await expect(page.getByTestId('source-help')).toContainText('현재 서버 커밋');
|
||||
await expect(page.getByTestId('source-help')).toContainText('현재 서버에 배포된 커밋');
|
||||
await expect(page.getByTestId('scenario-select')).toHaveValue('2');
|
||||
await expect(page.getByTestId('server-profile-tabs')).toBeVisible();
|
||||
await expect(page.getByRole('link', { name: '시나리오 초기화', exact: true })).toHaveAttribute(
|
||||
'aria-current',
|
||||
'page'
|
||||
);
|
||||
await expect(page.getByText('운영 프로필', { exact: true })).toHaveCount(0);
|
||||
|
||||
const desktopGeometry = await page
|
||||
.getByTestId('server-operations-page')
|
||||
@@ -281,8 +297,8 @@ test('separates branch and commit semantics and submits a reset from the dedicat
|
||||
});
|
||||
return children;
|
||||
});
|
||||
expect(desktopGeometry).toHaveLength(2);
|
||||
expect(desktopGeometry[1]!.x).toBeGreaterThan(desktopGeometry[0]!.x);
|
||||
expect(desktopGeometry).toHaveLength(1);
|
||||
expect(desktopGeometry[0]!.width).toBeGreaterThan(800);
|
||||
await page.getByTestId('source-commit').check();
|
||||
const sourceInput = page.getByTestId('source-ref');
|
||||
await sourceInput.focus();
|
||||
@@ -329,8 +345,19 @@ test('separates branch and commit semantics and submits a reset from the dedicat
|
||||
});
|
||||
return children;
|
||||
});
|
||||
expect(mobileGeometry[1]!.y).toBeGreaterThan(mobileGeometry[0]!.y);
|
||||
expect(mobileGeometry[0]!.width).toBeLessThanOrEqual(390);
|
||||
const mobileTabs = await page
|
||||
.getByTestId('server-profile-tabs')
|
||||
.locator('a')
|
||||
.evaluateAll((links) =>
|
||||
links.map((link) => {
|
||||
const rect = link.getBoundingClientRect();
|
||||
return { top: rect.top, width: rect.width, height: rect.height };
|
||||
})
|
||||
);
|
||||
expect(mobileTabs).toHaveLength(3);
|
||||
expect(mobileTabs[1]!.top).toBeGreaterThan(mobileTabs[0]!.top);
|
||||
expect(mobileTabs.every((tab) => tab.height >= 44)).toBe(true);
|
||||
await page.screenshot({ path: testInfo.outputPath('mobile-operations.png'), fullPage: true });
|
||||
});
|
||||
|
||||
@@ -340,7 +367,12 @@ test('separates DB-preserving profile deployment from DB reset', async ({ page }
|
||||
page.on('dialog', (dialog) => dialog.accept());
|
||||
|
||||
await page.goto('admin/servers/che%3A2/version');
|
||||
await expect(page.getByText('Game frontend')).toBeVisible();
|
||||
await expect(page.getByRole('heading', { name: 'DB 보존 버전 업데이트' })).toBeVisible();
|
||||
await expect(page.getByText('운영 프로필', { exact: true })).toHaveCount(0);
|
||||
await expect(page.getByRole('link', { name: '버전 업데이트', exact: true })).toHaveAttribute(
|
||||
'aria-current',
|
||||
'page'
|
||||
);
|
||||
await page.getByTestId('request-deploy').click();
|
||||
|
||||
await expect(page.getByText('DB 보존 배포 작업을 등록했습니다.')).toBeVisible();
|
||||
@@ -349,6 +381,24 @@ test('separates DB-preserving profile deployment from DB reset', async ({ page }
|
||||
expect(state.requestBodies.some((entry) => entry.operation === 'admin.operations.requestReset')).toBe(false);
|
||||
});
|
||||
|
||||
test('renders the fixed-profile version form without waiting for the server list', async ({ page }) => {
|
||||
const state: FixtureState = {
|
||||
operations: [],
|
||||
gatewayOperations: [],
|
||||
runtimeRunning: true,
|
||||
requestBodies: [],
|
||||
profileListDelayMs: 1500,
|
||||
profileListResolved: false,
|
||||
};
|
||||
await installFixture(page, state);
|
||||
|
||||
await page.goto('admin/servers/che%3A2/version');
|
||||
await expect(page.getByTestId('request-deploy')).toBeVisible({ timeout: 900 });
|
||||
expect(state.profileListResolved).toBe(false);
|
||||
await expect.poll(() => state.profileListResolved).toBe(true);
|
||||
expect(state.profileListRequests).toBe(1);
|
||||
});
|
||||
|
||||
test('scenario-only operator resets the current version without Git or Gateway controls', async ({ page }) => {
|
||||
const state: FixtureState = {
|
||||
operations: [],
|
||||
@@ -466,7 +516,7 @@ test('renders a failed reset, retries it as a new operation, and reaches success
|
||||
state.runtimeRunning = true;
|
||||
await page.getByTestId('refresh-operations').click();
|
||||
await expect(page.getByText('SUCCEEDED', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('RUNNING', { exact: true }).first()).toBeVisible();
|
||||
await expect(page.getByText('운영 프로필', { exact: true })).toHaveCount(0);
|
||||
|
||||
await page.screenshot({ path: testInfo.outputPath('failed-retry-succeeded-desktop.png'), fullPage: true });
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
|
||||
Reference in New Issue
Block a user