feat: 장수 계략 명령 전체를 Ref 호환 이관

화계에 묶여 있던 공통 확률·난수·비용·성장 처리를 계략 기반 명령으로 분리한다.

선동·탈취·파괴·화계를 기본 프로필과 계략 분류에 등록하고 Ref 실제 실행, 능력치 상승, 모바일 Chromium 검증을 추가한다.
This commit is contained in:
2026-08-15 19:11:14 +00:00
parent 7b1aa3b179
commit bf2f18aec9
15 changed files with 1050 additions and 1042 deletions
@@ -69,29 +69,36 @@ test('reserves an argument command in the real game API and reads it back from P
try {
await page.goto('/');
await expect(page.getByRole('heading', { name: '전장 현황' })).toBeVisible();
await page.getByRole('button', { name: '계략', exact: true }).click();
await page.getByRole('button', { name: /화계/ }).click();
const form = page.getByTestId('command-argument-form');
await expect(form).toBeVisible();
const citySelect = form.locator('select');
const optionValues = await citySelect
.locator('option')
.evaluateAll((options) => options.map((option) => (option as HTMLOptionElement).value));
const targetCityId = Number(optionValues.find((value) => Number(value) !== context.general.cityId));
expect(targetCityId).toBeGreaterThan(0);
await citySelect.selectOption(String(targetCityId));
const generalSection = page.locator('.reserved-section').filter({ hasText: '일반 예턴' });
const lastTurn = generalSection.locator('.reserved-item').nth(29);
await lastTurn.getByRole('button', { name: '배치' }).click();
await expect(lastTurn.locator('.turn-action')).toHaveText('che_화계');
const form = page.getByTestId('command-argument-form');
for (const strategy of [
{ key: 'che_선동', name: '선동' },
{ key: 'che_탈취', name: '탈취' },
{ key: 'che_파괴', name: '파괴' },
{ key: 'che_화계', name: '화계' },
]) {
await page.getByRole('button', { name: '계략', exact: true }).click();
await page.getByRole('button', { name: new RegExp(strategy.name) }).click();
await expect(form).toBeVisible();
const citySelect = form.locator('select');
const optionValues = await citySelect
.locator('option')
.evaluateAll((options) => options.map((option) => (option as HTMLOptionElement).value));
const targetCityId = Number(optionValues.find((value) => Number(value) !== context.general.cityId));
expect(targetCityId).toBeGreaterThan(0);
await citySelect.selectOption(String(targetCityId));
const persisted = (await game.turns.reserved.getGeneral.query({ generalId })).turns[29];
expect(persisted).toEqual({
index: 29,
action: 'che_화계',
args: { destCityId: targetCityId },
});
await lastTurn.getByRole('button', { name: '배치' }).click();
await expect(lastTurn.locator('.turn-action')).toHaveText(strategy.key);
const persisted = (await game.turns.reserved.getGeneral.query({ generalId })).turns[29];
expect(persisted).toEqual({
index: 29,
action: strategy.key,
args: { destCityId: targetCityId },
});
}
await page.getByRole('button', { name: '국가:인사', exact: true }).click();
await page.getByRole('button', { name: /포상/ }).click();