Automate an iOS Tic Tac Toe app with Appium 2 (XCUITest) Part 1: Player vs Player

How to use Appium 2 to automate playing Tic Tac Toe

# Install Node.js
brew install node@18

# Install Appium 2
npm install -g appium@next

# Install XCUITest Driver
appium driver install xcuitest

# Run this in a separate window to start up the Appium server
appium

# Install Ruby's Appium client library
gem install --no-document appium_lib

Get Started

Create a new Appium Test Automation Project in TestWise
# test_helper.rb
def app_file_path
'/Users/courtney/sample-apps/MorpionTPE.app.zip'
end

def appium_xcuitest_opts
opts = {
caps: {
platformName: 'ios',
automationName: 'xcuitest',
platformVersion: '16.2', # change to match your Xcode
deviceName: 'iPhone 14', # change here if necessary
app: app_file_path
},
appium_lib: {
server_url: "http://127.0.0.1:4723",
wait: 0.1,
},
}
end

def appium_opts
return appium_xcuitest_opts()
end
before(:all) do
@driver = Appium::Driver.new(appium_opts).start_driver
end
Tic TAI Toe’s game modes: Player VS Player, Player VS Computer and Computer VS Computer
# Begin game
Player 1: (1, 1)
Player 2: (3, 1)
Player 1: (1, 2)
Player 2: (3, 2)
Player 1: (1, 3) # Game ends, P1 wins

Execution Video

board = driver.find_elements(:class_name, "XCUIElementTypeImage")

# Board layout
# 0 1 2
# 3 4 5
# 6 7 8
board[0].click # taps the top-left cell
it "Play Tic Tac Toe - Player x Player - X Wins" do
driver.find_element(:name, "Player VS Player").click
board = driver.find_elements(:class_name, "XCUIElementTypeImage")

# 0 1 2
# 3 4 5
# 6 7 8
board[0].click
board[6].click
board[1].click
board[7].click
board[2].click

game_status_text = driver.find_element(:class_name, "XCUIElementTypeStaticText")["value"]
expect(game_status_text).to eq("Game has ended! Winner: Player X")
end
    menu_page = MenuPage.new(driver)
menu_page.click_player_vs_player_mode
class GameBoardPage < AbstractPage
def initialize(driver)
super(driver, "")
end

# (1, 1) is top-left, (3, 3) is bottom-right
def tap(x, y)
board = driver.find_elements(:class_name, "XCUIElementTypeImage")
index = (x - 1) * 3 + (y - 1)
board[index].click
end
end
it "Play Tic Tac Toe - Player x Player - X Wins" do
menu_page = MenuPage.new(driver)
menu_page.click_player_vs_player_mode

game_board_page = GameBoardPage.new(driver)
game_board_page.tap(1, 1)
game_board_page.tap(3, 1)
game_board_page.tap(1, 2)
game_board_page.tap(3, 2)
game_board_page.tap(1, 3)

expect(game_board_page.game_status_text).to eq("Game has ended! Winner: Player X")
end

Complete Test Scripts

class MenuPage < AbstractPage
def initialize(driver)
super(driver, "") # <= WIN TITLE
end

def click_player_vs_player_mode
driver.find_element(:name, "Player VS Player").click
end
end
class GameBoardPage < AbstractPage
def initialize(driver)
super(driver, "")
end

def tap(x, y)
board = driver.find_elements(:class_name, "XCUIElementTypeImage")
index = (x - 1) * 3 + (y - 1)
board[index].click
end

def game_status_text
driver.find_element(:class_name, "XCUIElementTypeStaticText")["value"]
end
end
load File.dirname(__FILE__) + "/../test_helper.rb"

describe "Player Vs Player Games" do
include TestHelper

before(:all) do
@driver = Appium::Driver.new(appium_opts).start_driver
end

after(:all) do
driver.quit unless debugging?
end

it "Play Tic Tac Toe - Player x Player - X Wins" do
menu_page = MenuPage.new(driver)
menu_page.click_player_vs_player_mode

game_board_page = GameBoardPage.new(driver)
game_board_page.tap(1, 1)
game_board_page.tap(3, 1)
game_board_page.tap(1, 2)
game_board_page.tap(3, 2)
game_board_page.tap(1, 3)

expect(game_board_page.game_status_text).to eq("Game has ended! Winner: Player X")
end

end

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store