Selenium for games: automating tic-tac-toe

In anticipation of the start of the " Java QA Automation Engineer " course , we are sharing with you the traditional translation of interesting material.






, Selenium . Selenium, , «», , - (tic-tac-toe) !





, , Selenium .





-

  • Selenium WebDriver





  • -





















-





:

1. Selenium WebDriver





Selenium WebDriver . maven



, pom.xml.





<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.0.0-alpha-5</version>
</dependency>
      
      



2. -





- - — Tic Tac Toe.





1.

enum



() -. Enum . .





package tictactoe;
import org.openqa.selenium.By;
import static java.lang.String.format;
 
public enum Space {
 
    TOP_LEFT("square top left"),
    TOP_CENTER("square top"),
    TOP_RIGHT("square top right"),
    CENTER_LEFT("square left"),
    CENTER_CENTER("square"),
    CENTER_RIGHT("square right"),
    BOTTOM_LEFT("square bottom left"),
    BOTTOM_CENTER("square bottom"),
    BOTTOM_RIGHT("square bottom right");
 
    private String className;
    private By locator;
 
    Space(String className){
        this.className = className;
        locator = By.xpath(format("//div[@class='%s']", className));
    }
 
    public String getClassName(){
        return className;
    }
 
    public By getLocator(){
        return locator;
    }
}
      
      



2.

, . , .





-, ChromeDriver Selenium.





public class Board {
 
    private ChromeDriver driver;
    
    public Board(ChromeDriver driver) {
        this.driver = driver;
    }
}
      
      



, , Map ( ), , , .





public class Board {
 
    private ChromeDriver driver;
    private Map<Space, Boolean> spaces = new HashMap();
 
    public Board(ChromeDriver driver) {
        this.driver = driver;
    }
}
      
      



map Space false, .





public class Board {
 
    private ChromeDriver driver;
    private Map<Space, Boolean> spaces = new HashMap();
 
    public Board(ChromeDriver driver) {
        this.driver = driver;
        Arrays.stream(Space.values()).forEach(space -> spaces.put(space, false));
    }
}
      
      



! , . , , Map.





, , , , . , , CI . .





public void play(Space space){
        driver.findElement(space.getLocator()).click();
        spaces.put(space, true);
        try{ Thread.sleep(500); } catch(Exception e){}
    }
      
      



play



Map, . Map, .





, .





private By emptySpacesSelector = By.xpath("//div[@class='board']/div/div[@class='']/..");
      
      



Selenium, , List (), Map, , Selenium , .





/**
     * Updates Spaces map to be in sync with the game on the browser
     */
    private void updateSpaceOccupancy(){
        var emptyElements = driver.findElements(emptySpacesSelector)
                .stream()
                .map(e->e.getAttribute("class"))
                .collect(Collectors.toList());
 
        Arrays.stream(Space.values()).forEach(space -> {
            if(!emptyElements.contains(space.getClassName())){
                spaces.put(space, true);
            }
        });
    }
      
      



, . , , . , , updateSpaceOccupancy()



, Map .





public List<Space> getOpenSpaces(){
        updateSpaceOccupancy();
        return spaces.entrySet()
                .stream()
                .filter(occupied -> !occupied.getValue())
                .map(space->space.getKey())
                .collect(Collectors.toList());
    }
      
      



3. ,

, . , , — ChromeDriver . .





public class Game {
 
    private ChromeDriver driver;
    private Board board;
    
    public Game() {
        System.setProperty("webdriver.chrome.driver", "resources/chromedriver");
        driver = new ChromeDriver();
        driver.get("https://playtictactoe.org/");
 
        board = new Board(driver);
    }
 
    public Board getBoard(){
        return board;
    }
}
      
      



, . , , , . , .





private By restartIndicator = By.className("restart");
      
      



public boolean isOver(){
        return driver.findElement(restartIndicator).isDisplayed();
    }
 
    public Board restart() {
        driver.findElement(restartIndicator).click();
        board = new Board(driver);
        return board;
    }
      
      



, . .. . -, ( , , ), , , .





public boolean isThereAWinner(int winningScore){
        updateScores();
        return playerScore >= winningScore || computerScore >= winningScore;
    }
 
   /**
    * Gets scores from the browser
    */
    public void updateScores(){
 
        var scores = driver.findElementsByClassName("score")
                .stream()
                .map(WebElement::getText)
                .map(Integer::parseInt)
                .collect(Collectors.toList());
 
        playerScore = scores.get(0);
        tieScore = scores.get(1);
        computerScore = scores.get(2);
    }
 
    public void printResults(){
        if(playerScore > computerScore){
            System.out.println(format("Yayyy, you won! ? Score: %d:%d", playerScore, computerScore));
        }
        else if(computerScore > playerScore){
            System.out.println(format("Awww, you lose. ? Score: %d:%d", computerScore, playerScore));
        }
    }
      
      



, , .





public void end(){
        printResults();
        driver.quit();
        System.exit(0);
    }
      
      



4.

! . , , .





public class PlayGame {
 
    public static void main(String args[]){
        var game = new Game();
        var board = game.getBoard();
    }
}
      
      



, . , , 5 , . , , while .





public static void main(String args[]){
        var game = new Game();
        var board = game.getBoard();
 
        while(!game.isThereAWinner(5))
        {
 
        }
    }
      
      



while



, .





while(!game.isThereAWinner(5))
        {
            while(!game.isOver()) 
            {
 
            }
 
        }
      
      



. . , .





while(!game.isThereAWinner(5))
        {
            while(!game.isOver()) {
                var spaces = board.getOpenSpaces();
                board.play(spaces.get(new Random().nextInt(spaces.size())));
            }
        }
      
      



, . , .





while(!game.isThereAWinner(5))
        {
            while(!game.isOver()) {
                var spaces = board.getOpenSpaces();
                board.play(spaces.get(new Random().nextInt(spaces.size())));
            }
            board = game.restart();
        }
      
      



, ! .





public static void main(String args[]){
        var game = new Game();
        var board = game.getBoard();
 
        while(!game.isThereAWinner(5))
        {
            while(!game.isOver()) {
                var spaces = board.getOpenSpaces();
                board.play(spaces.get(new Random().nextInt(spaces.size())));
            }
            board = game.restart();
        }
        game.end();
    }
      
      



! -.






"Java QA Automation Engineer".



demo- API:
«HTTP. Postman, Newman, Fiddler (Charles), curl, SOAP. SoapUI».








All Articles