Phase 4: interactive dice & sheet rolling
- Dice notation: exploding (Nd6!) and reroll-below (Nd6r2), capped + tested - Degrees of success / roll-vs-DC (PF2e ±10 + nat 20/1 steps; 5e crit on nat 20/1) - Global roll tray (shared store + RollTray in layout) with animated result + degree - Roll from the character sheet: skills, saves, and attack to-hit/damage are clickable and post to the tray + history (rollAndShow/rollCheck helpers) - Saved roll macros per campaign (persisted) on the Dice page 10 new unit tests (notation explode/reroll, degrees), interactive-dice e2e. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.evaluate(async () => {
|
||||
indexedDB.deleteDatabase('ttrpg-manager');
|
||||
localStorage.clear();
|
||||
});
|
||||
await page.reload();
|
||||
});
|
||||
|
||||
test('rolling a skill from the sheet shows the roll tray', async ({ page }) => {
|
||||
await page.getByRole('button', { name: '+ New campaign' }).first().click();
|
||||
await page.locator('input[data-autofocus]').fill('Dice Camp');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
await page.getByRole('link', { name: 'Characters' }).click();
|
||||
await page.getByRole('button', { name: '+ New character' }).first().click();
|
||||
await page.locator('input[data-autofocus]').fill('Roller');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
await page.getByRole('link', { name: /Roller/ }).click();
|
||||
|
||||
// Click the Acrobatics modifier to roll it
|
||||
await page.getByTitle('Roll Acrobatics (DEX)').click();
|
||||
// The shared roll tray appears (unique dismiss control) showing the roll
|
||||
await expect(page.getByRole('button', { name: 'Dismiss roll' })).toBeVisible();
|
||||
await expect(page.locator('text=/= \\d+/').first()).toBeVisible();
|
||||
});
|
||||
|
||||
test('dice page: save and use a macro', async ({ page }) => {
|
||||
await page.getByRole('link', { name: 'Dice' }).click();
|
||||
await page.getByLabel('Dice expression').fill('2d6+3');
|
||||
await page.getByRole('button', { name: /Save/ }).click();
|
||||
// Macro chip appears and rolls when clicked
|
||||
const chip = page.getByRole('button', { name: '2d6+3', exact: true });
|
||||
await expect(chip).toBeVisible();
|
||||
await chip.click();
|
||||
await expect(page.locator('text=/= \\d+/').first()).toBeVisible();
|
||||
});
|
||||
Reference in New Issue
Block a user