Skip to content

SergiiVolodkoWorking/TicTacToeOnline

Repository files navigation

TicTacToe Online

Build Status

image

This project implements TicTacToe as a client-server application so the game is playable via browser. Backend made on Elixir and it's web framework Phoenix. Fronted is implemented as a Flux RaectJS site utilizing React-Redux package to manage UI state.

Running the application

To start the game from sourcecode:

  • Navigate to the project's folder via terminal.
  • Install dependencies with mix deps.get
  • Install Node.js dependencies with npm --prefix assets install
  • Start Phoenix endpoint with mix phx.server

You should see something like this in your terminal image

The game is running, visit localhost:4000 from your browser to play.

The solution structure

The folder structure of this project is dictated by 2 major factors:

  1. Our deployment server of choice is Heroku. It demands root folder to have Phoenix application.
  2. Phoenix framework by default creates a folder structure that we see in the project root.

-- lib folder is the folder of our server code

-- assets - the folder with our client's code

-- other folders

---- priv - auto-generated by Phoenix. No changes there

---- config - contains configurations for run environments

-- test - place for our server unit and integration tests

-- tests_e2e - place for end-to-end tests. End-to-end tests are implemented as screenshot testing using Cypress.io framework. This framework also demands certain structure of the folders of our the tests directory.

Architecture

The solution is a client-server application with

  • Traditional RESTful API server having onion structure and written using a functional language
  • Flux client website implemented on ReactJS and React-Redux
  • Read and Write responsibilities are separated
  • Game state machine being distributed between client and server
  • 2-way communication done via polling data by client

Last 3 characteristics are the result of preparing the system for PvP play feature, which, unfortunately, is not in the game yet.

More details on the Architecture wiki page.

image

First of all it is a research project. Some of the outcomes of numerous researches could be found on the corresponding wiki page

Game Client

Is a ReactJS application, managing UI state utilizing Flux structure and React-Redux package.

Responsibilities:

  1. Send user commands (Start game, make move)
  2. Display current game state

Commands are sent via POST and PUT requests to the game server. Current game state is fetched by continuous polling data from the server via GET requests.

Folder structure

Client source code is in the assets folder of the solution.

  • It's js folder contains all the ReactJS components.
  • app.js is the entry point of the client.
  • /js/components - folder with actual components/screens.
  • Folders reducers, containers, actions contains React-Redux serving parts
  • /assets/css/app.css the file with our custom. css styles.

Important moment: Due to Phoenix specifics, app.js must have row import appCss from './../css/app.css' in order to hook up our custom styles.

More details on the Game client wiki page

Game Server

Is a webserver implemented using Elixir language and it's web framework Phoenix. Server designed in a layered manner, keeping all workers with side effects on the outer isolating them from workers with pure domain logic.

Responsibilities:

  1. Execute commands and change game state accordingly
  2. Persist current game state

Folder structure

Due to Phoenix template server logic is located in lib folder. And split between 2 nested folders:

  • tictactoe - Pure domain logic
  • tictactoe_web - Phoenix infrastructure and controllers

Server API

Endpoint
POST /start_game
GET /game/{game_id}
PUT /make_move/{game_id}
GET /version

Routing is defined in /tictactoe_web/router.ex So in case of adding new endpoints, this file must be also extended.

More details on the Game server wiki page

Testing

The system is covered with 3 types of tests.

image

From bottom to top

Unit and Integration tests

Are covering server-side domain and side-effects logic.

The tests are located in the test folder in tictactoe and tictactoe_web directories. The tests doesn't use any mocks but quite extensively use randomized fakes defined in test_helper.exs

To run the tests

  • Navigate to the project's folder via terminal.
  • Install dependencies with mix deps.get
  • Start Phoenix endpoint with mix test

End-to-end scenarios

Are the highest level tests in the solution. They run against the UI simulating complete use cases.

These tests has a bit more complicated infrastructure, since they need a UI testing framework. Our framework of choice is cypress.io.

Important, that the tests are the snapshot tests, meaning that that they preform some actions with the UI, than taking a screenshot and compare it with approved images. It makes tests text plain and simple, but unfortunately this kind of tests if very fragile when they executed by CI\CD pipeline.

There are 2 ways to run our scenarios

  1. Download cypress.io

-- Open test_e2e folder in project from cypress application

-- Run all tests

  1. Run via terminals

-- In first terminal instance start our server as it is described in the Running the application section

-- Open second terminal instance and:

--- Navigate to test_e2e folder of the project

--- Install required dependencies npm install

--- Execute tests npx cypress run

More details on the Testing wiki page

Deployment pipeline

The app is deployed to Heroku servers. In order to deploy a Phoenix app elixir_buildpack.config is needed

Our CI/CD server of choice is Travis Solution's deployment script is .travis.yml And since our end-to-end tests are doing snapshot comparisons, deployment script uses another bash script upload_screenshots.sh to provide developers with resulting screenshots and differences in case of failures.

About

New revolutionary online version of legendary TicTacToe game!

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published