This commit is contained in:
Bastian Wagner
2026-08-19 23:42:18 +02:00
parent fd9852bfbf
commit 67237f5ad8
4 changed files with 175 additions and 5 deletions

View File

@@ -134,17 +134,23 @@ describe('CombatPageComponent', () => {
const element = fixture.nativeElement as HTMLElement;
const sprite = element.querySelector('.sprite--player');
const monster = element.querySelector('.sprite--monster');
const stage = element.querySelector('.combat__stage');
element.querySelector<HTMLButtonElement>('[data-combat-attack]')?.click();
fixture.detectChanges();
expect(sprite?.classList.contains('sprite--attacking')).toBe(true);
expect(monster?.classList.contains('sprite--flinch')).toBe(false);
expect(element.textContent).toContain('31 / 45');
expect(element.textContent).toContain('95 / 100');
// Swing lands: the monster loses HP, the player's own loss is held back.
// Swing lands: the monster loses HP and flinches, its own loss is held back.
await vi.advanceTimersByTimeAsync(540);
fixture.detectChanges();
expect(sprite?.classList.contains('sprite--attacking')).toBe(false);
expect(monster?.classList.contains('sprite--flinch')).toBe(true);
expect(monster?.classList.contains('sprite--lunge')).toBe(false);
expect(stage?.classList.contains('combat__stage--shaken')).toBe(false);
expect(element.textContent).toContain('17 / 45');
expect(element.textContent).toContain('95 / 100');
// Only round 1's identical line is logged so far, not round 2's.
@@ -154,12 +160,17 @@ describe('CombatPageComponent', () => {
await vi.advanceTimersByTimeAsync(260);
fixture.detectChanges();
expect(sprite?.classList.contains('sprite--hit')).toBe(true);
expect(monster?.classList.contains('sprite--lunge')).toBe(true);
expect(monster?.classList.contains('sprite--flinch')).toBe(false);
expect(stage?.classList.contains('combat__stage--shaken')).toBe(true);
expect(element.textContent).toContain('90 / 100');
expect(countOccurrences(element.textContent, monsterHitLine)).toBe(2);
await vi.advanceTimersByTimeAsync(540);
fixture.detectChanges();
expect(sprite?.classList.contains('sprite--hit')).toBe(false);
expect(monster?.classList.contains('sprite--lunge')).toBe(false);
expect(stage?.classList.contains('combat__stage--shaken')).toBe(false);
});
it('skips the recoil when the round ends without the monster striking back', async () => {
@@ -184,9 +195,17 @@ describe('CombatPageComponent', () => {
await vi.advanceTimersByTimeAsync(540);
fixture.detectChanges();
const monster = element.querySelector('.sprite--monster');
expect(element.querySelector('.sprite--player')?.classList.contains('sprite--hit')).toBe(false);
// The killing blow still registers on the monster, it just never lunges back.
expect(monster?.classList.contains('sprite--flinch')).toBe(true);
expect(monster?.classList.contains('sprite--lunge')).toBe(false);
expect(element.querySelector('[data-combat-result="WON"]')).toBeTruthy();
expect(element.textContent).toContain('0 / 45');
await vi.advanceTimersByTimeAsync(800);
fixture.detectChanges();
expect(monster?.classList.contains('sprite--lunge')).toBe(false);
});
it('disables Angriff while an action is pending', async () => {