merge: 최신 로컬 main을 Vue 드래그 리팩터링에 통합
This commit is contained in:
@@ -1048,6 +1048,9 @@ const persistArtifact = async (page: Page, name: string) => {
|
||||
gameHeader: describe('.game-shell__header'),
|
||||
gameTitle: describe('.game-shell__title'),
|
||||
gameHeaderActions: describe('.desktop-action-controls'),
|
||||
headerRealtime: describe('.desktop-action-controls__realtime'),
|
||||
headerRefresh: describe('.desktop-action-controls__refresh'),
|
||||
headerLobby: describe('.desktop-action-controls__lobby'),
|
||||
legacyGameInfo: describe('.legacy-game-info'),
|
||||
activityStatus: describe('.activity-status'),
|
||||
executionStatus: describe('.execution-status'),
|
||||
@@ -2390,7 +2393,9 @@ test('the 939/940 boundary switches to the Ref-style 500px single document', asy
|
||||
const headerActionsRect = headerActions.getBoundingClientRect();
|
||||
return {
|
||||
headerHeight: headerRect.height,
|
||||
headerLeft: headerRect.left,
|
||||
headerRight: headerRect.right,
|
||||
headerActionsLeft: headerActionsRect.left,
|
||||
headerActionsRight: headerActionsRect.right,
|
||||
width: element.getBoundingClientRect().width,
|
||||
executionWidth: execution.getBoundingClientRect().width,
|
||||
@@ -2399,7 +2404,9 @@ test('the 939/940 boundary switches to the Ref-style 500px single document', asy
|
||||
columns: getComputedStyle(element).gridTemplateColumns,
|
||||
};
|
||||
});
|
||||
expect(activityGeometry.headerHeight).toBeLessThan(60);
|
||||
expect(activityGeometry.headerHeight).toBeGreaterThan(90);
|
||||
expect(activityGeometry.headerHeight).toBeLessThan(110);
|
||||
expect(activityGeometry.headerActionsLeft).toBeGreaterThanOrEqual(activityGeometry.headerLeft);
|
||||
expect(activityGeometry.headerActionsRight).toBeLessThanOrEqual(activityGeometry.headerRight);
|
||||
expect(activityGeometry.width).toBe(500);
|
||||
expect(activityGeometry.executionWidth).toBeCloseTo(166.67, 0);
|
||||
@@ -3179,6 +3186,78 @@ test('all main Lumen button families share the rounded pressed geometry', async
|
||||
await persistArtifact(page, `${basePath.slice(1)}-main-lumen-button-families`);
|
||||
});
|
||||
|
||||
test('lobby action is separated on desktop and anchors opposite the refresh action on mobile', async ({ page }) => {
|
||||
const state: NavigationFixture = {
|
||||
officerLevel: 5,
|
||||
permission: 2,
|
||||
nationLevel: 3,
|
||||
stage: 0,
|
||||
npcMode: 1,
|
||||
generalMeCalls: 0,
|
||||
operations: [],
|
||||
};
|
||||
await installFixture(page, state);
|
||||
await page.setViewportSize({ width: 1200, height: 900 });
|
||||
await waitForMain(page);
|
||||
|
||||
const actions = page.locator('.desktop-action-controls');
|
||||
const realtime = page.locator('.desktop-action-controls__realtime');
|
||||
const refresh = page.locator('.desktop-action-controls__refresh');
|
||||
const lobby = page.locator('.desktop-action-controls__lobby');
|
||||
const measure = () =>
|
||||
page.evaluate(() => {
|
||||
const rect = (selector: string) => {
|
||||
const element = document.querySelector<HTMLElement>(selector);
|
||||
if (!element) throw new Error(`${selector} is missing`);
|
||||
const box = element.getBoundingClientRect();
|
||||
return { left: box.left, right: box.right, top: box.top, bottom: box.bottom, width: box.width };
|
||||
};
|
||||
const actionStyle = getComputedStyle(document.querySelector<HTMLElement>('.desktop-action-controls')!);
|
||||
return {
|
||||
actions: rect('.desktop-action-controls'),
|
||||
realtime: rect('.desktop-action-controls__realtime'),
|
||||
refresh: rect('.desktop-action-controls__refresh'),
|
||||
lobby: rect('.desktop-action-controls__lobby'),
|
||||
title: rect('.game-shell__title'),
|
||||
display: actionStyle.display,
|
||||
columns: actionStyle.gridTemplateColumns,
|
||||
};
|
||||
});
|
||||
|
||||
await expect(actions).toHaveCSS('display', 'flex');
|
||||
let layout = await measure();
|
||||
expect(layout.lobby.left - layout.refresh.right).toBeGreaterThanOrEqual(20);
|
||||
expect(layout.refresh.top).toBeCloseTo(layout.lobby.top, 2);
|
||||
expect(layout.refresh.width).toBeLessThanOrEqual(62);
|
||||
expect(layout.lobby.width).toBeLessThanOrEqual(62);
|
||||
|
||||
await page.setViewportSize({ width: 500, height: 900 });
|
||||
await expect(actions).toHaveCSS('display', 'grid');
|
||||
await expect(realtime).toBeVisible();
|
||||
await expect(refresh).toBeVisible();
|
||||
await expect(lobby).toBeVisible();
|
||||
layout = await measure();
|
||||
expect(layout.columns.split(' ')).toHaveLength(3);
|
||||
expect(layout.actions.left).toBeCloseTo(0, 2);
|
||||
expect(layout.actions.right).toBeCloseTo(500, 2);
|
||||
expect(layout.refresh.left).toBeCloseTo(layout.actions.left, 2);
|
||||
expect(layout.lobby.right).toBeCloseTo(layout.actions.right, 2);
|
||||
expect(layout.refresh.right).toBeLessThan(layout.realtime.left);
|
||||
expect(layout.realtime.right).toBeLessThan(layout.lobby.left);
|
||||
expect(layout.refresh.top).toBeCloseTo(layout.lobby.top, 2);
|
||||
expect(layout.actions.top).toBeGreaterThanOrEqual(layout.title.bottom);
|
||||
expect(layout.refresh.width).toBeLessThanOrEqual(62);
|
||||
expect(layout.lobby.width).toBeLessThanOrEqual(62);
|
||||
expect(
|
||||
await page.evaluate(() => ({
|
||||
document: document.documentElement.scrollWidth - document.documentElement.clientWidth,
|
||||
body: document.body.scrollWidth - document.body.clientWidth,
|
||||
}))
|
||||
).toEqual({ document: 0, body: 0 });
|
||||
|
||||
await persistArtifact(page, `${basePath.slice(1)}-main-lobby-action-layout`);
|
||||
});
|
||||
|
||||
test('mobile main Lumen button families keep the same state geometry without overflow', async ({ page }) => {
|
||||
const state: NavigationFixture = {
|
||||
officerLevel: 5,
|
||||
|
||||
@@ -225,7 +225,7 @@ watch(
|
||||
</h1>
|
||||
<div class="game-shell__actions desktop-action-controls">
|
||||
<button
|
||||
class="game-shell__action toggle legacy-button legacy-button--navigation"
|
||||
class="game-shell__action desktop-action-controls__realtime toggle legacy-button legacy-button--navigation"
|
||||
:class="{ active: realtimeEnabled }"
|
||||
type="button"
|
||||
@click="dashboard.setRealtimeEnabled(!realtimeEnabled)"
|
||||
@@ -233,7 +233,7 @@ watch(
|
||||
실시간 동기화: {{ realtimeLabel }}
|
||||
</button>
|
||||
<button
|
||||
class="game-shell__action legacy-button legacy-button--navigation"
|
||||
class="game-shell__action desktop-action-controls__refresh legacy-button legacy-button--navigation"
|
||||
type="button"
|
||||
:aria-busy="refreshing"
|
||||
@click="requestManualRefresh"
|
||||
@@ -241,7 +241,7 @@ watch(
|
||||
갱 신
|
||||
</button>
|
||||
<button
|
||||
class="game-shell__action legacy-button legacy-button--navigation"
|
||||
class="game-shell__action desktop-action-controls__lobby legacy-button legacy-button--navigation"
|
||||
type="button"
|
||||
@click="moveLobby"
|
||||
>
|
||||
@@ -916,6 +916,10 @@ button {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.desktop-action-controls__lobby {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
font-size: 0.85rem;
|
||||
color: rgba(232, 221, 196, 0.7);
|
||||
@@ -930,7 +934,12 @@ button {
|
||||
}
|
||||
|
||||
.desktop-action-controls {
|
||||
gap: 4px;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
grid-template-areas: 'refresh realtime lobby';
|
||||
grid-template-columns: max-content 1fr max-content;
|
||||
align-items: start;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.desktop-action-controls .game-shell__action {
|
||||
@@ -938,6 +947,22 @@ button {
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.desktop-action-controls__refresh {
|
||||
grid-area: refresh;
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.desktop-action-controls__realtime {
|
||||
grid-area: realtime;
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.desktop-action-controls__lobby {
|
||||
grid-area: lobby;
|
||||
justify-self: end;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.main-page {
|
||||
width: 500px;
|
||||
min-height: 3688px;
|
||||
|
||||
Reference in New Issue
Block a user