feat(game-ui): add action feedback layer

This commit is contained in:
2026-08-12 15:56:58 +00:00
parent 5e80a940d4
commit 5d4d5009ee
15 changed files with 671 additions and 50 deletions
+38 -9
View File
@@ -392,7 +392,7 @@ test('uses the ref 500px responsive form widths', async ({ page }) => {
await expect(page.getByRole('heading', { name: '기밀실' })).toBeVisible();
});
test('retains article and comment input after a failed mutation, then reloads after success', async ({ page }) => {
test('retains article and comment input after a failed mutation, then reloads after success', async ({ page }, testInfo) => {
const state: BoardFixture = {
permission: 2,
canMeeting: true,
@@ -407,25 +407,54 @@ test('retains article and comment input after a failed mutation, then reloads af
await page.locator('#board-title').fill('새 제목');
await page.locator('#board-content').fill('새 내용');
page.once('dialog', async (dialog) => {
expect(dialog.message()).toBe('실패했습니다. :접속 제한입니다.');
await dialog.accept();
});
await page.locator('#submitArticle').click();
const articleToast = page.getByTestId('game-toast').filter({ hasText: '게시물 등록에 실패했습니다: 접속 제한입니다.' });
await expect(articleToast).toHaveAttribute('data-feedback-kind', 'error');
await expect(articleToast).toHaveAttribute('role', 'alert');
await expect(page.locator('#board-title')).toHaveValue('새 제목');
await expect(page.locator('#board-content')).toHaveValue('새 내용');
const desktopToastGeometry = await articleToast.evaluate((element) => {
const rect = element.getBoundingClientRect();
return { left: rect.left, right: rect.right, top: rect.top, width: rect.width, viewportWidth: window.innerWidth };
});
expect(desktopToastGeometry.left).toBeGreaterThanOrEqual(0);
expect(desktopToastGeometry.right).toBeLessThanOrEqual(desktopToastGeometry.viewportWidth);
expect(desktopToastGeometry.top).toBeGreaterThanOrEqual(0);
expect(desktopToastGeometry.width).toBeGreaterThan(250);
await page.screenshot({ path: testInfo.outputPath('game-toast-desktop.png'), fullPage: true });
await articleToast.getByRole('button', { name: '알림 닫기' }).click();
await expect(articleToast).toHaveCount(0);
await page.locator('#submitArticle').click();
await expect(page.getByText('새 제목', { exact: true })).toBeVisible();
await expect(page.locator('#board-title')).toHaveValue('');
const commentInput = page.locator('.comment-input').first();
await commentInput.fill('새 댓글');
page.once('dialog', async (dialog) => {
expect(dialog.message()).toBe('실패했습니다: 접속 제한입니다.');
await dialog.accept();
});
await page.setViewportSize({ width: 390, height: 844 });
const documentWidthBeforeToast = await page.evaluate(() => document.documentElement.scrollWidth);
await commentInput.press('Enter');
const commentToast = page.getByTestId('game-toast').filter({ hasText: '댓글 등록에 실패했습니다: 접속 제한입니다.' });
await expect(commentToast).toBeVisible();
await expect
.poll(async () => commentToast.evaluate((element) => window.innerHeight - element.getBoundingClientRect().bottom))
.toBeGreaterThanOrEqual(0);
const mobileToastGeometry = await commentToast.evaluate((element) => {
const rect = element.getBoundingClientRect();
return {
left: rect.left,
right: window.innerWidth - rect.right,
bottom: window.innerHeight - rect.bottom,
viewportWidth: window.innerWidth,
documentWidth: document.documentElement.scrollWidth,
};
});
expect(mobileToastGeometry.left).toBeGreaterThanOrEqual(0);
expect(mobileToastGeometry.right).toBeGreaterThanOrEqual(0);
expect(mobileToastGeometry.bottom).toBeGreaterThanOrEqual(0);
expect(mobileToastGeometry.documentWidth).toBe(documentWidthBeforeToast);
await page.screenshot({ path: testInfo.outputPath('game-toast-mobile.png') });
await expect(commentInput).toHaveValue('새 댓글');
await commentInput.press('Enter');