fix(game-ui): 로비 새 탭 이동을 지원한다
This commit is contained in:
@@ -4248,7 +4248,7 @@ test('all main Lumen button families share the rounded pressed geometry', async
|
|||||||
page.locator('.main-turn-controls').getByRole('button', { name: '갱 신' }),
|
page.locator('.main-turn-controls').getByRole('button', { name: '갱 신' }),
|
||||||
{ radius: '5.25px 0px 0px 5.25px' },
|
{ radius: '5.25px 0px 0px 5.25px' },
|
||||||
],
|
],
|
||||||
['로비로', page.locator('.main-turn-controls').getByRole('button', { name: '로비로' })],
|
['로비로', page.locator('.main-turn-controls').getByRole('link', { name: '로비로' })],
|
||||||
];
|
];
|
||||||
|
|
||||||
const measure = (control: Locator) =>
|
const measure = (control: Locator) =>
|
||||||
@@ -4531,7 +4531,7 @@ test('mobile main Lumen button families keep the same state geometry without ove
|
|||||||
page.locator('[data-main-target="commands"] .bottom-actions').getByRole('button', { name: '펼치기' }),
|
page.locator('[data-main-target="commands"] .bottom-actions').getByRole('button', { name: '펼치기' }),
|
||||||
page.locator('.layout-mobile .main-turn-controls').getByRole('button', { name: /자동 갱신/u }),
|
page.locator('.layout-mobile .main-turn-controls').getByRole('button', { name: /자동 갱신/u }),
|
||||||
page.locator('.layout-mobile .main-turn-controls').getByRole('button', { name: '갱 신' }),
|
page.locator('.layout-mobile .main-turn-controls').getByRole('button', { name: '갱 신' }),
|
||||||
page.locator('.layout-mobile .main-turn-controls').getByRole('button', { name: '로비로' }),
|
page.locator('.layout-mobile .main-turn-controls').getByRole('link', { name: '로비로' }),
|
||||||
];
|
];
|
||||||
for (const [index, control] of controls.entries()) {
|
for (const [index, control] of controls.entries()) {
|
||||||
await expect(control).toBeVisible();
|
await expect(control).toBeVisible();
|
||||||
@@ -4571,7 +4571,7 @@ test('mobile main Lumen button families keep the same state geometry without ove
|
|||||||
await persistArtifact(page, `${basePath.slice(1)}-mobile-main-lumen-button-families`);
|
await persistArtifact(page, `${basePath.slice(1)}-mobile-main-lumen-button-families`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('mobile single document refreshes once and preserves tokens on lobby return', async ({ page }) => {
|
test('mobile single document refreshes once and preserves tokens on lobby return', async ({ page, context }) => {
|
||||||
const state: NavigationFixture = {
|
const state: NavigationFixture = {
|
||||||
officerLevel: 5,
|
officerLevel: 5,
|
||||||
permission: 2,
|
permission: 2,
|
||||||
@@ -4677,10 +4677,20 @@ test('mobile single document refreshes once and preserves tokens on lobby return
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
localStorage.setItem('sammo-session-token', 'session_navigation');
|
localStorage.setItem('sammo-session-token', 'session_navigation');
|
||||||
});
|
});
|
||||||
await page.route('**/gateway/', async (route) => {
|
await context.route('**/gateway/', async (route) => {
|
||||||
await route.fulfill({ status: 200, contentType: 'text/html', body: '<!doctype html><title>gateway</title>' });
|
await route.fulfill({ status: 200, contentType: 'text/html', body: '<!doctype html><title>gateway</title>' });
|
||||||
});
|
});
|
||||||
await Promise.all([page.waitForURL('**/gateway/'), page.getByRole('button', { name: '로비로' }).click()]);
|
const lobbyLink = page.locator('.main-turn-controls__lobby');
|
||||||
|
await expect(lobbyLink).toHaveAttribute('href', /\/gateway\/$/);
|
||||||
|
const sourceUrl = page.url();
|
||||||
|
const popupPromise = context.waitForEvent('page');
|
||||||
|
await lobbyLink.click({ button: 'middle' });
|
||||||
|
const popup = await popupPromise;
|
||||||
|
await popup.waitForURL('**/gateway/');
|
||||||
|
expect(page.url()).toBe(sourceUrl);
|
||||||
|
await popup.close();
|
||||||
|
|
||||||
|
await Promise.all([page.waitForURL('**/gateway/'), lobbyLink.click()]);
|
||||||
expect(
|
expect(
|
||||||
await page.evaluate(() => ({
|
await page.evaluate(() => ({
|
||||||
session: localStorage.getItem('sammo-session-token'),
|
session: localStorage.getItem('sammo-session-token'),
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { gameFrontendRuntimeConfig } from '../../config/runtimeConfig';
|
||||||
|
|
||||||
|
const handleClick = (event: MouseEvent): void => {
|
||||||
|
if (event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
window.location.replace(gameFrontendRuntimeConfig.gatewayWebUrl);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a :href="gameFrontendRuntimeConfig.gatewayWebUrl" @click="handleClick"><slot>로비로</slot></a>
|
||||||
|
</template>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { legacyNationTextColor } from '../../utils/legacyNationColor';
|
import { legacyNationTextColor } from '../../utils/legacyNationColor';
|
||||||
|
import GatewayLobbyLink from './GatewayLobbyLink.vue';
|
||||||
import MainNavigationLink from './MainNavigationLink.vue';
|
import MainNavigationLink from './MainNavigationLink.vue';
|
||||||
import {
|
import {
|
||||||
buildGlobalNavigation,
|
buildGlobalNavigation,
|
||||||
@@ -29,7 +30,6 @@ const props = defineProps<{
|
|||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
refresh: [];
|
refresh: [];
|
||||||
toggleRealtime: [];
|
toggleRealtime: [];
|
||||||
lobby: [];
|
|
||||||
quick: [item: QuickNavigationItem];
|
quick: [item: QuickNavigationItem];
|
||||||
action: [action: NonNullable<MainNavigationLinkItem['action']>];
|
action: [action: NonNullable<MainNavigationLinkItem['action']>];
|
||||||
}>();
|
}>();
|
||||||
@@ -212,14 +212,12 @@ const onAction = (action: NonNullable<MainNavigationLinkItem['action']>) => {
|
|||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
<li class="bottom-lobby" role="none">
|
<li class="bottom-lobby" role="none">
|
||||||
<button
|
<GatewayLobbyLink
|
||||||
class="quick-link lobby-link legacy-button legacy-button--navigation"
|
class="quick-link lobby-link legacy-button legacy-button--navigation"
|
||||||
type="button"
|
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
@click="emit('lobby')"
|
|
||||||
>
|
>
|
||||||
로비로
|
로비로
|
||||||
</button>
|
</GatewayLobbyLink>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import GatewayLobbyLink from './GatewayLobbyLink.vue';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
realtimeEnabled: boolean;
|
realtimeEnabled: boolean;
|
||||||
refreshing: boolean;
|
refreshing: boolean;
|
||||||
@@ -7,7 +9,6 @@ defineProps<{
|
|||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
refresh: [];
|
refresh: [];
|
||||||
toggleRealtime: [];
|
toggleRealtime: [];
|
||||||
lobby: [];
|
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -34,13 +35,11 @@ const emit = defineEmits<{
|
|||||||
<strong>{{ realtimeEnabled ? 'ON' : 'OFF' }}</strong>
|
<strong>{{ realtimeEnabled ? 'ON' : 'OFF' }}</strong>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<GatewayLobbyLink
|
||||||
class="main-turn-controls__lobby legacy-button legacy-button--navigation"
|
class="main-turn-controls__lobby legacy-button legacy-button--navigation"
|
||||||
type="button"
|
|
||||||
@click="emit('lobby')"
|
|
||||||
>
|
>
|
||||||
로비로
|
로비로
|
||||||
</button>
|
</GatewayLobbyLink>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -208,10 +208,6 @@ const requestManualRefresh = () => {
|
|||||||
void loadMainData();
|
void loadMainData();
|
||||||
};
|
};
|
||||||
|
|
||||||
const moveLobby = () => {
|
|
||||||
window.location.replace(gameFrontendRuntimeConfig.gatewayWebUrl);
|
|
||||||
};
|
|
||||||
|
|
||||||
const moveQuick = (item: QuickNavigationItem) => {
|
const moveQuick = (item: QuickNavigationItem) => {
|
||||||
document.querySelector(item.selector)?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
document.querySelector(item.selector)?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
};
|
};
|
||||||
@@ -348,7 +344,6 @@ watch(
|
|||||||
:refreshing="refreshing"
|
:refreshing="refreshing"
|
||||||
@refresh="requestManualRefresh"
|
@refresh="requestManualRefresh"
|
||||||
@toggle-realtime="dashboard.setRealtimeEnabled(!realtimeEnabled)"
|
@toggle-realtime="dashboard.setRealtimeEnabled(!realtimeEnabled)"
|
||||||
@lobby="moveLobby"
|
|
||||||
/>
|
/>
|
||||||
</PanelCard>
|
</PanelCard>
|
||||||
</div>
|
</div>
|
||||||
@@ -524,7 +519,6 @@ watch(
|
|||||||
:refreshing="refreshing"
|
:refreshing="refreshing"
|
||||||
@refresh="requestManualRefresh"
|
@refresh="requestManualRefresh"
|
||||||
@toggle-realtime="dashboard.setRealtimeEnabled(!realtimeEnabled)"
|
@toggle-realtime="dashboard.setRealtimeEnabled(!realtimeEnabled)"
|
||||||
@lobby="moveLobby"
|
|
||||||
/>
|
/>
|
||||||
</PanelCard>
|
</PanelCard>
|
||||||
<PanelCard title="도시 정보" data-main-target="city">
|
<PanelCard title="도시 정보" data-main-target="city">
|
||||||
@@ -639,7 +633,6 @@ watch(
|
|||||||
:entries="globalNavigation"
|
:entries="globalNavigation"
|
||||||
@refresh="requestManualRefresh"
|
@refresh="requestManualRefresh"
|
||||||
@toggle-realtime="dashboard.setRealtimeEnabled(!realtimeEnabled)"
|
@toggle-realtime="dashboard.setRealtimeEnabled(!realtimeEnabled)"
|
||||||
@lobby="moveLobby"
|
|
||||||
@quick="moveQuick"
|
@quick="moveQuick"
|
||||||
@action="handleNavigationAction"
|
@action="handleNavigationAction"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user