fix(tests): assert against rendered lastDetail panel instead of nc.log in horde combat tests
The old assertions targeted nc.log, which the component never renders. Updated to assert against the rendered lastDetail panel, and use fake timers to handle the setTimeout-deferred turn advancement.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import DeathwatchRoller from '../components/DeathwatchRoller';
|
||||
|
||||
jest.setTimeout(20000);
|
||||
jest.setTimeout(30000);
|
||||
|
||||
const mockPlayers = [
|
||||
{
|
||||
@@ -68,20 +68,41 @@ function mockFetch(url) {
|
||||
return Promise.resolve({ ok: false, status: 404, json: () => Promise.resolve({}) });
|
||||
}
|
||||
|
||||
function makeRandomSequence() {
|
||||
const seq = [];
|
||||
// startCombat: 4 player init dice + 1 enemy init die
|
||||
seq.push(0.89, 0.69, 0.49, 0.29, 0.09);
|
||||
// Roll 1: Alpha attacks (d100 + 2d10 + uid)
|
||||
seq.push(0.30, 0.50, 0.50, 0.50);
|
||||
// Roll 2: Bravo attacks (d100 + 2d10 + uid)
|
||||
seq.push(0.40, 0.50, 0.50, 0.50);
|
||||
// Roll 3: Charlie attacks (d100 + 1d10 + uid)
|
||||
seq.push(0.50, 0.50, 0.50);
|
||||
// Roll 4: Delta attacks (d100 + 1d10 + uid)
|
||||
seq.push(0.40, 0.50, 0.50);
|
||||
// Roll 5: Horde attacks (d100 reaction + 1d10 damage + uid)
|
||||
seq.push(0.60, 0.50, 0.50);
|
||||
// Pad
|
||||
for (let i = seq.length; i < 100; i++) seq.push(0.50);
|
||||
return seq;
|
||||
}
|
||||
|
||||
describe('DeathwatchRoller horde combat', () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
fetch.mockImplementation(mockFetch);
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
jest.useRealTimers();
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
test('runs 4 players against 5 horde setups with working roll progression', async () => {
|
||||
for (const horde of mockHordes) {
|
||||
const randomValues = [0.8, 0.6, 0.4, 0.2, 0.0];
|
||||
const randomValues = makeRandomSequence();
|
||||
jest.spyOn(Math, 'random').mockImplementation(() => (randomValues.length ? randomValues.shift() : 0.5));
|
||||
|
||||
const { unmount } = render(<DeathwatchRoller authedPlayer="gm" />);
|
||||
@@ -104,24 +125,44 @@ describe('DeathwatchRoller horde combat', () => {
|
||||
await waitFor(() => expect(screen.getByText(`Horde Combat: ${horde.name}`)).toBeInTheDocument());
|
||||
expect(screen.getAllByText(/Round 1/).length).toBeGreaterThan(0);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
// Roll 1: Alpha attacks (highest initiative), then advances to Bravo
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
jest.runAllTimers();
|
||||
});
|
||||
await waitFor(() => expect(screen.getAllByText(/Bravo's turn/i).length).toBeGreaterThan(0));
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
// Roll 2: Bravo attacks, then advances to Charlie
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
jest.runAllTimers();
|
||||
});
|
||||
await waitFor(() => expect(screen.getAllByText(/Charlie's turn/i).length).toBeGreaterThan(0));
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
// Roll 3: Charlie attacks, then advances to Delta
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
jest.runAllTimers();
|
||||
});
|
||||
await waitFor(() => expect(screen.getAllByText(/Delta's turn/i).length).toBeGreaterThan(0));
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
// Roll 4: Delta attacks, then advances to horde's turn
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
jest.runAllTimers();
|
||||
});
|
||||
await waitFor(() => expect(screen.getAllByText(new RegExp(`${horde.name}'s turn`, 'i')).length).toBeGreaterThan(0));
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
// Roll 5: Horde attacks, then advances back to Alpha (Round 2)
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
jest.runAllTimers();
|
||||
});
|
||||
await waitFor(() => expect(screen.getAllByText(/Alpha's turn/i).length).toBeGreaterThan(0));
|
||||
|
||||
// Verify the roll history has accumulated entries from the combat
|
||||
await waitFor(() => {
|
||||
expect(screen.getAllByText(new RegExp(`Alpha attacks|Bravo attacks|Charlie attacks|Delta attacks`, 'i')).length).toBeGreaterThan(0);
|
||||
expect(screen.getByText(new RegExp(`${horde.name} hits`, 'i'))).toBeInTheDocument();
|
||||
expect(screen.getAllByText(/Bolter|Bolt Pistol|Plasma Gun|Chainsword/i).length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
unmount();
|
||||
@@ -129,4 +170,4 @@ describe('DeathwatchRoller horde combat', () => {
|
||||
fetch.mockImplementation(mockFetch);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import DeathwatchRoller from '../components/DeathwatchRoller';
|
||||
|
||||
const mockRoster = [
|
||||
@@ -56,19 +56,31 @@ function mockFetch(url) {
|
||||
return Promise.resolve({ ok: false, status: 404, json: () => Promise.resolve({}) });
|
||||
}
|
||||
|
||||
function makeRandomSequence() {
|
||||
const seq = [];
|
||||
// startCombat: 2 player init dice + 1 enemy init die
|
||||
seq.push(0.90, 0.70, 0.10);
|
||||
// Roll 1: player1 attacks (d100 + damage dice + uid)
|
||||
seq.push(0.30, 0.50, 0.50, 0.50);
|
||||
for (let i = seq.length; i < 100; i++) seq.push(0.50);
|
||||
return seq;
|
||||
}
|
||||
|
||||
describe('DeathwatchRoller horde combat player main weapon handling', () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
fetch.mockImplementation(mockFetch);
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
jest.useRealTimers();
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
test('uses the player main weapon with sanitized damage and working roll progression', async () => {
|
||||
const randomValues = [0.3, 0.2, 0.1, 0.0, 0.4, 0.5, 0.6];
|
||||
const randomValues = makeRandomSequence();
|
||||
jest.spyOn(Math, 'random').mockImplementation(() => (randomValues.length ? randomValues.shift() : 0.5));
|
||||
|
||||
render(<DeathwatchRoller authedPlayer="player1" />);
|
||||
@@ -92,12 +104,14 @@ describe('DeathwatchRoller horde combat player main weapon handling', () => {
|
||||
expect(screen.getByText('Thunder Hammer')).toBeInTheDocument();
|
||||
expect(screen.getByText('2d10+8')).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Roll' }));
|
||||
jest.runAllTimers();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/player1 attacks with Thunder Hammer/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/vs 55 WS/i)).toBeInTheDocument();
|
||||
expect(screen.getAllByText(/player2's turn/i).length).toBeGreaterThan(0);
|
||||
expect(screen.getByText(/Attack \d+ vs \d+ (WS|BS)/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user