# **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; closeBrowser(): Promise; navigateToGame(url: string): Promise; getBoardState(): Promise; // Define BoardState structure getTeamTurn(): Promise<'red' | 'blue'>; submitClue(clue: string, count: number): Promise; makeGuess(word: string): Promise; endTurn(): Promise; // ... 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.