device_api-ios 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: