You're an engineer on the CoderX Games team. Yesterday your teammate shipped the new Tic-Tac-Toe widget, and QA filed a bug ticket right away: "Clicks don't behave — the first square seems to do nothing, and later moves look like they land in the wrong square. Games never reach a winner or a draw."
Your job: dig through the codebase, find the wiring bug, and fix it so the game plays correctly.
The widget is split across a few modules, the same way the real feature repo is laid out:
src/components/Square.jsx — renders a single playable cell (button.square).
src/components/Board.jsx — renders the 3x3 grid of Square cells and reports clicks.
src/utils/winner.js — computeWinner(squares) returns 'X', 'O', or null.
src/App.jsx — owns the game state: the board array, whose turn it is, who won, and draw detection.
When the bug is fixed, the widget must behave like this:
- A 3x3 board of empty cells renders on load.
- Clicking an empty cell writes the current player's mark (
X starts).
- Players alternate — every click flips the turn from
X to O and back.
- A cell that already has a mark can never be overwritten (and the turn doesn't change).
- A winning line — any row, column, or diagonal — ends the game, the status reads
Winner: X / Winner: O, and further clicks are ignored.
- When all nine cells are filled with no winner, the status reads
Draw.
All six behaviors above are checked by the hidden test suite — make them all pass.
Notes
- Don't rename files, the exported
App, the square class names, the data-testids (board, status, cell-0 … cell-8), or the markup structure — the tests locate cells through them.
- The win-detection and turn logic in
App.jsx / utils/winner.js are correct; the defect lives in how the board reports which cell was clicked. Trace the index from a click through to handleCellClick before touching anything else.
- The initial render must keep working — an empty, legible 3x3 grid, no crashes.