Merge remote-tracking branch 'origin/main' into fix/nation-general-filter-menu-20260813
This commit is contained in:
@@ -572,6 +572,8 @@ const persistArtifact = async (page: Page, name: string) => {
|
||||
executionStatus: describe('.execution-status'),
|
||||
tournamentStatus: describe('.tournament-status'),
|
||||
voteStatus: describe('.vote-status'),
|
||||
autoRefresh: describe('[data-bottom-menu="auto-refresh"]'),
|
||||
manualRefresh: describe('[data-bottom-menu="manual-refresh"]'),
|
||||
commandMenu: describe('.reserved-command-editor details[open] .menu-items'),
|
||||
commandDividers: [...document.querySelectorAll<HTMLElement>('.reserved-command-editor details[open] .menu-divider')].map(
|
||||
(element) => {
|
||||
@@ -1472,6 +1474,7 @@ test('mobile single document refreshes once and preserves tokens on lobby return
|
||||
generalMeCalls: 0,
|
||||
operations: [],
|
||||
};
|
||||
await installRealtimeHarness(page);
|
||||
await installFixture(page, state);
|
||||
await page.setViewportSize({ width: 500, height: 900 });
|
||||
await waitForMain(page);
|
||||
@@ -1494,9 +1497,65 @@ test('mobile single document refreshes once and preserves tokens on lobby return
|
||||
await expect(page.locator(selector)).toBeVisible();
|
||||
}
|
||||
|
||||
const autoRefresh = page.getByRole('button', { name: '자동 갱신 ON' });
|
||||
const manualRefresh = page.getByRole('button', { name: '직접 갱신' });
|
||||
await expect(autoRefresh).toHaveAttribute('aria-pressed', 'true');
|
||||
await expect(autoRefresh.locator('strong')).toHaveCSS('color', 'rgb(158, 240, 184)');
|
||||
await expect(manualRefresh).toHaveAttribute('aria-busy', 'false');
|
||||
await expect
|
||||
.poll(() => page.evaluate(() => (window as unknown as { __hasMainRealtime: () => boolean }).__hasMainRealtime()))
|
||||
.toBe(true);
|
||||
|
||||
const refreshGeometry = await page.locator('.bottom-refresh-controls').evaluate((controls) => {
|
||||
const auto = controls.querySelector<HTMLElement>('[data-bottom-menu="auto-refresh"]');
|
||||
const manual = controls.querySelector<HTMLElement>('[data-bottom-menu="manual-refresh"]');
|
||||
if (!auto || !manual) throw new Error('mobile refresh controls are incomplete');
|
||||
const controlsRect = controls.getBoundingClientRect();
|
||||
const autoRect = auto.getBoundingClientRect();
|
||||
const manualRect = manual.getBoundingClientRect();
|
||||
return {
|
||||
controls: { left: controlsRect.left, right: controlsRect.right, width: controlsRect.width },
|
||||
auto: { left: autoRect.left, right: autoRect.right, width: autoRect.width },
|
||||
manual: { left: manualRect.left, right: manualRect.right, width: manualRect.width },
|
||||
overflow: controls.scrollWidth - controls.clientWidth,
|
||||
};
|
||||
});
|
||||
expect(refreshGeometry.controls.width).toBe(125);
|
||||
expect(refreshGeometry.auto.width).toBe(85);
|
||||
expect(refreshGeometry.manual.width).toBe(40);
|
||||
expect(refreshGeometry.auto.left).toBe(refreshGeometry.controls.left);
|
||||
expect(refreshGeometry.auto.right).toBe(refreshGeometry.manual.left);
|
||||
expect(refreshGeometry.manual.right).toBe(refreshGeometry.controls.right);
|
||||
expect(refreshGeometry.overflow).toBeLessThanOrEqual(0);
|
||||
|
||||
await autoRefresh.focus();
|
||||
await expect(autoRefresh).toBeFocused();
|
||||
await autoRefresh.hover();
|
||||
await expect(autoRefresh).toHaveCSS('filter', 'brightness(1.14)');
|
||||
await autoRefresh.click();
|
||||
const disabledAutoRefresh = page.getByRole('button', { name: '자동 갱신 OFF' });
|
||||
await expect(disabledAutoRefresh).toHaveAttribute('aria-pressed', 'false');
|
||||
await expect(disabledAutoRefresh.locator('strong')).toHaveCSS('color', 'rgb(187, 187, 187)');
|
||||
await expect
|
||||
.poll(() => page.evaluate(() => (window as unknown as { __hasMainRealtime: () => boolean }).__hasMainRealtime()))
|
||||
.toBe(false);
|
||||
await persistArtifact(page, `${basePath.slice(1)}-mobile-auto-refresh-controls-off`);
|
||||
|
||||
state.generalName = '직접갱신된장수';
|
||||
const callsBeforeRefresh = state.generalMeCalls;
|
||||
await page.getByRole('button', { name: '갱 신' }).click();
|
||||
await manualRefresh.click();
|
||||
await expect.poll(() => state.generalMeCalls).toBeGreaterThan(callsBeforeRefresh);
|
||||
await expect(page.locator('.general-title')).toContainText('직접갱신된장수');
|
||||
|
||||
const callsBeforeEnable = state.generalMeCalls;
|
||||
await page.getByRole('button', { name: '자동 갱신 OFF' }).click();
|
||||
await expect(page.getByRole('button', { name: '자동 갱신 ON' })).toHaveAttribute('aria-pressed', 'true');
|
||||
await expect.poll(() => state.generalMeCalls).toBeGreaterThan(callsBeforeEnable);
|
||||
await expect
|
||||
.poll(() => page.evaluate(() => (window as unknown as { __hasMainRealtime: () => boolean }).__hasMainRealtime()))
|
||||
.toBe(true);
|
||||
|
||||
await persistArtifact(page, `${basePath.slice(1)}-mobile-auto-refresh-controls`);
|
||||
|
||||
await page.evaluate(() => {
|
||||
localStorage.setItem('sammo-session-token', 'session_navigation');
|
||||
|
||||
@@ -18,10 +18,13 @@ const props = defineProps<{
|
||||
tournamentStage: number;
|
||||
nationColor: string;
|
||||
npcMode: number;
|
||||
realtimeEnabled: boolean;
|
||||
refreshing: boolean;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
refresh: [];
|
||||
toggleRealtime: [];
|
||||
lobby: [];
|
||||
quick: [item: QuickNavigationItem];
|
||||
}>();
|
||||
@@ -189,14 +192,31 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="bottom-trigger refresh-trigger"
|
||||
type="button"
|
||||
data-bottom-menu="refresh"
|
||||
@click="emit('refresh')"
|
||||
>
|
||||
갱신
|
||||
</button>
|
||||
<div class="bottom-refresh-controls">
|
||||
<button
|
||||
class="bottom-trigger auto-refresh-trigger"
|
||||
:class="{ active: realtimeEnabled }"
|
||||
type="button"
|
||||
data-bottom-menu="auto-refresh"
|
||||
:aria-pressed="realtimeEnabled"
|
||||
@click="emit('toggleRealtime')"
|
||||
>
|
||||
<span>자동 갱신</span>
|
||||
<strong>{{ realtimeEnabled ? 'ON' : 'OFF' }}</strong>
|
||||
</button>
|
||||
<button
|
||||
class="bottom-trigger manual-refresh-trigger"
|
||||
type="button"
|
||||
data-bottom-menu="manual-refresh"
|
||||
aria-label="직접 갱신"
|
||||
title="직접 갱신"
|
||||
:disabled="refreshing"
|
||||
:aria-busy="refreshing"
|
||||
@click="emit('refresh')"
|
||||
>
|
||||
<span aria-hidden="true">↻</span>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
@@ -221,6 +241,17 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bottom-refresh-controls {
|
||||
display: grid;
|
||||
width: 125px;
|
||||
height: 45px;
|
||||
grid-template-columns: minmax(0, 1fr) 40px;
|
||||
}
|
||||
|
||||
.bottom-refresh-controls > .bottom-trigger {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.bottom-trigger {
|
||||
box-sizing: border-box;
|
||||
width: 125px;
|
||||
@@ -245,6 +276,43 @@ const onQuick = (item: QuickNavigationItem) => {
|
||||
background: #212529;
|
||||
}
|
||||
|
||||
.auto-refresh-trigger {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 2px 1px;
|
||||
font-size: 12px;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.auto-refresh-trigger strong {
|
||||
color: #bbb;
|
||||
font-size: 11px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.auto-refresh-trigger.active {
|
||||
background-color: #164f2c;
|
||||
}
|
||||
|
||||
.auto-refresh-trigger.active strong {
|
||||
color: #9ef0b8;
|
||||
}
|
||||
|
||||
.manual-refresh-trigger {
|
||||
padding: 0;
|
||||
background: #212529;
|
||||
font-size: 22px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.manual-refresh-trigger:disabled {
|
||||
cursor: wait;
|
||||
filter: grayscale(0.6);
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.bottom-trigger:hover,
|
||||
.bottom-trigger:focus-visible,
|
||||
.bottom-trigger[aria-expanded='true'] {
|
||||
|
||||
@@ -455,7 +455,10 @@ watch(
|
||||
:tournament-stage="tournamentStage"
|
||||
:nation-color="nationColor"
|
||||
:npc-mode="npcMode"
|
||||
:realtime-enabled="realtimeEnabled"
|
||||
:refreshing="refreshing"
|
||||
@refresh="loadMainData"
|
||||
@toggle-realtime="dashboard.setRealtimeEnabled(!realtimeEnabled)"
|
||||
@lobby="moveLobby"
|
||||
@quick="moveQuick"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user