Module: Calabash::Cucumber::SimulatorAccessibility
- Includes:
- PlistBuddy, XcodeTools
- Included in:
- Launcher
- Defined in:
- lib/calabash-cucumber/utils/simulator_accessibility.rb
Overview
methods for checking and setting simulator accessibility
Instance Method Summary collapse
-
#accessibility_properties_hash ⇒ Hash
a hash table of the accessibility properties that control whether or not accessibility is enabled and whether the AXInspector is visible.
-
#enable_accessibility_in_sdk_dir(sim_app_support_sdk_dir, opts = {}) ⇒ Boolean
enables accessibility on the simulator indicated by
sim_app_support_sdk_dir
. -
#enable_accessibility_on_simulators(opts = {}) ⇒ Boolean
enables accessibility on any existing iOS Simulator by adjusting the simulator’s Library/Preferences/com.apple.Accessibility.plist contents.
-
#existing_simulator_support_sdk_dirs ⇒ Object
returns a list of absolute paths the existing simulator directories.
-
#launch_simulator ⇒ Object
launches the iOS Simulator indicated by
xcode-select
orDEVELOPER_DIR
. -
#plist_path_with_sdk_dir(sdk_dir) ⇒ String
the absolute path to the SDK’s com.apple.Accessibility.plist file.
-
#possible_simulator_sdks ⇒ Array<String>
returns a list of possible SDKs per Xcode version.
-
#possible_simulator_support_sdk_dirs ⇒ Array<String>
return absolute paths to possible simulator support sdk dirs.
-
#quit_simulator ⇒ Object
quits the iOS Simulator.
-
#reset_simulator_content_and_settings ⇒ Object
resets the simulator content and settings.
-
#simulator_app_support_dir ⇒ String
the absolute path to the iPhone Simulator Application Support directory.
Methods included from PlistBuddy
#build_plist_cmd, #execute_plist_cmd, #plist_buddy, #plist_key_exists?, #plist_read, #plist_set
Methods included from XcodeTools
#installed_simulators, #instruments, #instruments_supports_hyphen_s?, #xcode_bin_dir, #xcode_developer_dir
Instance Method Details
#accessibility_properties_hash ⇒ Hash
a hash table of the accessibility properties that control whether or not accessibility is enabled and whether the AXInspector is visible.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/calabash-cucumber/utils/simulator_accessibility.rb', line 189 def accessibility_properties_hash { # this is required :access_enabled => {:key => 'AccessibilityEnabled', :value => 'true', :type => 'bool'}, # i _think_ this is legacy :app_access_enabled => {:key => 'ApplicationAccessibilityEnabled', :value => 'true', :type => 'bool'}, # i don't know what this does :automation_enabled => {:key => 'AutomationEnabled', :value => 'true', :type => 'bool'}, # determines if the Accessibility Inspector is showing :inspector_showing => {:key => 'AXInspectorEnabled', :value => 'false', :type => 'bool'}, # controls if the Accessibility Inspector is expanded or not expanded :inspector_full_size => {:key => 'AXInspector.enabled', :value => 'false', :type => 'bool'}, # controls the frame of the Accessibility Inspector # this is a 'string' => {{0, 0}, {276, 166}} :inspector_frame => {:key => 'AXInspector.frame', :value => '{{270, -13}, {276, 166}}', :type => 'string'} } end |
#enable_accessibility_in_sdk_dir(sim_app_support_sdk_dir, opts = {}) ⇒ Boolean
enables accessibility on the simulator indicated by sim_app_support_sdk_dir
.
WARNING: this will quit the simulator
path = '/6.1'
enable_accessibility_in_sdk_dir(path)
this method also hides the AXInspector.
if the Library/Preferences/com.apple.Accessibility.plist does not exist this method will create a Library/Preferences/com.apple.Accessibility.plist that (oddly) the Simulator will not overwrite.
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/calabash-cucumber/utils/simulator_accessibility.rb', line 137 def enable_accessibility_in_sdk_dir(sim_app_support_sdk_dir, opts={}) default_opts = {:verbose => false} merged = default_opts.merge(opts) quit_simulator verbose = merged[:verbose] sdk = File.basename(sim_app_support_sdk_dir) msgs = ["cannot enable accessibility for #{sdk} SDK"] plist_path = File.("#{sim_app_support_sdk_dir}/Library/Preferences/com.apple.Accessibility.plist") hash = accessibility_properties_hash() if File.exist?(plist_path) res = hash.map do |hash_key, settings| success = plist_set(settings[:key], settings[:type], settings[:value], plist_path) unless success if verbose if settings[:type] == 'bool' value = settings[:value] ? 'YES' : 'NO' else value = settings[:value] end msgs << "could not set #{hash_key} => '#{settings[:key]}' to #{value}" calabash_warn(msgs.join("\n")) end end success end res.all? { |elm| elm } else FileUtils.mkdir_p("#{sim_app_support_sdk_dir}/Library/Preferences") plist = CFPropertyList::List.new data = {} # CFPropertyList gem is super wonky # it matches Boolean to a string type with 'true/false' values # - stick with PlistBuddy # hash.each do |_, settings| # data[settings[:key]] = settings[:value] # end plist.value = CFPropertyList.guess(data) plist.save(plist_path, CFPropertyList::List::FORMAT_BINARY) enable_accessibility_in_sdk_dir(sim_app_support_sdk_dir) end end |
#enable_accessibility_on_simulators(opts = {}) ⇒ Boolean
enables accessibility on any existing iOS Simulator by adjusting the simulator’s Library/Preferences/com.apple.Accessibility.plist contents.
a simulator ‘exists’ if has an Application Support directory. for example, the 6.1, 7.0.3-64, and 7.1 simulators exist if the following directories are present:
~/Library/Application Support/iPhone Simulator/Library/6.1
~/Library/Application Support/iPhone Simulator/Library/7.0.3-64
~/Library/Application Support/iPhone Simulator/Library/7.1
a simulator is ‘possible’ if the SDK is available in the Xcode version.
this method merges (uniquely) the possible and existing SDKs.
this method also hides the AXInspector.
102 103 104 105 106 107 108 109 110 |
# File 'lib/calabash-cucumber/utils/simulator_accessibility.rb', line 102 def enable_accessibility_on_simulators(opts={}) possible = possible_simulator_support_sdk_dirs existing = existing_simulator_support_sdk_dirs dirs = (possible + existing).uniq results = dirs.map do |dir| enable_accessibility_in_sdk_dir(dir, opts) end results.all? { |elm| elm } end |
#existing_simulator_support_sdk_dirs ⇒ Object
returns a list of absolute paths the existing simulator directories.
a simulator ‘exists’ if has an Application Support directory. for example, the 6.1, 7.0.3-64, and 7.1 simulators exist if the following directories are present:
~/Library/Application Support/iPhone Simulator/Library/6.1
~/Library/Application Support/iPhone Simulator/Library/7.0.3-64
~/Library/Application Support/iPhone Simulator/Library/7.1
@return a list of absolute paths to simulator directories
247 248 249 250 251 252 |
# File 'lib/calabash-cucumber/utils/simulator_accessibility.rb', line 247 def existing_simulator_support_sdk_dirs sim_app_support_path = simulator_app_support_dir() Dir.glob("#{sim_app_support_path}/*").select { |path| path =~ /(\d)\.(\d)\.?(\d)?(-64)?/ } end |
#launch_simulator ⇒ Object
launches the iOS Simulator indicated by xcode-select
or DEVELOPER_DIR
33 34 35 36 |
# File 'lib/calabash-cucumber/utils/simulator_accessibility.rb', line 33 def launch_simulator dev_dir = xcode_developer_dir system "open -a \"#{dev_dir}/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone Simulator.app\"" end |
#plist_path_with_sdk_dir(sdk_dir) ⇒ String
the absolute path to the SDK’s com.apple.Accessibility.plist file
232 233 234 |
# File 'lib/calabash-cucumber/utils/simulator_accessibility.rb', line 232 def plist_path_with_sdk_dir(sdk_dir) File.("#{sdk_dir}/Library/Preferences/com.apple.Accessibility.plist") end |
#possible_simulator_sdks ⇒ Array<String>
returns a list of possible SDKs per Xcode version
it is not enough to ask for the available sdks because of the new 64-bit variants that started to appear Xcode 5 and the potential for patch level versions.
unfortunately, this method will need be maintained per Xcode version.
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/calabash-cucumber/utils/simulator_accessibility.rb', line 263 def possible_simulator_sdks sdk_detector = SimLauncher::SdkDetector.new available = sdk_detector.available_sdk_versions instruments_version = instruments(:version) # in Xcode 5.1* SDK 7.0 ==> 7.0.3 if (instruments_version == '5.1' or instruments_version == '5.1.1') and available.include?('7.0') available << '7.0.3' available << '7.0.3-64' end if instruments_version == '5.1.1' and available.include?('7.1') available << '7.1' available << '7.1-64' end gem_compat_xcode_versions = ['5.1', '5.1.1'] unless gem_compat_xcode_versions.include?(instruments_version) msg = ["expected Xcode instruments version to be '5.1' or '5.1.1'", "but found version '#{instruments_version}'", "Gem needs a manual update for Xcode #{instruments_version}!"].join("\n") calabash_warn(msg) end # in Xcode 5.1* SDK 7.0 ==> 7.0.3 so we should not include '7.0' # if the user's support directory already contains a 7.0 and 7.0-64 dir # we will detect it by reading from disk. (available - ['7.0']).uniq.sort end |
#possible_simulator_support_sdk_dirs ⇒ Array<String>
return absolute paths to possible simulator support sdk dirs
these directories may or may not exist
297 298 299 300 301 302 |
# File 'lib/calabash-cucumber/utils/simulator_accessibility.rb', line 297 def possible_simulator_support_sdk_dirs base_dir = simulator_app_support_dir possible_simulator_sdks.map { |sdk| "#{base_dir}/#{sdk}" } end |
#quit_simulator ⇒ Object
quits the iOS Simulator
ATM there can only be only simulator open at a time, so simply doing what the sim_launcher gem does:
def quit_simulator
`echo 'application "iPhone Simulator" quit' | osascript`
end
works. I am not sure if we will ever be able to launch more than one simulator, but in case we can, this method will quit the simulator that is indicated by xcode-select
or DEVELOPER_DIR
.
27 28 29 30 |
# File 'lib/calabash-cucumber/utils/simulator_accessibility.rb', line 27 def quit_simulator dev_dir = xcode_developer_dir system "/usr/bin/osascript -e 'tell application \"#{dev_dir}/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone Simulator.app\" to quit'" end |
#reset_simulator_content_and_settings ⇒ Object
resets the simulator content and settings. it is analogous to touching the menu item.
it works by deleting the following directories:
-
~/Library/Application Support/iPhone Simulator/Library
-
~/Library/Application Support/iPhone Simulator/Library/<sdk>
and relaunching the iOS Simulator which will recreate the Library directory and the latest SDK directory.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/calabash-cucumber/utils/simulator_accessibility.rb', line 48 def reset_simulator_content_and_settings quit_simulator sim_lib_path = File.join(simulator_app_support_dir(), 'Library') FileUtils.rm_rf(sim_lib_path) existing_simulator_support_sdk_dirs.each do |dir| FileUtils.rm_rf(dir) end launch_simulator # this is tricky because we need to wait for the simulator to recreate # the directories. specifically, we need the Accessibility plist to be # exist so subsequent calabash launches will be able to enable # accessibility. # # the directories take ~3.0 - ~5.0 to create. counter = 0 loop do break if counter == 80 dirs = existing_simulator_support_sdk_dirs if dirs.count == 0 sleep(0.2) else break if dirs.all? { |dir| plist = File.("#{dir}/Library/Preferences/com.apple.Accessibility.plist") File.exists?(plist) } sleep(0.2) end counter = counter + 1 end end |
#simulator_app_support_dir ⇒ String
the absolute path to the iPhone Simulator Application Support directory
225 226 227 |
# File 'lib/calabash-cucumber/utils/simulator_accessibility.rb', line 225 def simulator_app_support_dir File.('~/Library/Application Support/iPhone Simulator') end |