spymaster-dev-b / docs /dev_b_prd.md
Danisz's picture
feat(browser): refactor handler API, add internal tests, update docs and types
19c41e0
|
Raw History Blame Contribute Delete
10.1 kB
# **PRD – Dev B: Browser Layer (Playwright Interaction)**
This document defines the requirements and approach for the Browser Layer, whose sole purpose is to automate and interact with Codenames.game using Playwright. The goal is to provide a clean, reliable API for the Server Layer, focusing on robust automation and maintainability. Simplicity is paramount: the implementation should avoid unnecessary complexity, use clear abstractions, and prioritize ease of understanding and modification.
---
## 1 β€’ Goal
To implement the **Browser Layer** module responsible for interacting with the Codenames.game website using Playwright. This layer will encapsulate all browser automation logic, exposing a clean API for the Server Layer to consume.
---
## 2 β€’ Key Technologies
- **Playwright:** For browser automation and interaction.
- **Chromium:** The target browser controlled by Playwright.
- **Node.js & TypeScript:** For the implementation environment.
- **`ICodenamesBrowser` Interface:** The contract defining the API exposed to the Server Layer.
---
## 2.1 β€’ API Abstraction & Testing Philosophy
The Browser Layer must expose a **technology-agnostic API** (see `ICodenamesGameAPI` in `shared/types.ts`). This API should only describe game concepts and actions, not how they are implemented.
**Why?**
- This abstraction allows the underlying implementation to change (e.g., switching from Playwright to a Bridge) without breaking the contract with the Server Layer.
- It enables robust, maintainable tests:
- **Public API tests** (in `handler.test.ts`) validate only observable game behavior, not implementation details.
**Benefits:**
- Implementation-agnostic, future-proof API
- Robust, maintainable test suite
- Clear separation of concerns
---
## 3 β€’ Responsibilities & Deliverables
- **Implement Playwright Logic:**
- Launch and manage a Chromium browser instance.
- Navigate to the Codenames.game website and handle room joining/setup if necessary.
- Reliably scrape the DOM to extract current game state (board words, team turn, etc.).
- Execute game actions based on API calls (e.g., clicking clue input, typing clue, clicking words, clicking end turn button).
- **Expose API:**
- Implement the `ICodenamesBrowser` interface (defined in `shared/types.ts` or agreed upon with Dev A). This interface will serve as the contract between the Browser and Server layers.
- **Testing:**
- Develop unit and integration tests within the `browser/tests/` directory to verify Playwright interactions, selectors, and state extraction logic independently.
- **Deliverables:**
- `browser/handler.ts`: Core implementation of the browser interaction logic and API.
- `browser/selectors.ts`: (Optional but recommended) Centralized repository for CSS/XPath selectors to mitigate UI change risks.
- `browser/tests/`: Unit and integration tests for the Browser Layer.
---
## 4 β€’ `ICodenamesBrowser` Interface (Contract)
*(To be finalized and agreed upon with Dev A)*
This interface defines the methods the Server Layer will call. Example methods might include:
```typescript
interface ICodenamesBrowser {
launchBrowser(options?: any): Promise<void>;
closeBrowser(): Promise<void>;
navigateToGame(url: string): Promise<void>;
getBoardState(): Promise<BoardState>; // Define BoardState structure
getTeamTurn(): Promise<'red' | 'blue'>;
submitClue(clue: string, count: number): Promise<void>;
makeGuess(word: string): Promise<void>;
endTurn(): Promise<void>;
// ... other necessary methods
}
```
---
## 5 β€’ Suggested Folder Structure (Focus Area)
```
spymaster/ # cwd
β”œβ”€β”€ browser/ # <-- Your primary focus
β”‚ β”œβ”€β”€ handler.ts # Core implementation
β”‚ β”œβ”€β”€ selectors.ts # (Optional) Selector definitions
β”‚ └── tests/ # Unit/integration tests
β”œβ”€β”€ shared/ # For shared types like ICodenamesBrowser
β”‚ └── types.ts
β”œβ”€β”€ ... (other project files)
```
---
## 6 β€’ Development Steps
1. **Setup & Interface Agreement:**
- Set up the `browser/` directory structure.
- **Critically:** Collaborate with Dev A to finalize and agree on the `ICodenamesBrowser` interface definition. This is your contract.
2. **Independent Implementation:**
- Implement the `browser/handler.ts` class/functions to fulfill the `ICodenamesBrowser` interface.
- Focus on robust Playwright scripting:
- Use reliable selectors (consider `browser/selectors.ts`).
- Handle potential timing issues (waits, retries).
- Implement state scraping logic.
- Implement action execution logic.
3. **Local Testing:**
- Write and run unit/integration tests in `browser/tests/` to verify your Playwright code directly against a live or mock Codenames game instance. Ensure state is scraped correctly and actions execute as expected.
4. **Integration & Debugging:**
- Once Dev A has a functional Server Layer and the project is built/linked (`npm run build`, `npm link`), participate in E2E testing initiated via `npx your-package-name`.
- Debug any Playwright-related issues (selector changes, timing problems, incorrect state) identified during E2E testing.
---
## 7 β€’ Testing Approach
- **Primary:** Unit and integration tests (`browser/tests/`) are crucial for verifying the core Playwright logic without relying on the full MCP stack. Use these to test:
- Browser launching and navigation.
- Accuracy of DOM scraping and state extraction.
- Correct execution of clicks, typing, etc.
- **Secondary:** Participate in E2E testing led by Dev A using MCP Inspector against the `npx`-launched application to catch integration issues.
### 7.1 β€’ Testing Environment: Explicit Requirements
- **Single, Always-Live Test Room:**
- All Playwright tests in `browser/tests/` must use the same, pre-designated Codenames.game room for all test runs.
- The test room must be referred to by its room code only (e.g., `web-bean-lip`), not the full URL.
- The base URL must be set in the environment variable `CODENAMES_BASE_URL` (e.g., `https://codenames.game/room/`).
- The room code must be set in the environment variable `CODENAMES_TEST_ROOM_CODE` (e.g., `web-bean-lip`).
- Tests must construct the full room URL by concatenating `CODENAMES_BASE_URL` and `CODENAMES_TEST_ROOM_CODE`.
- The test room is always live and shared.
- Each test suite must use a `beforeAll` hook to:
- Set up the Playwright browser and page.
- Navigate to the constructed room URL.
- Join the room as needed.
- Each test suite must use an `afterAll` hook to:
- Leave the room if possible.
- Close the page and the Playwright browser.
- The setup and teardown logic used in `beforeAll` and `afterAll` must be extracted into reusable functions (e.g., `setupBrowserAndJoinRoom`, `leaveRoomAndTeardownBrowser`). These functions must be tested independently in dedicated test files to ensure reliability and debuggability.
- Note: The file `test-assets/playwright/join_room.test.ts` exists and performs room join and clue actions. This test must not be run during the Dev B process, as it may interfere with the shared test room and ongoing development or testing activities. However, it can serve as a valuable reference for implementing Playwright-based room interaction and automation logic.
- **Robustness to Unknown State:**
- Tests must be written to handle any possible state the room may be in at the start of the test (e.g., in-progress game, finished game, unexpected board/clue log).
- Where possible, tests should attempt to bring the room to a desired state by interacting with the UI (e.g., clicking "New Game"), but must not assume this always succeeds or is possible.
- Tests must be resilient to failures due to unexpected room state and should log the current state at the start of each test for debugging.
- **Documentation:**
- Add a `browser/tests/README.md` that:
- Specifies that the test room code is configured via the `CODENAMES_TEST_ROOM_CODE` environment variable.
- Specifies that the base URL is configured via the `CODENAMES_BASE_URL` environment variable.
- Describes any manual steps required to prepare the room for testing.
- Provides a step-by-step guide for running tests locally.
---
## 8 β€’ Key Risks & Mitigations
- **Codenames.game UI Changes:** Selectors breaking is the highest risk.
- **Mitigation:**
- Use stable selector strategies (IDs where possible, robust CSS/XPath).
- Centralize selectors in `browser/selectors.ts` for easier updates.
- Rely on comprehensive tests (`browser/tests/`) to catch breakages quickly.
- **Race Conditions/Timing Issues:** Playwright actions failing due to the web page not being ready.
- **Mitigation:** Use Playwright's built-in auto-waits, explicit waits (`waitForSelector`, `waitForFunction`), and potentially retry logic where appropriate.
- **Interface Mismatch:** Browser Layer implementation deviating from the agreed `ICodenamesBrowser` interface.
- **Mitigation:** Strict adherence to the TypeScript interface definition. Early and frequent communication with Dev A if changes seem necessary.
---
## 9 β€’ Acceptance Criteria
- The `browser/handler.ts` module successfully implements all methods defined in the agreed-upon `ICodenamesBrowser` interface.
- Unit/integration tests in `browser/tests/` pass, demonstrating:
- Successful browser launch and navigation to Codenames.game.
- Accurate retrieval of game state (board, turn, clues) via API methods.
- Successful execution of game actions (giving clue, making guess, ending turn) via API methods.
- During E2E testing (run via `npx your-package-name`), the Browser Layer correctly responds to Server Layer requests initiated via MCP Inspector, reflecting accurate game state and performing actions in the Chromium window.
- Code is well-structured, potentially using `browser/selectors.ts` for maintainability.