From 62f4ca3058e858f4508c6a4aad8fcef5a08ed230 Mon Sep 17 00:00:00 2001 From: hided62 Date: Mon, 14 Sep 2026 15:09:42 +0000 Subject: [PATCH] =?UTF-8?q?=ED=86=A0=EB=84=88=EB=A8=BC=ED=8A=B8=20?= =?UTF-8?q?=EB=8C=80=EC=A7=84=20=EC=9E=A5=EC=88=98=EC=97=90=20=EB=8A=A5?= =?UTF-8?q?=EB=A0=A5=EC=B9=98=EC=99=80=20=EB=B0=B0=EB=8B=B9=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../e2e/tournamentBracket.spec.ts | 58 +++++++++++++++++++ .../tournament/TournamentBracket.vue | 34 +++++++++-- .../src/views/TournamentView.vue | 4 +- 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/app/game-frontend/e2e/tournamentBracket.spec.ts b/app/game-frontend/e2e/tournamentBracket.spec.ts index 672607b2..ac53b4f8 100644 --- a/app/game-frontend/e2e/tournamentBracket.spec.ts +++ b/app/game-frontend/e2e/tournamentBracket.spec.ts @@ -1177,3 +1177,61 @@ test('closed betting keeps investment and return visible without submit controls await page.getByRole('tab', { name: '16강', exact: true }).click(); } }); + +for (const width of [1365, 801, 390, 320]) { + test(`tournament candidates show stat and live odds at ${width}px`, async ({ page }, testInfo) => { + await page.setViewportSize({ width, height: 900 }); + const realtimeState = { tournamentStage: 7, totalAmount: 2800 }; + await installFixture(page, { tournamentType: 3, tournamentStage: 7, realtimeState }); + await page.goto('tournament'); + await page.waitForLoadState('networkidle'); + await page.evaluate(() => document.fonts.ready); + const bracket = page.locator(width > 800 ? '.desktop-bracket' : '.mobile-bracket'); + const cards = bracket.locator(width > 800 ? '.desktop-bracket-name' : '.mobile-bracket-name'); + await expect(cards.first().locator('.bracket-core-stat')).toHaveText('지력 80'); + await expect(cards.first().locator('.bracket-odds')).toHaveText('배당 28.00'); + const geometry = await cards.evaluateAll((elements) => + elements.map((card) => ({ + card: card.getBoundingClientRect().toJSON(), + fields: [ + ...card.querySelectorAll( + '.general-identity-icon, .general-identity-name, .bracket-core-stat, .bracket-odds' + ), + ].map((el) => ({ + className: el.className, + rect: el.getBoundingClientRect().toJSON(), + fontSize: getComputedStyle(el).fontSize, + scrollWidth: el.scrollWidth, + clientWidth: el.clientWidth, + })), + })) + ); + for (const { card, fields } of geometry) { + for (const field of fields) { + expect(field.rect.left).toBeGreaterThanOrEqual(card.left); + expect(field.rect.right).toBeLessThanOrEqual(card.right); + expect(field.rect.top).toBeGreaterThanOrEqual(card.top); + expect(field.rect.bottom).toBeLessThanOrEqual(card.bottom); + if (field.className === 'general-identity-icon') expect(field.rect.width).toBe(64); + if (field.className === 'bracket-core-stat' || field.className === 'bracket-odds') { + expect(field.fontSize).toBe('14px'); + expect(field.scrollWidth).toBeLessThanOrEqual(field.clientWidth + 1); + } + } + } + await writeFile(testInfo.outputPath('tournament-info-geometry.json'), JSON.stringify(geometry, null, 2)); + await writeFile(testInfo.outputPath('tournament-info-dom.html'), await bracket.evaluate((el) => el.outerHTML)); + await page.screenshot({ path: testInfo.outputPath('tournament-info.png'), fullPage: true }); + if (width <= 800) { + for (const label of ['8강', '4강', '결승', '우승']) { + await bracket.getByRole('tab', { name: label, exact: true }).click(); + await expect(cards.first().locator('.bracket-core-stat')).toHaveText('지력 80'); + await expect(cards.first().locator('.bracket-odds')).toHaveText('배당 28.00'); + } + } + realtimeState.totalAmount = 5600; + await page.getByRole('button', { name: '갱신', exact: true }).click(); + await expect(cards.first().locator('.bracket-odds')).toHaveText('배당 56.00'); + expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(width); + }); +} diff --git a/app/game-frontend/src/components/tournament/TournamentBracket.vue b/app/game-frontend/src/components/tournament/TournamentBracket.vue index a55296c7..19cabf37 100644 --- a/app/game-frontend/src/components/tournament/TournamentBracket.vue +++ b/app/game-frontend/src/components/tournament/TournamentBracket.vue @@ -81,7 +81,7 @@ const connections = computed(() => ); const odds = (id: number | null) => { - if (id === null) return '0'; + if (id === null || props.betTotals === undefined) return '-'; const amount = props.betTotals?.[id] ?? 0; if (!amount) return '∞'; return (props.totalBet / amount).toFixed(2); @@ -158,11 +158,19 @@ const mobilePairs = computed(() => { }" > + > + + { :data-general-id="slot.id ?? undefined" > -