Files
yattee/spec/ui/support/app.rb
Arkadiusz Fal 9cd9506dcf Fix UI tests for onboarding flow and AddRemoteServer redesign
- Skip onboarding in tests by setting UserDefaults before launch
- Update all addSource.* identifiers to addRemoteServer.* for new flow
- Switch from identifier-based to text-based element lookups (iOS 26 AXe limitation)
- Add Yattee Server credential support in instance setup
- Update baseline screenshots for Home tab and settings
2026-02-10 00:05:39 +01:00

126 lines
3.9 KiB
Ruby

# frozen_string_literal: true
require 'open3'
module UITest
# Manages app build, install, and launch lifecycle
class App
class AppError < StandardError; end
class << self
# Build the app for simulator
# @param device [String] Device name for destination
# @param skip [Boolean] Skip build if true
def build(device:, skip: false)
if skip
puts 'Skipping build (--skip-build)'
validate_app_exists!
return
end
puts "Building Yattee for #{device}..."
args = [
'xcodebuild',
'-project', Config.xcodeproj,
'-scheme', Config.scheme,
'-configuration', Config.configuration,
'-destination', "platform=iOS Simulator,name=#{device}",
'-derivedDataPath', Config.derived_data_path,
'build'
]
# Run build and capture output
output, status = Open3.capture2e(*args)
unless status.success?
# Extract relevant error lines
error_lines = output.lines.select { |l| l.include?('error:') }.join
raise AppError, "Build failed:\n#{error_lines.empty? ? output.last(2000) : error_lines}"
end
puts 'Build succeeded'
validate_app_exists!
end
# Install app to simulator
# @param udid [String] UDID of the simulator
# By default, uninstalls first to reset app data (use --keep-app-data to skip)
def install(udid:)
validate_app_exists!
# Uninstall first to reset app data (unless --keep-app-data)
unless Config.keep_app_data?
puts 'Resetting app data (uninstalling previous install)...'
uninstall(udid: udid)
# Reset keychain to prevent "Save Password?" dialogs during tests
puts 'Resetting simulator keychain...'
reset_keychain(udid: udid)
end
puts 'Installing app...'
output, status = Open3.capture2e('xcrun', 'simctl', 'install', udid, Config.app_path)
raise AppError, "Install failed: #{output}" unless status.success?
puts 'App installed'
end
# Launch app on simulator
# @param udid [String] UDID of the simulator
def launch(udid:)
puts 'Launching app...'
# Terminate if already running
terminate(udid: udid, silent: true)
# Skip onboarding in tests by passing launch argument
# iOS apps accept UserDefaults overrides via launch arguments
output, status = Open3.capture2e(
'xcrun', 'simctl', 'launch', udid, Config.bundle_id,
'-onboardingCompleted', 'YES'
)
raise AppError, "Launch failed: #{output}" unless status.success?
puts 'App launched'
end
# Terminate app on simulator
# @param udid [String] UDID of the simulator
# @param silent [Boolean] Don't raise error if app not running
def terminate(udid:, silent: false)
output, status = Open3.capture2e('xcrun', 'simctl', 'terminate', udid, Config.bundle_id)
# simctl terminate returns non-zero if app isn't running
return if silent
raise AppError, "Terminate failed: #{output}" unless status.success?
end
# Uninstall app from simulator
# @param udid [String] UDID of the simulator
def uninstall(udid:)
Open3.capture2e('xcrun', 'simctl', 'uninstall', udid, Config.bundle_id)
# Ignore errors - app might not be installed
end
# Reset simulator keychain to prevent "Save Password?" dialogs
# @param udid [String] UDID of the simulator
def reset_keychain(udid:)
Open3.capture2e('xcrun', 'simctl', 'keychain', udid, 'reset')
# Ignore errors - reset is best effort
end
private
def validate_app_exists!
return if File.exist?(Config.app_path)
raise AppError, "App not found at #{Config.app_path}. Run build first or remove --skip-build"
end
end
end
end