merge: 최신 main을 모바일 터치 드래그 브랜치에 통합
This commit is contained in:
@@ -953,9 +953,7 @@ test('shows and reserves the Ref spy command for a user on desktop and mobile',
|
||||
await expect(spy).toBeFocused();
|
||||
await spy.click();
|
||||
const form = picker.getByTestId('command-argument-form');
|
||||
await expect(form.getByTestId('command-argument-guidance')).toContainText(
|
||||
'선택한 도시에 첩보를 실행합니다.'
|
||||
);
|
||||
await expect(form.getByTestId('command-argument-guidance')).toContainText('선택한 도시에 첩보를 실행합니다.');
|
||||
await expect(form.getByTestId('command-argument-guidance')).toContainText(
|
||||
'인접 도시에서는 더 많은 정보를 얻습니다.'
|
||||
);
|
||||
@@ -979,9 +977,7 @@ test('shows and reserves the Ref spy command for a user on desktop and mobile',
|
||||
await picker.screenshot({ path: test.info().outputPath('spy-command-mobile-500.png') });
|
||||
});
|
||||
|
||||
test('defaults founding to a Ref-selectable nation trait and paints color option labels', async ({
|
||||
page,
|
||||
}) => {
|
||||
test('defaults founding to a Ref-selectable nation trait and paints color option labels', async ({ page }) => {
|
||||
const foundingColors = [
|
||||
{ value: 0, label: '색상 1', color: '#FF0000' },
|
||||
{ value: 15, label: '색상 16', color: '#6495ED' },
|
||||
@@ -1284,7 +1280,9 @@ test('keeps general and chief command categories after input and across page rel
|
||||
const reloadedChiefPicker = chiefPage.getByTestId('command-picker');
|
||||
await expect(reloadedChiefPicker.getByRole('button', { name: '전략', exact: true })).toHaveClass(/active/);
|
||||
await expect(reloadedChiefPicker.getByRole('button', { name: '필사즉생', exact: true })).toBeVisible();
|
||||
await expect.poll(() => reloadedChiefPicker.evaluate((element) => element.getBoundingClientRect().height)).toBeGreaterThan(200);
|
||||
await expect
|
||||
.poll(() => reloadedChiefPicker.evaluate((element) => element.getBoundingClientRect().height))
|
||||
.toBeGreaterThan(200);
|
||||
await reloadedChiefPicker.screenshot({
|
||||
path: test.info().outputPath('chief-category-after-reload-mobile-500.png'),
|
||||
});
|
||||
@@ -1825,6 +1823,61 @@ test('shows city or capital maps for every requested chief command', async ({ pa
|
||||
await page.screenshot({ path: test.info().outputPath('chief-command-map-guidance.png'), fullPage: true });
|
||||
});
|
||||
|
||||
test('prioritizes own cities for assignment while retaining other map targets', async ({ page }) => {
|
||||
const assignmentTable = structuredClone(commandTable);
|
||||
assignmentTable.inputOptions.cities = [
|
||||
{ value: 2, label: '허창 (적국)', description: '적국 · 예주 · 대도시' },
|
||||
{ value: 3, label: '단양 (무주)' },
|
||||
{ value: 1, label: '업 (아국)' },
|
||||
];
|
||||
|
||||
await install(page, false, assignmentTable);
|
||||
await page.setViewportSize({ width: 1200, height: 900 });
|
||||
await page.goto('/che/chief-center');
|
||||
await page.getByRole('button', { name: '1턴 명령 입력', exact: true }).click();
|
||||
const picker = page.getByTestId('command-picker');
|
||||
await picker.getByRole('button', { name: /^(?:국가:)?인사$/, exact: true }).click();
|
||||
await picker.getByRole('button', { name: /발령/ }).click();
|
||||
|
||||
const form = picker.getByTestId('command-argument-form');
|
||||
const citySelect = form.locator('#command-arg-destCityId');
|
||||
await expect(form.getByTestId('command-argument-map')).toBeVisible();
|
||||
await expect(citySelect.locator('option')).toHaveText(['업 (아국)', '허창 (적국)', '단양 (무주)']);
|
||||
await expect(citySelect).toHaveValue('1');
|
||||
|
||||
await form.getByTestId('command-argument-map').locator('.city-base').nth(1).click();
|
||||
await expect(citySelect).toHaveValue('2');
|
||||
await expect(form.getByTestId('command-map-selection-status')).toContainText('선택 도시허창');
|
||||
await expect(page).toHaveURL(/\/che\/chief-center$/);
|
||||
await form.screenshot({ path: test.info().outputPath('chief-assignment-own-city-priority.png') });
|
||||
|
||||
await page.setViewportSize({ width: 500, height: 900 });
|
||||
await page.goto('/che/chief-center');
|
||||
await page.getByRole('button', { name: '1턴 명령 입력', exact: true }).click();
|
||||
const mobilePicker = page.getByTestId('command-picker');
|
||||
await mobilePicker.getByRole('button', { name: /^(?:국가:)?인사$/, exact: true }).click();
|
||||
await mobilePicker.getByRole('button', { name: /발령/ }).click();
|
||||
|
||||
const mobileForm = mobilePicker.getByTestId('command-argument-form');
|
||||
const mobileMap = mobileForm.getByTestId('command-argument-map');
|
||||
const mobileCitySelect = mobileForm.locator('#command-arg-destCityId');
|
||||
await expect(mobileMap).toBeVisible();
|
||||
await expect(mobileCitySelect.locator('option')).toHaveText(['업 (아국)', '허창 (적국)', '단양 (무주)']);
|
||||
const mobileGeometry = await mobilePicker.evaluate((element) => ({
|
||||
width: element.getBoundingClientRect().width,
|
||||
overflow: element.scrollWidth - element.clientWidth,
|
||||
}));
|
||||
expect(mobileGeometry).toEqual({ width: 500, overflow: 0 });
|
||||
const mapGeometry = await mobileMap.locator('.map-area').evaluate((element) => {
|
||||
const rect = element.getBoundingClientRect();
|
||||
return { width: rect.width, height: rect.height };
|
||||
});
|
||||
expect(mapGeometry.width / mapGeometry.height).toBeCloseTo(7 / 5, 2);
|
||||
await mobileMap.screenshot({ path: test.info().outputPath('chief-assignment-map-mobile.png') });
|
||||
await mobileCitySelect.scrollIntoViewIfNeeded();
|
||||
await mobilePicker.screenshot({ path: test.info().outputPath('chief-assignment-own-city-priority-mobile.png') });
|
||||
});
|
||||
|
||||
test('prioritizes current nation targets while preserving every choice', async ({ page }) => {
|
||||
await install(page);
|
||||
await page.setViewportSize({ width: 1200, height: 900 });
|
||||
|
||||
@@ -467,6 +467,112 @@ test('국가 정보의 작위는 Ref 국가 등급 이름으로 표시된다', a
|
||||
await expect(root).not.toContainText('작 위1');
|
||||
});
|
||||
|
||||
test('map keeps desktop hover navigation and lets touch users choose one-tap or two-tap city navigation', async ({
|
||||
browser,
|
||||
page,
|
||||
}, testInfo) => {
|
||||
await install(page);
|
||||
await page.setViewportSize({ width: 1200, height: 900 });
|
||||
await go(page, 'global-info');
|
||||
|
||||
const desktopCity = page.locator('.city-base').first();
|
||||
await expect(page.locator('.map-toggle-single-tap')).toHaveCount(0);
|
||||
await desktopCity.hover();
|
||||
await expect(page.locator('.map-tooltip .tooltip-title')).toHaveText('【하북|특】업');
|
||||
await desktopCity.click();
|
||||
await expect(page).toHaveURL(/\/current-city\?cityId=1$/u);
|
||||
|
||||
const configuredBaseUrl = testInfo.project.use.baseURL;
|
||||
if (typeof configuredBaseUrl !== 'string') {
|
||||
throw new Error('Playwright baseURL is required for the mobile map contract');
|
||||
}
|
||||
const context = await browser.newContext({
|
||||
baseURL: configuredBaseUrl,
|
||||
viewport: { width: 390, height: 844 },
|
||||
screen: { width: 390, height: 844 },
|
||||
deviceScaleFactor: 1,
|
||||
isMobile: true,
|
||||
hasTouch: true,
|
||||
colorScheme: 'dark',
|
||||
});
|
||||
const mobilePage = await context.newPage();
|
||||
|
||||
try {
|
||||
await install(mobilePage);
|
||||
await go(mobilePage, 'global-info');
|
||||
|
||||
const twoTapButton = mobilePage.getByRole('button', { name: '두번 탭 해 도시 이동 끄기' });
|
||||
await expect(twoTapButton).toBeVisible();
|
||||
await expect(twoTapButton).toHaveAttribute('aria-pressed', 'false');
|
||||
const controlGeometry = await twoTapButton.evaluate((element) => {
|
||||
const rect = element.getBoundingClientRect();
|
||||
const mapRect = element.closest('.map-area')?.getBoundingClientRect();
|
||||
const style = getComputedStyle(element);
|
||||
return {
|
||||
right: rect.right,
|
||||
bottom: rect.bottom,
|
||||
mapRight: mapRect?.right,
|
||||
mapBottom: mapRect?.bottom,
|
||||
fontSize: style.fontSize,
|
||||
lineHeight: style.lineHeight,
|
||||
documentWidth: document.documentElement.scrollWidth,
|
||||
viewportWidth: document.documentElement.clientWidth,
|
||||
overflowing: Array.from(document.querySelectorAll<HTMLElement>('body *'))
|
||||
.filter(
|
||||
(candidate) => candidate.getBoundingClientRect().right > document.documentElement.clientWidth
|
||||
)
|
||||
.map((candidate) => ({
|
||||
tag: candidate.tagName,
|
||||
className: candidate.className,
|
||||
right: candidate.getBoundingClientRect().right,
|
||||
}))
|
||||
.slice(0, 8),
|
||||
};
|
||||
});
|
||||
expect(controlGeometry).toMatchObject({
|
||||
fontSize: '11px',
|
||||
lineHeight: '18px',
|
||||
viewportWidth: 500,
|
||||
overflowing: [],
|
||||
});
|
||||
expect(controlGeometry.documentWidth).toBeLessThanOrEqual(controlGeometry.viewportWidth + 1);
|
||||
expect(controlGeometry.mapRight! - controlGeometry.right).toBeCloseTo(4, 1);
|
||||
expect(controlGeometry.mapBottom! - controlGeometry.bottom).toBeCloseTo(4, 1);
|
||||
|
||||
const mobileCities = mobilePage.locator('.city-base');
|
||||
await mobileCities.nth(0).tap();
|
||||
await expect(mobilePage).toHaveURL(/\/global-info$/u);
|
||||
await expect(mobilePage.locator('.map-tooltip .tooltip-title')).toHaveText('【하북|특】업');
|
||||
|
||||
await mobileCities.nth(1).tap();
|
||||
await expect(mobilePage).toHaveURL(/\/global-info$/u);
|
||||
await expect(mobilePage.locator('.map-tooltip .tooltip-title')).toHaveText('【하북|수】성2');
|
||||
await mobilePage.screenshot({ path: testInfo.outputPath('mobile-map-first-tap-tooltip.png'), fullPage: true });
|
||||
|
||||
await mobileCities.nth(1).tap();
|
||||
await expect(mobilePage).toHaveURL(/\/current-city\?cityId=2$/u);
|
||||
|
||||
await go(mobilePage, 'global-info');
|
||||
await mobilePage.getByRole('button', { name: '두번 탭 해 도시 이동 끄기' }).click();
|
||||
const singleTapButton = mobilePage.getByRole('button', { name: '두번 탭 해 도시 이동 켜기' });
|
||||
await expect(singleTapButton).toHaveAttribute('aria-pressed', 'true');
|
||||
expect(await mobilePage.evaluate(() => localStorage.getItem('sam.toggleSingleTap'))).toBe('yes');
|
||||
|
||||
await mobilePage.reload();
|
||||
await expect(singleTapButton).toBeVisible();
|
||||
await mobilePage.locator('.city-base').nth(2).tap();
|
||||
await expect(mobilePage).toHaveURL(/\/current-city\?cityId=3$/u);
|
||||
|
||||
await go(mobilePage, 'global-info');
|
||||
await mobilePage.getByRole('button', { name: '두번 탭 해 도시 이동 켜기' }).click();
|
||||
expect(await mobilePage.evaluate(() => localStorage.getItem('sam.toggleSingleTap'))).toBe('no');
|
||||
await mobilePage.locator('.city-base').first().tap();
|
||||
await expect(mobilePage).toHaveURL(/\/global-info$/u);
|
||||
} finally {
|
||||
await context.close();
|
||||
}
|
||||
});
|
||||
|
||||
test('global-info renders the ref nation summary columns beside the map', async ({ page }) => {
|
||||
await install(page);
|
||||
await page.setViewportSize({ width: 1200, height: 900 });
|
||||
|
||||
Reference in New Issue
Block a user