briar 0.1.3.b2 → 0.1.3.b3
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.
- checksums.yaml +4 -4
- data/features/step_definitions/keyboard_steps.rb +1 -1
- data/lib/briar.rb +6 -1
- data/lib/briar/bars/navbar.rb +28 -9
- data/lib/briar/briar_core.rb +1 -1
- data/lib/briar/cucumber.rb +3 -0
- data/lib/briar/keyboard/uia_keyboard.rb +10 -146
- data/lib/briar/keyboard/uia_keyboard_language.rb +122 -0
- data/lib/briar/keyboard/uia_numeric_keyboard.rb +38 -0
- data/lib/briar/table.rb +4 -0
- data/lib/briar/uia/briar_ipad_emulation.rb +190 -0
- data/lib/briar/uia/briar_uia.rb +51 -0
- data/lib/briar/version.rb +1 -1
- metadata +7 -4
- data/lib/briar/briar_uia.rb +0 -98
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 512528d4fa2a1d45ded34cc521654f7f562b6179
|
|
4
|
+
data.tar.gz: 94345455689bbe7fb6b67d3bdeb4e6f780ada03f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9d96364adc048ea8b503f3ada1d3e05b87430056ea33c0b1027a7777dd95f8f9735dfc63577ebd8699203ce48174bf6f9948cc388b688df45f0de99b2e1d371b
|
|
7
|
+
data.tar.gz: 3b81e8ae7d62a14d880aa14b38956cbfd03d1ab06635cb834f7aa006bcba9c092d3868badc347f43bd738dfb62fe49e68cfca4b60eda3e1efd8bcd203e05b930
|
data/lib/briar.rb
CHANGED
|
@@ -36,7 +36,8 @@ require 'calabash-cucumber'
|
|
|
36
36
|
|
|
37
37
|
require 'briar/version'
|
|
38
38
|
require 'briar/briar_core'
|
|
39
|
-
require 'briar/briar_uia'
|
|
39
|
+
require 'briar/uia/briar_uia'
|
|
40
|
+
require 'briar/uia/briar_ipad_emulation'
|
|
40
41
|
|
|
41
42
|
require 'briar/alerts_and_sheets/alert_view'
|
|
42
43
|
require 'briar/alerts_and_sheets/action_sheet'
|
|
@@ -57,8 +58,12 @@ require 'briar/picker/date_picker'
|
|
|
57
58
|
|
|
58
59
|
require 'briar/email'
|
|
59
60
|
require 'briar/image_view'
|
|
61
|
+
|
|
60
62
|
require 'briar/keyboard/keyboard'
|
|
61
63
|
require 'briar/keyboard/uia_keyboard'
|
|
64
|
+
require 'briar/keyboard/uia_keyboard_language'
|
|
65
|
+
require 'briar/keyboard/uia_numeric_keyboard'
|
|
66
|
+
|
|
62
67
|
require 'briar/label'
|
|
63
68
|
require 'briar/scroll_view'
|
|
64
69
|
|
data/lib/briar/bars/navbar.rb
CHANGED
|
@@ -101,11 +101,26 @@ module Briar
|
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
|
|
104
|
-
def go_back_after_waiting
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
def go_back_after_waiting(opts={})
|
|
105
|
+
default_opts = {:wait_before_going_back => 0.2,
|
|
106
|
+
:timeout => BRIAR_WAIT_TIMEOUT,
|
|
107
|
+
:timeout_message => nil,
|
|
108
|
+
:wait_step_pause => BRIAR_WAIT_STEP_PAUSE,
|
|
109
|
+
:retry_frequency => BRIAR_WAIT_RETRY_FREQ}
|
|
110
|
+
opts = default_opts.merge(opts)
|
|
111
|
+
wait_before = opts[:wait_before_going_back]
|
|
112
|
+
sleep(wait_before)
|
|
113
|
+
|
|
114
|
+
msg = opts[:timeout_message]
|
|
115
|
+
timeout = opts[:timeout]
|
|
116
|
+
if msg.nil?
|
|
117
|
+
msg = "waited for '#{timeout + wait_before}' for navbar back button but didn't see it"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
wait_for(:timeout => timeout,
|
|
121
|
+
:retry_frequency => opts[:retry_frequency],
|
|
122
|
+
:post_timeout => opts[:wait_step_pause],
|
|
123
|
+
:timeout_message => msg) do
|
|
109
124
|
not query('navigationItemButtonView first').empty?
|
|
110
125
|
end
|
|
111
126
|
touch('navigationItemButtonView first')
|
|
@@ -114,8 +129,9 @@ module Briar
|
|
|
114
129
|
|
|
115
130
|
def go_back_and_wait_for_view (view)
|
|
116
131
|
sleep(0.2)
|
|
117
|
-
|
|
118
|
-
|
|
132
|
+
timeout = BRIAR_WAIT_TIMEOUT
|
|
133
|
+
msg = "waited '#{timeout}' seconds but did not see navbar back button"
|
|
134
|
+
wait_for(wait_opts(msg, timeout)) do
|
|
119
135
|
not query('navigationItemButtonView first').empty?
|
|
120
136
|
end
|
|
121
137
|
|
|
@@ -127,10 +143,13 @@ module Briar
|
|
|
127
143
|
end
|
|
128
144
|
|
|
129
145
|
def touch_navbar_item(item_name, wait_for_view_id=nil)
|
|
130
|
-
|
|
131
|
-
|
|
146
|
+
timeout = BRIAR_WAIT_TIMEOUT
|
|
147
|
+
msg = "waited '#{timeout}' seconds for nav bar item '#{item_name}' to appear"
|
|
148
|
+
|
|
149
|
+
wait_for(wait_opts(msg, timeout)) do
|
|
132
150
|
(index_of_navbar_button(item_name) != nil) || button_exists?(item_name)
|
|
133
151
|
end
|
|
152
|
+
|
|
134
153
|
sleep(0.2)
|
|
135
154
|
idx = index_of_navbar_button item_name
|
|
136
155
|
|
data/lib/briar/briar_core.rb
CHANGED
|
@@ -50,7 +50,7 @@ module Briar
|
|
|
50
50
|
screenshot_and_raise "should see view with id '#{view_id}'"
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
actual_ht = {x: res['rect']['center_x'], y: res['rect']['center_y']}
|
|
53
|
+
actual_ht = {x: res['rect']['center_x'].to_f, y: res['rect']['center_y'].to_f}
|
|
54
54
|
|
|
55
55
|
unless actual_ht == center_ht
|
|
56
56
|
screenshot_and_raise "#{view_id} has center '#{actual_ht}' but should have center '#{center_ht}'"
|
data/lib/briar/cucumber.rb
CHANGED
|
@@ -3,6 +3,7 @@ require 'briar'
|
|
|
3
3
|
World(Briar)
|
|
4
4
|
World(Briar::Core)
|
|
5
5
|
World(Briar::UIA)
|
|
6
|
+
World(Briar::UIA::IPadEmulation)
|
|
6
7
|
World(Briar::Alerts_and_Sheets)
|
|
7
8
|
World(Briar::Bars)
|
|
8
9
|
World(Briar::Control::Button)
|
|
@@ -17,6 +18,8 @@ World(Briar::Email)
|
|
|
17
18
|
World(Briar::ImageView)
|
|
18
19
|
World(Briar::Keyboard)
|
|
19
20
|
World(Briar::UIAKeyboard)
|
|
21
|
+
World(Briar::UIAKeyboard::Numeric)
|
|
22
|
+
World(Briar::UIAKeyboard::Language)
|
|
20
23
|
World(Briar::Label)
|
|
21
24
|
World(Briar::ScrollView)
|
|
22
25
|
World(Briar::Table)
|
|
@@ -2,151 +2,6 @@ require 'calabash-cucumber'
|
|
|
2
2
|
|
|
3
3
|
module Briar
|
|
4
4
|
module UIAKeyboard
|
|
5
|
-
# use the apple localization codes
|
|
6
|
-
BRIAR_LANGUAGE_KEYS = {
|
|
7
|
-
:en => 'space',
|
|
8
|
-
:de => 'Leerzeichen',
|
|
9
|
-
# could not decide what the language code should be (alt was ja-JP)
|
|
10
|
-
:ja => '空白'
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
# work in progress
|
|
14
|
-
# the number of buttons on the keyboard will be
|
|
15
|
-
# 3 <== there is no international button
|
|
16
|
-
# 4 <== there is an international button
|
|
17
|
-
def keyboard_has_international? (opts={})
|
|
18
|
-
default_opts = {:await_keyboard => false}
|
|
19
|
-
opts = default_opts.merge(opts)
|
|
20
|
-
await_keyboard if opts[:await_keyboard]
|
|
21
|
-
res = uia('UIATarget.localTarget().frontMostApp().keyboard().buttons().length')
|
|
22
|
-
button_count = res['value']
|
|
23
|
-
button_count == 4
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def touch_international_key(opts={})
|
|
27
|
-
default_opts = {:await_keyboard => false,
|
|
28
|
-
:step_pause => 0.4}
|
|
29
|
-
opts = default_opts.merge(opts)
|
|
30
|
-
|
|
31
|
-
await_keyboard if opts[:await_keyboard]
|
|
32
|
-
|
|
33
|
-
unless keyboard_has_international?
|
|
34
|
-
screenshot_and_raise 'could not find an international key on the keyboard'
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# the international button will be at index 1
|
|
38
|
-
# 3 <== return key
|
|
39
|
-
# 2 <== Dictation key
|
|
40
|
-
# 1 <== International key
|
|
41
|
-
# 0 <== shift key
|
|
42
|
-
res = uia('UIATarget.localTarget().frontMostApp().keyboard().buttons()[1].tap()')
|
|
43
|
-
# sleep for a moment and let the keyboard settle into the new language
|
|
44
|
-
sleep(opts[:step_pause])
|
|
45
|
-
res
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
# work in progress
|
|
50
|
-
# when looking at elements() the space bar will be at the penultimate index
|
|
51
|
-
# when looking at keys() the space bar index seems to float around
|
|
52
|
-
def spacebar_label (opts={})
|
|
53
|
-
default_opts = {:await_keyboard => false}
|
|
54
|
-
opts = default_opts.merge(opts)
|
|
55
|
-
await_keyboard if opts[:await_keyboard]
|
|
56
|
-
elm_count = uia('UIATarget.localTarget().frontMostApp().keyboard().elements().length')['value']
|
|
57
|
-
spacebar_idx = elm_count - 2
|
|
58
|
-
res = uia("UIATarget.localTarget().frontMostApp().keyboard().elements()[#{spacebar_idx}].label()")
|
|
59
|
-
res['value']
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def spacebar_has_label?(label, opts={})
|
|
63
|
-
default_opts = {:await_keyboard => false}
|
|
64
|
-
opts = default_opts.merge(opts)
|
|
65
|
-
await_keyboard if opts[:await_keyboard]
|
|
66
|
-
spacebar_label.eql?(label)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def english_keyboard? (opts={})
|
|
70
|
-
default_opts = {:await_keyboard => false}
|
|
71
|
-
opts = default_opts.merge(opts)
|
|
72
|
-
await_keyboard if opts[:await_keyboard]
|
|
73
|
-
spacebar_has_label? BRIAR_LANGUAGE_KEYS[:en]
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def german_keyboard? (opts={})
|
|
77
|
-
default_opts = {:await_keyboard => false}
|
|
78
|
-
opts = default_opts.merge(opts)
|
|
79
|
-
await_keyboard if opts[:await_keyboard]
|
|
80
|
-
spacebar_has_label? BRIAR_LANGUAGE_KEYS[:de]
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def romaji_keyboard? (opts={})
|
|
84
|
-
default_opts = {:await_keyboard => false}
|
|
85
|
-
opts = default_opts.merge(opts)
|
|
86
|
-
await_keyboard if opts[:await_keyboard]
|
|
87
|
-
spacebar_has_label? BRIAR_LANGUAGE_KEYS[:ja]
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def touch_international_until_language(language_key, opts={})
|
|
91
|
-
default_opts = {:await_keyboard => false}
|
|
92
|
-
opts = default_opts.merge(opts)
|
|
93
|
-
await_keyboard if opts[:await_keyboard]
|
|
94
|
-
|
|
95
|
-
unless keyboard_has_international?
|
|
96
|
-
screenshot_and_raise 'keyboard does not have an international key'
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
target = BRIAR_LANGUAGE_KEYS[language_key]
|
|
100
|
-
if target.nil?
|
|
101
|
-
screenshot_and_raise "unknown language key '#{language_key}'"
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
stop_at = spacebar_label
|
|
105
|
-
return if target.eql?(stop_at)
|
|
106
|
-
|
|
107
|
-
touch_international_key
|
|
108
|
-
|
|
109
|
-
current = spacebar_label
|
|
110
|
-
loop do
|
|
111
|
-
break if current.eql?(target)
|
|
112
|
-
touch_international_key
|
|
113
|
-
current = spacebar_label
|
|
114
|
-
if current.eql?(stop_at)
|
|
115
|
-
screenshot_and_raise "could not find keyboard using key '#{language_key}' and space bar label '#{target}'"
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def is_numeric_keyboard?(opts={})
|
|
121
|
-
default_opts = {:await_keyboard => false}
|
|
122
|
-
opts = default_opts.merge(opts)
|
|
123
|
-
await_keyboard if opts[:await_keyboard]
|
|
124
|
-
res = uia('UIATarget.localTarget().frontMostApp().keyboard().keys().length')['value']
|
|
125
|
-
res == 12
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def briar_keyboard_send_numeric_backspace(opts={})
|
|
129
|
-
default_opts = {:await_keyboard => false}
|
|
130
|
-
opts = default_opts.merge(opts)
|
|
131
|
-
await_keyboard if opts[:await_keyboard]
|
|
132
|
-
if ios7?
|
|
133
|
-
uia('UIATarget.localTarget().frontMostApp().keyboard().buttons()[0].tap()')
|
|
134
|
-
else
|
|
135
|
-
keyboard_enter_char 'Delete'
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def briar_keyboard_send_backspace(opts={})
|
|
140
|
-
default_opts = {:await_keyboard => false}
|
|
141
|
-
opts = default_opts.merge(opts)
|
|
142
|
-
await_keyboard if opts[:await_keyboard]
|
|
143
|
-
if is_numeric_keyboard?
|
|
144
|
-
briar_keyboard_send_numeric_backspace
|
|
145
|
-
else
|
|
146
|
-
briar_keyboard_send_backspace
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
5
|
def uia_keyboard_visible?
|
|
151
6
|
res = uia('UIATarget.localTarget().frontMostApp().keyboard()')['value']
|
|
152
7
|
not res.eql?(':nil')
|
|
@@ -165,8 +20,17 @@ module Briar
|
|
|
165
20
|
wait_for(opts) do
|
|
166
21
|
uia_keyboard_visible?
|
|
167
22
|
end
|
|
168
|
-
|
|
169
23
|
end
|
|
170
24
|
|
|
25
|
+
def dismiss_ipad_keyboard
|
|
26
|
+
screenshot_and_raise 'cannot dismiss keyboard on iphone' if iphone?
|
|
27
|
+
screenshot_and_raise 'cannot dismiss keyboard without launching with instruments' unless uia_available?
|
|
28
|
+
send_uia_command command: "uia.keyboard().buttons()['Hide keyboard'].tap()"
|
|
29
|
+
step_pause
|
|
30
|
+
end
|
|
171
31
|
end
|
|
172
32
|
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
require 'calabash-cucumber'
|
|
2
|
+
|
|
3
|
+
module Briar
|
|
4
|
+
module UIAKeyboard
|
|
5
|
+
module Language
|
|
6
|
+
# use the apple localization codes
|
|
7
|
+
BRIAR_LANGUAGE_KEYS = {
|
|
8
|
+
:en => 'space',
|
|
9
|
+
:de => 'Leerzeichen',
|
|
10
|
+
# could not decide what the language code should be (alt was ja-JP)
|
|
11
|
+
:ja => '空白'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
# work in progress
|
|
15
|
+
# the number of buttons on the keyboard will be
|
|
16
|
+
# 3 <== there is no international button
|
|
17
|
+
# 4 <== there is an international button
|
|
18
|
+
def keyboard_has_international? (opts={})
|
|
19
|
+
default_opts = {:await_keyboard => false}
|
|
20
|
+
opts = default_opts.merge(opts)
|
|
21
|
+
await_keyboard if opts[:await_keyboard]
|
|
22
|
+
res = uia('UIATarget.localTarget().frontMostApp().keyboard().buttons().length')
|
|
23
|
+
button_count = res['value']
|
|
24
|
+
button_count == 4
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def touch_international_key(opts={})
|
|
28
|
+
default_opts = {:await_keyboard => false,
|
|
29
|
+
:step_pause => 0.4}
|
|
30
|
+
opts = default_opts.merge(opts)
|
|
31
|
+
|
|
32
|
+
await_keyboard if opts[:await_keyboard]
|
|
33
|
+
|
|
34
|
+
unless keyboard_has_international?
|
|
35
|
+
screenshot_and_raise 'could not find an international key on the keyboard'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# the international button will be at index 1
|
|
39
|
+
# 3 <== return key
|
|
40
|
+
# 2 <== Dictation key
|
|
41
|
+
# 1 <== International key
|
|
42
|
+
# 0 <== shift key
|
|
43
|
+
res = uia('UIATarget.localTarget().frontMostApp().keyboard().buttons()[1].tap()')
|
|
44
|
+
# sleep for a moment and let the keyboard settle into the new language
|
|
45
|
+
sleep(opts[:step_pause])
|
|
46
|
+
res
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# work in progress
|
|
51
|
+
# when looking at elements() the space bar will be at the penultimate index
|
|
52
|
+
# when looking at keys() the space bar index seems to float around
|
|
53
|
+
def spacebar_label (opts={})
|
|
54
|
+
default_opts = {:await_keyboard => false}
|
|
55
|
+
opts = default_opts.merge(opts)
|
|
56
|
+
await_keyboard if opts[:await_keyboard]
|
|
57
|
+
elm_count = uia('UIATarget.localTarget().frontMostApp().keyboard().elements().length')['value']
|
|
58
|
+
spacebar_idx = elm_count - 2
|
|
59
|
+
res = uia("UIATarget.localTarget().frontMostApp().keyboard().elements()[#{spacebar_idx}].label()")
|
|
60
|
+
res['value']
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def spacebar_has_label?(label, opts={})
|
|
64
|
+
default_opts = {:await_keyboard => false}
|
|
65
|
+
opts = default_opts.merge(opts)
|
|
66
|
+
await_keyboard if opts[:await_keyboard]
|
|
67
|
+
spacebar_label.eql?(label)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def english_keyboard? (opts={})
|
|
71
|
+
default_opts = {:await_keyboard => false}
|
|
72
|
+
opts = default_opts.merge(opts)
|
|
73
|
+
await_keyboard if opts[:await_keyboard]
|
|
74
|
+
spacebar_has_label? BRIAR_LANGUAGE_KEYS[:en]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def german_keyboard? (opts={})
|
|
78
|
+
default_opts = {:await_keyboard => false}
|
|
79
|
+
opts = default_opts.merge(opts)
|
|
80
|
+
await_keyboard if opts[:await_keyboard]
|
|
81
|
+
spacebar_has_label? BRIAR_LANGUAGE_KEYS[:de]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def romaji_keyboard? (opts={})
|
|
85
|
+
default_opts = {:await_keyboard => false}
|
|
86
|
+
opts = default_opts.merge(opts)
|
|
87
|
+
await_keyboard if opts[:await_keyboard]
|
|
88
|
+
spacebar_has_label? BRIAR_LANGUAGE_KEYS[:ja]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def touch_international_until_language(language_key, opts={})
|
|
92
|
+
default_opts = {:await_keyboard => false}
|
|
93
|
+
opts = default_opts.merge(opts)
|
|
94
|
+
await_keyboard if opts[:await_keyboard]
|
|
95
|
+
|
|
96
|
+
unless keyboard_has_international?
|
|
97
|
+
screenshot_and_raise 'keyboard does not have an international key'
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
target = BRIAR_LANGUAGE_KEYS[language_key]
|
|
101
|
+
if target.nil?
|
|
102
|
+
screenshot_and_raise "unknown language key '#{language_key}'"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
stop_at = spacebar_label
|
|
106
|
+
return if target.eql?(stop_at)
|
|
107
|
+
|
|
108
|
+
touch_international_key
|
|
109
|
+
|
|
110
|
+
current = spacebar_label
|
|
111
|
+
loop do
|
|
112
|
+
break if current.eql?(target)
|
|
113
|
+
touch_international_key
|
|
114
|
+
current = spacebar_label
|
|
115
|
+
if current.eql?(stop_at)
|
|
116
|
+
screenshot_and_raise "could not find keyboard using key '#{language_key}' and space bar label '#{target}'"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'calabash-cucumber'
|
|
2
|
+
|
|
3
|
+
module Briar
|
|
4
|
+
module UIAKeyboard
|
|
5
|
+
module Numeric
|
|
6
|
+
|
|
7
|
+
def is_numeric_keyboard?(opts={})
|
|
8
|
+
default_opts = {:await_keyboard => false}
|
|
9
|
+
opts = default_opts.merge(opts)
|
|
10
|
+
await_keyboard if opts[:await_keyboard]
|
|
11
|
+
res = uia('UIATarget.localTarget().frontMostApp().keyboard().keys().length')['value']
|
|
12
|
+
res == 12
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def keyboard_send_numeric_backspace(opts={})
|
|
16
|
+
default_opts = {:await_keyboard => false}
|
|
17
|
+
opts = default_opts.merge(opts)
|
|
18
|
+
await_keyboard if opts[:await_keyboard]
|
|
19
|
+
if ios7?
|
|
20
|
+
uia('UIATarget.localTarget().frontMostApp().keyboard().buttons()[0].tap()')
|
|
21
|
+
else
|
|
22
|
+
keyboard_enter_char 'Delete'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def keyboard_send_backspace(opts={})
|
|
27
|
+
default_opts = {:await_keyboard => false}
|
|
28
|
+
opts = default_opts.merge(opts)
|
|
29
|
+
await_keyboard if opts[:await_keyboard]
|
|
30
|
+
if is_numeric_keyboard?
|
|
31
|
+
keyboard_send_numeric_backspace
|
|
32
|
+
else
|
|
33
|
+
keyboard_send_backspace
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/briar/table.rb
CHANGED
|
@@ -260,6 +260,10 @@ module Briar
|
|
|
260
260
|
end
|
|
261
261
|
|
|
262
262
|
def query_str_for_confirm_delete_in_row(row_id, table_id=nil)
|
|
263
|
+
if device.ios5?
|
|
264
|
+
# it is not either of those...
|
|
265
|
+
pending 'cannot detect the confirm delete button (yet) in iOS 5'
|
|
266
|
+
end
|
|
263
267
|
mark = device.ios7? ? 'Delete' : 'Confirm Deletion'
|
|
264
268
|
"#{query_str_for_row row_id, table_id} descendant control marked:'#{mark}'"
|
|
265
269
|
end
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
require 'calabash-cucumber'
|
|
2
|
+
|
|
3
|
+
module Briar
|
|
4
|
+
module UIA
|
|
5
|
+
module IPadEmulation
|
|
6
|
+
|
|
7
|
+
class Cache
|
|
8
|
+
attr_accessor :device_internal
|
|
9
|
+
attr_accessor :window_index
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@device_internal = nil
|
|
13
|
+
@window_index = nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def current_device
|
|
17
|
+
if device_internal.nil?
|
|
18
|
+
#noinspection RubyParenthesesAfterMethodCallInspection
|
|
19
|
+
@device_internal = device()
|
|
20
|
+
end
|
|
21
|
+
@device_internal
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
# use the apple localization codes
|
|
26
|
+
BRIAR_IPAD_1X_2X_BUTTON_LABELS = {
|
|
27
|
+
:en => {:emulated_1x => 'Switch to full screen mode',
|
|
28
|
+
:emulated_2x => 'Switch to normal mode'}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
def ensure_uia_and_ipad(cache=Cache.new)
|
|
32
|
+
#noinspection RubyParenthesesAfterMethodCallInspection
|
|
33
|
+
unless cache.current_device.ipad?
|
|
34
|
+
screenshot_and_raise 'this function is only for the iPad'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
unless cache.current_device.ios7?
|
|
38
|
+
screenshot_and_raise 'this function only works on iOS 7'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
unless uia_available?
|
|
42
|
+
screenshot_and_raise 'this function requires the app be launched with instruments'
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def ipad_1x_2x_labels_hash(lang_code)
|
|
48
|
+
ht = BRIAR_IPAD_1X_2X_BUTTON_LABELS[lang_code]
|
|
49
|
+
if ht.nil?
|
|
50
|
+
screenshot_and_raise "did not recognize language code '#{lang_code}'"
|
|
51
|
+
end
|
|
52
|
+
ht
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def ipad_1x_2x_labels_array(lang_code)
|
|
56
|
+
ht = ipad_1x_2x_labels_hash lang_code
|
|
57
|
+
[ht[:emulated_1x], ht[:emulated_2x]]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def uia_ipad_scale(opts={})
|
|
61
|
+
default_opts = {:language_code => :en,
|
|
62
|
+
:ensure_uia_and_ipad => false,
|
|
63
|
+
:cache => Cache.new}
|
|
64
|
+
opts = default_opts.merge(opts)
|
|
65
|
+
|
|
66
|
+
if opts[:ensure_uia_and_ipad]
|
|
67
|
+
ensure_uia_and_ipad(opts[:cache])
|
|
68
|
+
opts[:ensure_uia_and_ipad] = false
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
idx = window_index_of_ipad_1x_2x_button opts
|
|
73
|
+
|
|
74
|
+
res = uia("UIATarget.localTarget().frontMostApp().windows()[#{idx}].buttons()[0].label()")
|
|
75
|
+
val = res['value']
|
|
76
|
+
|
|
77
|
+
candidates = ipad_1x_2x_labels_array(opts[:language_code])
|
|
78
|
+
|
|
79
|
+
if val.eql?(candidates[0])
|
|
80
|
+
:emulated_1x
|
|
81
|
+
else
|
|
82
|
+
:emulated_2x
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def is_iphone_app_emulated_on_ipad?(cache=Cache.new)
|
|
88
|
+
return false unless cache.current_device.ipad?
|
|
89
|
+
idx = window_index_of_ipad_1x_2x_button({:raise_if_not_found => false,
|
|
90
|
+
:cache => cache})
|
|
91
|
+
idx != -1
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def window_index_of_ipad_1x_2x_button(opts={})
|
|
95
|
+
|
|
96
|
+
default_opts = {:language_code => :en,
|
|
97
|
+
:ensure_uia_and_ipad => false,
|
|
98
|
+
:raise_if_not_found => true,
|
|
99
|
+
:cache => Cache.new}
|
|
100
|
+
opts = default_opts.merge(opts)
|
|
101
|
+
|
|
102
|
+
cache = opts[:cache]
|
|
103
|
+
return cache.window_index unless cache.window_index.nil?
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
ensure_uia_and_ipad(opts[:cache]) if opts[:ensure_uia_and_ipad]
|
|
107
|
+
|
|
108
|
+
window_count = uia('UIATarget.localTarget().frontMostApp().windows().length')['value']
|
|
109
|
+
index = 0
|
|
110
|
+
|
|
111
|
+
lang_code = opts[:language_code]
|
|
112
|
+
candidates = ipad_1x_2x_labels_array(lang_code)
|
|
113
|
+
success = false
|
|
114
|
+
loop do
|
|
115
|
+
res = uia("UIATarget.localTarget().frontMostApp().windows()[#{index}].buttons()[0].label()")
|
|
116
|
+
if candidates.include?(res['value'])
|
|
117
|
+
success = true
|
|
118
|
+
break
|
|
119
|
+
end
|
|
120
|
+
index = index + 1
|
|
121
|
+
break unless index < window_count
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
unless success
|
|
125
|
+
if opts[:raise_if_not_found]
|
|
126
|
+
screenshot_and_raise "could not find window with button label '#{candidates[0]}' or '#{candidates[1]}' - is your an iphone app emulated on an ipad?"
|
|
127
|
+
end
|
|
128
|
+
index = -1
|
|
129
|
+
end
|
|
130
|
+
cache.window_index = index
|
|
131
|
+
index
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def uia_tap_ipad_scale_button(opts={})
|
|
135
|
+
default_opts = {:language_code => :en,
|
|
136
|
+
:ensure_uia_and_ipad => false,
|
|
137
|
+
:step_pause_after_touch => BRIAR_STEP_PAUSE,
|
|
138
|
+
:cache => Cache.new}
|
|
139
|
+
opts = default_opts.merge(opts)
|
|
140
|
+
ensure_uia_and_ipad(opts[:cache]) if opts[:ensure_uia_and_ipad]
|
|
141
|
+
|
|
142
|
+
idx = window_index_of_ipad_1x_2x_button(opts)
|
|
143
|
+
uia("UIATarget.localTarget().frontMostApp().windows()[#{idx}].buttons()[0].tap()")
|
|
144
|
+
sleep(opts[:step_pause_after_touch])
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def ensure_ipad_emulation_scale(scale, opts={})
|
|
149
|
+
allowed = [:emulated_1x, :emulated_2x]
|
|
150
|
+
unless allowed.include?(scale)
|
|
151
|
+
screenshot_and_raise "'#{scale}' is not one of '#{allowed}' allowed args"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
cache = Cache.new
|
|
155
|
+
#noinspection RubyParenthesesAfterMethodCallInspection
|
|
156
|
+
return unless is_iphone_app_emulated_on_ipad?(cache)
|
|
157
|
+
|
|
158
|
+
default_opts = {:language_code => :en,
|
|
159
|
+
:ensure_uia_and_ipad => false,
|
|
160
|
+
:step_pause_after_touch => BRIAR_STEP_PAUSE,
|
|
161
|
+
:cache => cache}
|
|
162
|
+
opts = default_opts.merge(opts)
|
|
163
|
+
|
|
164
|
+
actual_scale = uia_ipad_scale(opts)
|
|
165
|
+
|
|
166
|
+
if actual_scale != scale
|
|
167
|
+
uia_tap_ipad_scale_button opts
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def ensure_ipad_emulation_1x(opts={})
|
|
172
|
+
default_opts = {:language_code => :en,
|
|
173
|
+
:ensure_uia_and_ipad => false,
|
|
174
|
+
:step_pause_after_touch => BRIAR_STEP_PAUSE,
|
|
175
|
+
:cache => Cache.new}
|
|
176
|
+
opts = default_opts.merge(opts)
|
|
177
|
+
ensure_ipad_emulation_scale(:emulated_1x, opts)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def ensure_ipad_emulation_2x(opts={})
|
|
181
|
+
default_opts = {:language_code => :en,
|
|
182
|
+
:ensure_uia_and_ipad => false,
|
|
183
|
+
:step_pause_after_touch => BRIAR_STEP_PAUSE,
|
|
184
|
+
:cache => Cache.new}
|
|
185
|
+
opts = default_opts.merge(opts)
|
|
186
|
+
ensure_ipad_emulation_scale(:emulated_2x, opts)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'calabash-cucumber'
|
|
2
|
+
|
|
3
|
+
module Briar
|
|
4
|
+
module UIA
|
|
5
|
+
|
|
6
|
+
def uia_available?
|
|
7
|
+
# proxy for testing if run_loop exists
|
|
8
|
+
not uia_not_available?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def uia_not_available?
|
|
12
|
+
default_device.nil?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def uia_handle_target_command(cmd, *query_args)
|
|
16
|
+
args = query_args.map do |part|
|
|
17
|
+
if part.is_a?(String)
|
|
18
|
+
"#{escape_uia_string(part)}"
|
|
19
|
+
else
|
|
20
|
+
"#{escape_uia_string(part.to_edn)}"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
command = %Q[target.#{cmd}(#{args.join(', ')})]
|
|
24
|
+
if ENV['DEBUG'] == '1'
|
|
25
|
+
puts 'Sending UIA command'
|
|
26
|
+
puts command
|
|
27
|
+
end
|
|
28
|
+
s=send_uia_command :command => command
|
|
29
|
+
if ENV['DEBUG'] == '1'
|
|
30
|
+
puts 'Result'
|
|
31
|
+
p s
|
|
32
|
+
end
|
|
33
|
+
if s['status'] == 'success'
|
|
34
|
+
s['value']
|
|
35
|
+
else
|
|
36
|
+
raise s
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def uia_touch_with_options(point, opts={})
|
|
41
|
+
defaults = {:tap_count => 1,
|
|
42
|
+
:touch_count => 1,
|
|
43
|
+
:duration => 0.0}
|
|
44
|
+
opts = defaults.merge(opts)
|
|
45
|
+
pt = "{x: #{point[:x]}, y: #{point[:y]}}"
|
|
46
|
+
args = "{tapCount: #{opts[:tap_count]}, touchCount: #{opts[:touch_count]}, duration: #{opts[:duration]}}"
|
|
47
|
+
uia_handle_target_command(:tapWithOptions, pt, args)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/briar/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: briar
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.3.
|
|
4
|
+
version: 0.1.3.b3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joshua Moody
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2013-12-
|
|
11
|
+
date: 2013-12-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: calabash-cucumber
|
|
@@ -101,7 +101,6 @@ files:
|
|
|
101
101
|
- lib/briar/bars/toolbar.rb
|
|
102
102
|
- lib/briar/briar_core.rb
|
|
103
103
|
- lib/briar/briar_steps.rb
|
|
104
|
-
- lib/briar/briar_uia.rb
|
|
105
104
|
- lib/briar/control/button.rb
|
|
106
105
|
- lib/briar/control/segmented_control.rb
|
|
107
106
|
- lib/briar/control/slider.rb
|
|
@@ -110,6 +109,8 @@ files:
|
|
|
110
109
|
- lib/briar/image_view.rb
|
|
111
110
|
- lib/briar/keyboard/keyboard.rb
|
|
112
111
|
- lib/briar/keyboard/uia_keyboard.rb
|
|
112
|
+
- lib/briar/keyboard/uia_keyboard_language.rb
|
|
113
|
+
- lib/briar/keyboard/uia_numeric_keyboard.rb
|
|
113
114
|
- lib/briar/label.rb
|
|
114
115
|
- lib/briar/picker/date_picker.rb
|
|
115
116
|
- lib/briar/picker/date_picker_core.rb
|
|
@@ -120,6 +121,8 @@ files:
|
|
|
120
121
|
- lib/briar/table.rb
|
|
121
122
|
- lib/briar/text_field.rb
|
|
122
123
|
- lib/briar/text_view.rb
|
|
124
|
+
- lib/briar/uia/briar_ipad_emulation.rb
|
|
125
|
+
- lib/briar/uia/briar_uia.rb
|
|
123
126
|
- lib/briar/version.rb
|
|
124
127
|
- spec/spec_helper.rb
|
|
125
128
|
homepage: https://github.com/jmoody/briar
|
|
@@ -145,7 +148,7 @@ rubyforge_project:
|
|
|
145
148
|
rubygems_version: 2.1.11
|
|
146
149
|
signing_key:
|
|
147
150
|
specification_version: 4
|
|
148
|
-
summary: briar-0.1.3.
|
|
151
|
+
summary: briar-0.1.3.b3
|
|
149
152
|
test_files:
|
|
150
153
|
- features/step_definitions/alerts_and_sheets/action_sheet_steps.rb
|
|
151
154
|
- features/step_definitions/alerts_and_sheets/alert_view_steps.rb
|
data/lib/briar/briar_uia.rb
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
require 'calabash-cucumber'
|
|
2
|
-
|
|
3
|
-
module Briar
|
|
4
|
-
module UIA
|
|
5
|
-
|
|
6
|
-
def uia_available?
|
|
7
|
-
# proxy for testing if run_loop exists
|
|
8
|
-
not uia_not_available?
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def uia_not_available?
|
|
12
|
-
default_device.nil?
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def uia_handle_target_command(cmd, *query_args)
|
|
16
|
-
args = query_args.map do |part|
|
|
17
|
-
if part.is_a?(String)
|
|
18
|
-
"#{escape_uia_string(part)}"
|
|
19
|
-
else
|
|
20
|
-
"#{escape_uia_string(part.to_edn)}"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
command = %Q[target.#{cmd}(#{args.join(', ')})]
|
|
24
|
-
if ENV['DEBUG'] == '1'
|
|
25
|
-
puts 'Sending UIA command'
|
|
26
|
-
puts command
|
|
27
|
-
end
|
|
28
|
-
s=send_uia_command :command => command
|
|
29
|
-
if ENV['DEBUG'] == '1'
|
|
30
|
-
puts 'Result'
|
|
31
|
-
p s
|
|
32
|
-
end
|
|
33
|
-
if s['status'] == 'success'
|
|
34
|
-
s['value']
|
|
35
|
-
else
|
|
36
|
-
raise s
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def uia_touch_with_options(point, opts={})
|
|
41
|
-
defaults = {:tap_count => 1,
|
|
42
|
-
:touch_count => 1,
|
|
43
|
-
:duration => 0.0}
|
|
44
|
-
opts = defaults.merge(opts)
|
|
45
|
-
pt = "{x: #{point[:x]}, y: #{point[:y]}}"
|
|
46
|
-
args = "{tapCount: #{opts[:tap_count]}, touchCount: #{opts[:touch_count]}, duration: #{opts[:duration]}}"
|
|
47
|
-
uia_handle_target_command(:tapWithOptions, pt, args)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def dismiss_ipad_keyboard
|
|
51
|
-
screenshot_and_raise 'cannot dismiss keyboard on iphone' if iphone?
|
|
52
|
-
screenshot_and_raise 'cannot dismiss keyboard without launching with instruments' unless uia_available?
|
|
53
|
-
send_uia_command command: "uia.keyboard().buttons()['Hide keyboard'].tap()"
|
|
54
|
-
step_pause
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def make_ipad_emulation_1x
|
|
58
|
-
#irb(main):040:0> uia('UIATarget.localTarget().frontMostApp().windows()[2].buttons()[0].label()')
|
|
59
|
-
#{
|
|
60
|
-
# "status" => "success",
|
|
61
|
-
# "value" => "Switch to normal mode",
|
|
62
|
-
# "index" => 21
|
|
63
|
-
#}
|
|
64
|
-
#irb(main):041:0> uia('UIATarget.localTarget().frontMostApp().windows()[2].buttons()[0].label()')
|
|
65
|
-
#{
|
|
66
|
-
# "status" => "success",
|
|
67
|
-
# "value" => "Switch to full screen mode",
|
|
68
|
-
# "index" => 22
|
|
69
|
-
#}
|
|
70
|
-
|
|
71
|
-
device = device()
|
|
72
|
-
unless device.ipad?
|
|
73
|
-
pending 'this trick only works on the iPad'
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
unless device.ios7?
|
|
77
|
-
pending 'this trick only works on iOS 7'
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
unless uia_available?
|
|
81
|
-
pending 'this trick requires the app be launched with instruments'
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# this only works because iPhone apps emulated on iPads in iOS 7 _always_
|
|
85
|
-
# launch at 2x
|
|
86
|
-
uia_touch_with_options({x: 738, y: 24})
|
|
87
|
-
step_pause
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def ensure_ipad_emulation_1x
|
|
91
|
-
device = device()
|
|
92
|
-
if device.ipad? and device.ios7? and uia_available?
|
|
93
|
-
uia_touch_with_options({x: 738, y: 24})
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
end
|
|
98
|
-
end
|