device_api-ios 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5e0d6fee430df723821822f044a27761bec4932d
4
+ data.tar.gz: a38729c9ef0cc3a0266ee14892ee0d83b942f284
5
+ SHA512:
6
+ metadata.gz: 610556e7181893924af71a2764d2e18e668c82f60514b1950308fa373e1fc4342d45f53e2e754a1fe36ef9738623cbb97cfa5370c8000361eea945922397ff92
7
+ data.tar.gz: 8a8a987c173cf19d285d20307be932add6046ede1bedf419c8224ed53e4bca6a7914e9f9aee47ca31872667caf1f85af3f305086258918fe6a2c862843bb731e
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+ source 'https://gems.cloud.bbc.co.uk'
3
+
4
+ gem 'device_api', '>=1.0.0'
5
+ gem 'ios-devices'
6
+
7
+ group :test do
8
+ gem 'rspec'
9
+ gem 'yaml'
10
+ gem 'open3'
11
+ gem 'ostruct'
12
+ end
@@ -0,0 +1,33 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ remote: https://gems.cloud.bbc.co.uk/
4
+ specs:
5
+ columnize (0.8.9)
6
+ debugger (1.6.8)
7
+ columnize (>= 0.3.1)
8
+ debugger-linecache (~> 1.2.0)
9
+ debugger-ruby_core_source (~> 1.3.5)
10
+ debugger-linecache (1.2.0)
11
+ debugger-ruby_core_source (1.3.5)
12
+ device_api (1.0.0)
13
+ diff-lcs (1.2.5)
14
+ rspec (3.1.0)
15
+ rspec-core (~> 3.1.0)
16
+ rspec-expectations (~> 3.1.0)
17
+ rspec-mocks (~> 3.1.0)
18
+ rspec-core (3.1.4)
19
+ rspec-support (~> 3.1.0)
20
+ rspec-expectations (3.1.1)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.1.0)
23
+ rspec-mocks (3.1.1)
24
+ rspec-support (~> 3.1.0)
25
+ rspec-support (3.1.0)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ debugger
32
+ device_api (>= 1.0.0)
33
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 BBC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,49 @@
1
+ # DeviceAPI-IOS
2
+
3
+
4
+ *DeviceAPI-IOS* is the iOS implementation of *DeviceAPI* - an initiative to allow full automation of device activities
5
+
6
+ ## Dependencies
7
+
8
+ *DeviceAPI-IOS* shells out to a number of iOS command line tools. You will need to make sure that the libimobiledevice library is installed and the following commands are available on your path:
9
+ * ideviceinfo
10
+
11
+ ## Using the gem
12
+
13
+ Add the device_api-ios gem to your gemfile - this will automatically bring in the device_api base gem on which the iOS gem is built.
14
+
15
+ gem 'device_api-ios'
16
+
17
+ You'll need to require the library in your code:
18
+
19
+ require 'device_api/ios'
20
+
21
+ Try connecting an iOS device with USB and run:
22
+
23
+ devices = DeviceAPI::IOS.devices
24
+
25
+ You might need to accept the 'Trust this computer' dialog on your device.
26
+
27
+ ### Detecting devices
28
+
29
+ There are two methods for detecting devices:
30
+ DeviceAPI::IOS.devices
31
+ This returns an array of objects representing the connected devices. You will get an empty array if there are no connected devices.
32
+ DeviceAPI::IOS.device(serial_id)
33
+ This looks for a device with a matching serial_id and returns a single device object.
34
+
35
+ ### Device object
36
+
37
+ When *DeviceAPI* detects a device, it returns a device object that lets you interact with and query the device with various iOS tools.
38
+
39
+ For example:
40
+
41
+ device = DeviceAPI::IOS.device(serial_id)
42
+ device.serial # '50d9299992726df277bg6befdf88e1704f4f8f8b'
43
+ device.model # 'iPad mini 3'
44
+
45
+ ## License
46
+
47
+ *DeviceAPI-IOS* is available to everyone under the terms of the MIT open source licence. Take a look at the LICENSE file in the code.
48
+
49
+ Copyright (c) 2015 BBC
@@ -0,0 +1,14 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'device_api-ios'
3
+ s.version = '1.0.1'
4
+ s.date = Time.now.strftime("%Y-%m-%d")
5
+ s.summary = 'IOS Device Management API'
6
+ s.description = 'iOS implementation of DeviceAPI'
7
+ s.authors = ['BBC', 'Jon Wilson', 'Kedar Barde']
8
+ s.email = ['jon.wilson01@bbc.co.uk', 'kedar_barde@mindtree.com']
9
+ s.files = `git ls-files`.split "\n"
10
+ s.homepage = 'https://github.com/bbc/device_api-ios'
11
+ s.license = 'MIT'
12
+ s.add_runtime_dependency 'device_api', '>=1.0', '<2.0'
13
+ s.add_development_dependency 'rspec'
14
+ end
@@ -0,0 +1,25 @@
1
+ require 'yaml'
2
+ require 'device_api/ios/device'
3
+ require 'device_api/ios/idevice'
4
+
5
+ module DeviceAPI
6
+ module IOS
7
+
8
+ # Returns an array of connected iOS devices
9
+ def self.devices
10
+ IDevice.devices.map do |d|
11
+ if d.keys.first
12
+ DeviceAPI::IOS::Device.new(serial: d.keys.first, display: d.values.flatten.first, state: 'ok')
13
+ end
14
+ end
15
+ end
16
+
17
+ # Retrieve a Device object by serial ID
18
+ def self.device(serial)
19
+ if serial.to_s.empty?
20
+ raise DeviceAPI::BadSerialString.new("Serial was '#{ serial.nil? ? 'nil' : serial }'")
21
+ end
22
+ DeviceAPI::IOS::Device.new(serial: serial, state: 'ok')
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,68 @@
1
+ require 'device_api/device'
2
+ require 'device_api/ios/device'
3
+ require 'device_api/ios/idevice'
4
+ require 'ios/devices'
5
+
6
+ # DeviceAPI - an interface to allow for automation of devices
7
+ module DeviceAPI
8
+ # iOS component of DeviceAPI
9
+ module IOS
10
+ # Namespace for the Device object.
11
+ class Device < DeviceAPI::Device
12
+ def initialize(options = {})
13
+ @serial = options[:serial]
14
+ @state = options[:state]
15
+ end
16
+
17
+ # Mapping of device status - used to provide a consistent status across platforms
18
+ # @return (String) common status string
19
+ def status
20
+ {
21
+ 'device' => :ok,
22
+ 'no device' => :dead,
23
+ 'offline' => :offline
24
+ }[@state]
25
+ end
26
+
27
+ # Look up device model using the ios-devices gem - changing 'iPad4,7' to 'iPad mini 3'
28
+ # @return (String) human readable model and version (where applicable)
29
+ def model
30
+ Ios::Devices.search(get_prop('ProductType')).name
31
+ end
32
+
33
+ # Returns the devices iOS version number - i.e. 8.2
34
+ # @return (String) iOS version number
35
+ def version
36
+ get_prop('ProductVersion')
37
+ end
38
+
39
+ # Return the device class - i.e. iPad, iPhone, etc
40
+ # @return (String) iOS device class
41
+ def device_class
42
+ get_prop('DeviceClass')
43
+ end
44
+
45
+ # Get the IMEI number of the device
46
+ # @return (String) IMEI number of current device
47
+ def imei
48
+ get_prop('InternationalMobileEquipmentIdentity')
49
+ end
50
+
51
+ # Has the 'Trust this device' dialog been accepted?
52
+ # @return (Boolean) true if the device is trusted, otherwise false
53
+ def trusted?
54
+ IDevice.trusted?(serial)
55
+ end
56
+
57
+ private
58
+
59
+ def get_prop(key)
60
+ if !@props || !@props[key]
61
+ @props = IDevice.get_props(serial)
62
+ end
63
+ @props[key]
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,68 @@
1
+ require 'device_api/execution'
2
+
3
+ # DeviceAPI - an interface to allow for automation of devices
4
+ module DeviceAPI
5
+ # iOS component of DeviceAPI
6
+ module IOS
7
+ # Namespace for all methods encapsulating idevice calls
8
+ class IDevice < Execution
9
+
10
+ # Returns an array of hashes representing connected devices
11
+ # @return (Array) Hash containing serial and device name
12
+ def self.devices
13
+ result = execute_with_timeout_and_retry('idevice_id -l')
14
+
15
+ raise IDeviceCommandError.new(result.stderr) if result.exit != 0
16
+
17
+ lines = result.stdout.split("\n")
18
+ results = []
19
+
20
+ lines.each do |ln|
21
+ if /[0-9a-zA-Z].*/.match(ln)
22
+ results.push(ln => execute_with_timeout_and_retry("ideviceinfo -u #{ln} -k DeviceName").stdout.split("\n"))
23
+ end
24
+ end
25
+ results
26
+ end
27
+
28
+ # Check to see if device has trusted the computer
29
+ # @param device_id uuid of the device
30
+ # @return true if the device returns information to ideviceinfo, otherwise false
31
+ def self.trusted?(device_id)
32
+ result = execute("ideviceinfo -u '#{device_id}'")
33
+ return true if result.exit == 0
34
+ false
35
+ end
36
+
37
+ # Returns a Hash containing properties of the specified device using idevice_id.
38
+ # @param device_id uuid of the device
39
+ # @return (Hash) key value pair of properties
40
+ def self.get_props(device_id)
41
+ result = execute("ideviceinfo -u '#{device_id}'")
42
+
43
+ raise IDeviceCommandError.new(result.stderr) if result.exit != 0
44
+
45
+ result = result.stdout
46
+ props = {}
47
+ unless result.start_with?('Usage:')
48
+ prop_list = result.split("\n")
49
+ prop_list.each do |line|
50
+ matches = line.scan(/(.*): (.*)/)
51
+ prop_name, prop_value = matches[0]
52
+ props[prop_name.strip] = prop_value.strip
53
+ end
54
+ end
55
+
56
+ props
57
+ end
58
+ end
59
+
60
+ # Exception class to handle exceptions related to IDevice Class
61
+ class IDeviceCommandError < StandardError
62
+ def initialize(msg)
63
+ super(msg)
64
+ end
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,104 @@
1
+ $LOAD_PATH.unshift( './lib/' )
2
+
3
+ require 'device_api/execution'
4
+ require 'device_api/ios/idevice'
5
+ require 'device_api/ios/device'
6
+ require 'yaml'
7
+
8
+ include RSpec
9
+
10
+ ProcessStatusStub = Struct.new(:exitstatus)
11
+ $STATUS_ZERO = ProcessStatusStub.new(0)
12
+
13
+ describe DeviceAPI::IOS do
14
+
15
+ before(:all) do
16
+
17
+ config_file = '../../config.yml'
18
+ CONFIG = YAML.load_file(File.expand_path(config_file, __FILE__))
19
+ @bundle_id = CONFIG["bundle_id"]
20
+ @app_path = File.expand_path(CONFIG["app_path"])
21
+ @arr_devices = DeviceAPI::IOS::IDevice.get_list_of_devices
22
+ keys = @arr_devices[0].keys
23
+ @test_device_uuid = keys[0]
24
+ @app_name = CONFIG["app_name"]
25
+
26
+ end
27
+
28
+ describe ".model" do
29
+
30
+ before(:each) do
31
+ @ios_device = DeviceAPI::IOS::Device.new(:serial=>@test_device_uuid,:state => "ok",:type => "Device")
32
+ end
33
+
34
+ it "returns model of device" do
35
+ props = DeviceAPI::IOS::IDevice.get_props(@test_device_uuid)
36
+ expect(props['ModelNumber']).to eq(@ios_device.model)
37
+ end
38
+
39
+
40
+ end
41
+
42
+
43
+
44
+ describe ".install" do
45
+
46
+ before(:each) do
47
+
48
+ result = DeviceAPI::Execution.execute("ideviceinstaller -u #{@test_device_uuid} -l")
49
+ if(result.stdout.include? @bundle_id and result.stderr=="")
50
+ DeviceAPI::Execution.execute("ideviceinstaller -u '#{@test_device_uuid}' -U #{@bundle_id}")
51
+ end
52
+
53
+ @ios_device = DeviceAPI::IOS::Device.new(:serial=>@test_device_uuid,:state => "ok",:type => "Device")
54
+
55
+ end
56
+
57
+ it "returns successfully installed message once ios app is installed on a device" do
58
+ expect(@ios_device.install(@app_path)).to eq :success
59
+ end
60
+
61
+
62
+ end
63
+
64
+ describe ".uninstall" do
65
+
66
+ before(:each) do
67
+ @ios_device = DeviceAPI::IOS::Device.new(:serial=>@test_device_uuid,:state => "ok",:type => "Device")
68
+ app_bundle_list = @ios_device.bundle_id_list
69
+ app_names = app_bundle_list.keys
70
+ result = DeviceAPI::Execution.execute("ideviceinstaller -u #{@test_device_uuid} -l")
71
+
72
+ if(!app_names.include? @app_name)
73
+ DeviceAPI::Execution.execute("ideviceinstaller -u '#{@test_device_uuid}' -i #{@app_path}")
74
+ @local_bundle_id = (@ios_device.bundle_id_list)[@app_name]
75
+ else
76
+ @local_bundle_id = app_bundle_list[@app_name]
77
+ end
78
+ end
79
+
80
+ it "Uninstalls the app from ios device" do
81
+ res = @ios_device.uninstall(@local_bundle_id)
82
+ expect( res ).to eq :success
83
+
84
+ end
85
+
86
+
87
+ end
88
+
89
+ describe ".get_props" do
90
+ before(:each) do
91
+ @ios_device = DeviceAPI::IOS::Device.new(:serial=>@test_device_uuid,:state => "ok",:type => "Device")
92
+ end
93
+
94
+ it "Returns a hash of name value pair properties" do
95
+ props = @ios_device.get_props
96
+ expect( props ).to be_a Hash
97
+ expect( props['ActivationState']).to eq('Activated')
98
+ end
99
+
100
+ end
101
+
102
+
103
+ end
104
+
@@ -0,0 +1,109 @@
1
+ $LOAD_PATH.unshift( './lib/' )
2
+
3
+ require 'device_api/execution'
4
+ require 'device_api/ios/idevice'
5
+ require 'yaml'
6
+
7
+ include RSpec
8
+
9
+ ProcessStatusStub = Struct.new(:exitstatus)
10
+ $STATUS_ZERO = ProcessStatusStub.new(0)
11
+
12
+ describe DeviceAPI::IOS::IDevice do
13
+
14
+ before(:all) do
15
+
16
+ config_file = '../../config.yml'
17
+ CONFIG = YAML.load_file(File.expand_path(config_file, __FILE__))
18
+ @bundle_id = CONFIG["bundle_id"]
19
+ @app_path = File.expand_path(CONFIG["app_path"])
20
+ @arr_devices = DeviceAPI::IOS::IDevice.get_list_of_devices
21
+ keys = @arr_devices[0].keys
22
+ @test_device_uuid = keys[0]
23
+
24
+ end
25
+
26
+ describe ".get_list_of_devices" do
27
+
28
+ before(:each) do
29
+ @arr_devices = DeviceAPI::IOS::IDevice.get_list_of_devices
30
+ end
31
+
32
+ it "returns an Array of connected ios devices" do
33
+ expect(@arr_devices.class).to eq(Array)
34
+ end
35
+
36
+ it "returns an Array of Hash of connected ios devices - When atleast one devices is connected" do
37
+ expect(@arr_devices[0].class).to eq(Hash)
38
+ end
39
+
40
+ end
41
+
42
+ describe ".get_state" do
43
+
44
+ it "returns state of a device based on the device - When atleast one device is connected" do
45
+ expect( DeviceAPI::IOS::IDevice.get_state(@test_device_uuid)).to eq("Activated")
46
+ end
47
+
48
+
49
+ end
50
+
51
+ describe ".install_app" do
52
+
53
+ before(:each) do
54
+
55
+ result = DeviceAPI::Execution.execute("ideviceinstaller -u #{@test_device_uuid} -l")
56
+ if(result.stdout.include? @bundle_id and result.stderr=="")
57
+ DeviceAPI::Execution.execute("ideviceinstaller -u '#{@test_device_uuid}' -U #{@bundle_id}")
58
+ end
59
+
60
+ end
61
+
62
+ it "returns successfully installed message once ios app is installed on a device" do
63
+ expect( DeviceAPI::IOS::IDevice.install_app(@test_device_uuid,@app_path)).to eq true
64
+ end
65
+
66
+
67
+ end
68
+
69
+ describe ".launch_app" do
70
+
71
+ before(:each) do
72
+
73
+ result = DeviceAPI::Execution.execute("ideviceinstaller -u #{@test_device_uuid} -l")
74
+ if(result.stdout.include? @bundle_id and result.stderr=="")
75
+ DeviceAPI::Execution.execute("ideviceinstaller -u '#{@test_device_uuid}' -U #{@bundle_id}")
76
+ end
77
+
78
+ end
79
+
80
+ it "Launches the app on the ios device" do
81
+ props = DeviceAPI::IOS::IDevice.launch_app(@test_device_uuid,@app_path)
82
+ expect( props ).to eq true
83
+
84
+ end
85
+
86
+
87
+ end
88
+
89
+ describe ".get_props" do
90
+
91
+ it "Returns a hash of name value pair properties" do
92
+ props = DeviceAPI::IOS::IDevice.get_props(@test_device_uuid)
93
+ expect( props ).to be_a Hash
94
+ expect( props['ActivationState']).to eq('Activated')
95
+ end
96
+
97
+ end
98
+
99
+ describe ".bundle_id_list" do
100
+
101
+ it "Returns a hash of name value pair of application name and bundle_id" do
102
+ list = DeviceAPI::IOS::IDevice.bundle_id_list(@test_device_uuid)
103
+ expect(list).to be_a Hash
104
+ end
105
+
106
+ end
107
+
108
+ end
109
+
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: device_api-ios
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - BBC
8
+ - Jon Wilson
9
+ - Kedar Barde
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2015-05-22 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: device_api
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
22
+ - - "<"
23
+ - !ruby/object:Gem::Version
24
+ version: '2.0'
25
+ type: :runtime
26
+ prerelease: false
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: '1.0'
32
+ - - "<"
33
+ - !ruby/object:Gem::Version
34
+ version: '2.0'
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ type: :development
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ description: iOS implementation of DeviceAPI
50
+ email:
51
+ - jon.wilson01@bbc.co.uk
52
+ - kedar_barde@mindtree.com
53
+ executables: []
54
+ extensions: []
55
+ extra_rdoc_files: []
56
+ files:
57
+ - Gemfile
58
+ - Gemfile.lock
59
+ - LICENSE
60
+ - README.md
61
+ - device_api-ios.gemspec
62
+ - lib/device_api/ios.rb
63
+ - lib/device_api/ios/device.rb
64
+ - lib/device_api/ios/idevice.rb
65
+ - spec/ios_device_spec.rb
66
+ - spec/ios_idevice_spec.rb
67
+ homepage: https://github.com/bbc/device_api-ios
68
+ licenses:
69
+ - MIT
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 2.4.5
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: IOS Device Management API
91
+ test_files: []
92
+ has_rdoc: