run_loop 2.1.2 → 2.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/run_loop.rb +7 -0
- data/lib/run_loop/abstract.rb +18 -0
- data/lib/run_loop/core.rb +30 -1
- data/lib/run_loop/core_simulator.rb +5 -1
- data/lib/run_loop/detect_aut/detect.rb +8 -2
- data/lib/run_loop/detect_aut/xcode.rb +6 -2
- data/lib/run_loop/device.rb +9 -2
- data/lib/run_loop/device_agent/app/CBX-Runner.app.zip +0 -0
- data/lib/run_loop/device_agent/bin/xctestctl +0 -0
- data/lib/run_loop/device_agent/cbxrunner.rb +155 -0
- data/lib/run_loop/device_agent/frameworks.rb +64 -0
- data/lib/run_loop/device_agent/frameworks/Frameworks.zip +0 -0
- data/lib/run_loop/device_agent/ipa/CBX-Runner.app.zip +0 -0
- data/lib/run_loop/device_agent/launcher.rb +51 -0
- data/lib/run_loop/device_agent/xcodebuild.rb +91 -0
- data/lib/run_loop/device_agent/xctestctl.rb +109 -0
- data/lib/run_loop/dylib_injector.rb +10 -1
- data/lib/run_loop/environment.rb +66 -0
- data/lib/run_loop/host_cache.rb +7 -2
- data/lib/run_loop/physical_device/{ideviceinstaller.rb → life_cycle.rb} +86 -39
- data/lib/run_loop/sim_control.rb +8 -3
- data/lib/run_loop/version.rb +1 -1
- data/lib/run_loop/xcuitest.rb +134 -116
- data/scripts/lib/log.js +1 -1
- data/scripts/lib/on_alert.js +102 -17
- data/vendor-licenses/FBSimulatorControl.LICENSE +30 -0
- data/vendor-licenses/xctestctl.LICENSE +32 -0
- metadata +15 -3
data/lib/run_loop/sim_control.rb
CHANGED
@@ -294,7 +294,11 @@ module RunLoop
|
|
294
294
|
end
|
295
295
|
else
|
296
296
|
possible = XCODE_5_SDKS.map do |sdk|
|
297
|
-
File.
|
297
|
+
File.join(RunLoop::Environment.user_home_directory,
|
298
|
+
"Library",
|
299
|
+
"Application Support",
|
300
|
+
"iPhone Simulator",
|
301
|
+
sdk)
|
298
302
|
end
|
299
303
|
|
300
304
|
dirs = (possible + existing).uniq
|
@@ -646,10 +650,11 @@ module RunLoop
|
|
646
650
|
# The absolute path to the iPhone Simulator Application Support directory.
|
647
651
|
# @return [String] absolute path
|
648
652
|
def sim_app_support_dir
|
653
|
+
home_dir = RunLoop::Environment.user_home_directory
|
649
654
|
if xcode_version_gte_6?
|
650
|
-
File.
|
655
|
+
File.join(home_dir, "Library", "Developer", "CoreSimulator", "Devices")
|
651
656
|
else
|
652
|
-
File.
|
657
|
+
File.join(home_dir, "Library", "Application Support", "iPhone Simulator")
|
653
658
|
end
|
654
659
|
end
|
655
660
|
|
data/lib/run_loop/version.rb
CHANGED
data/lib/run_loop/xcuitest.rb
CHANGED
@@ -3,6 +3,9 @@ module RunLoop
|
|
3
3
|
# @!visibility private
|
4
4
|
class XCUITest
|
5
5
|
|
6
|
+
require "run_loop/shell"
|
7
|
+
include RunLoop::Shell
|
8
|
+
|
6
9
|
class HTTPError < RuntimeError; end
|
7
10
|
|
8
11
|
# @!visibility private
|
@@ -38,59 +41,64 @@ module RunLoop
|
|
38
41
|
core_sim.install
|
39
42
|
end
|
40
43
|
|
41
|
-
|
44
|
+
cbx_launcher = XCUITest.detect_cbx_launcher(options, device)
|
45
|
+
|
46
|
+
xcuitest = RunLoop::XCUITest.new(bundle_id, device, cbx_launcher)
|
42
47
|
xcuitest.launch
|
43
48
|
xcuitest
|
44
49
|
end
|
45
50
|
|
46
51
|
# @!visibility private
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
#
|
53
|
+
# @param [RunLoop::Device] device the device under test
|
54
|
+
def self.default_cbx_launcher(device)
|
55
|
+
RunLoop::DeviceAgent::XCTestctl.new(device)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @!visibility private
|
59
|
+
# @param [Hash] options the options passed by the user
|
60
|
+
# @param [RunLoop::Device] device the device under test
|
61
|
+
def self.detect_cbx_launcher(options, device)
|
62
|
+
value = options[:cbx_launcher]
|
63
|
+
if value
|
64
|
+
if value == :xcodebuild
|
65
|
+
RunLoop::DeviceAgent::Xcodebuild.new(device)
|
66
|
+
elsif value == :xctestctl
|
67
|
+
RunLoop::DeviceAgent::XCTestctl.new(device)
|
68
|
+
else
|
69
|
+
raise(ArgumentError,
|
70
|
+
"Expected :cbx_launcher => #{value} to be :xcodebuild or :xctestctl")
|
71
|
+
end
|
72
|
+
else
|
73
|
+
XCUITest.default_cbx_launcher(device)
|
74
|
+
end
|
51
75
|
end
|
52
76
|
|
77
|
+
attr_reader :bundle_id, :device, :cbx_launcher
|
78
|
+
|
53
79
|
# @!visibility private
|
54
80
|
#
|
55
81
|
# The app with `bundle_id` needs to be installed.
|
56
82
|
#
|
57
83
|
# @param [String] bundle_id The identifier of the app under test.
|
58
84
|
# @param [RunLoop::Device] device The device device.
|
59
|
-
def initialize(bundle_id, device)
|
85
|
+
def initialize(bundle_id, device, cbx_launcher)
|
60
86
|
@bundle_id = bundle_id
|
61
87
|
@device = device
|
88
|
+
@cbx_launcher = cbx_launcher
|
62
89
|
end
|
63
90
|
|
91
|
+
# @!visibility private
|
64
92
|
def to_s
|
65
|
-
"#<XCUITest #{url} : #{bundle_id} : #{device}>"
|
93
|
+
"#<XCUITest #{url} : #{bundle_id} : #{device} : #{cbx_launcher}>"
|
66
94
|
end
|
67
95
|
|
96
|
+
# @!visibility private
|
68
97
|
def inspect
|
69
98
|
to_s
|
70
99
|
end
|
71
100
|
|
72
101
|
# @!visibility private
|
73
|
-
def bundle_id
|
74
|
-
@bundle_id
|
75
|
-
end
|
76
|
-
|
77
|
-
# @!visibility private
|
78
|
-
def device
|
79
|
-
@device
|
80
|
-
end
|
81
|
-
|
82
|
-
# @!visibility private
|
83
|
-
def workspace
|
84
|
-
@workspace ||= lambda do
|
85
|
-
path = RunLoop::Environment.send(:cbxws)
|
86
|
-
if path
|
87
|
-
path
|
88
|
-
else
|
89
|
-
raise "TODO: figure out how to distribute the CBX-Runner"
|
90
|
-
end
|
91
|
-
end.call
|
92
|
-
end
|
93
|
-
|
94
102
|
def launch
|
95
103
|
start = Time.now
|
96
104
|
launch_cbx_runner
|
@@ -123,6 +131,15 @@ module RunLoop
|
|
123
131
|
launch_aut(bundle_id)
|
124
132
|
end
|
125
133
|
|
134
|
+
# @!visibility private
|
135
|
+
def runtime
|
136
|
+
options = http_options
|
137
|
+
request = request("device")
|
138
|
+
client = client(options)
|
139
|
+
response = client.get(request)
|
140
|
+
expect_200_response(response)
|
141
|
+
end
|
142
|
+
|
126
143
|
# @!visibility private
|
127
144
|
def query(mark)
|
128
145
|
options = http_options
|
@@ -134,23 +151,50 @@ module RunLoop
|
|
134
151
|
end
|
135
152
|
|
136
153
|
# @!visibility private
|
137
|
-
def
|
154
|
+
def query_for_coordinate(mark)
|
138
155
|
body = query(mark)
|
139
|
-
|
156
|
+
coordinate_from_query_result(body)
|
140
157
|
end
|
141
158
|
|
142
159
|
# @!visibility private
|
143
|
-
def
|
144
|
-
|
145
|
-
|
146
|
-
|
160
|
+
def tap_mark(mark)
|
161
|
+
coordinate = query_for_coordinate(mark)
|
162
|
+
tap_coordinate(coordinate[:x], coordinate[:y])
|
163
|
+
end
|
164
|
+
|
165
|
+
# @!visibility private
|
166
|
+
def tap_coordinate(x, y, options)
|
167
|
+
make_coordinate_gesture_request("touch", x, y)
|
168
|
+
end
|
169
|
+
|
170
|
+
# @!visibility private
|
171
|
+
def double_tap(x, y)
|
172
|
+
make_coordinate_gesture_request("double_tap", x, y)
|
173
|
+
end
|
174
|
+
|
175
|
+
# @!visibiity private
|
176
|
+
def coordinate_gesture_parameters(name, x, y, options={})
|
177
|
+
{
|
178
|
+
:gesture => name,
|
147
179
|
:specifiers => {
|
148
|
-
:coordinate =>
|
180
|
+
:coordinate => [x, y]
|
149
181
|
},
|
150
|
-
:options =>
|
182
|
+
:options => options
|
151
183
|
}
|
152
|
-
|
153
|
-
|
184
|
+
end
|
185
|
+
|
186
|
+
# @!visibility private
|
187
|
+
def coordinate_gesture_request(name, x, y, gesture_options={})
|
188
|
+
parameters = coordinate_gesture_parameters(name, x, y, gesture_options)
|
189
|
+
request("gesture", parameters)
|
190
|
+
end
|
191
|
+
|
192
|
+
# @!visibility private
|
193
|
+
def make_coordinate_gesture_request(name, x, y, options={})
|
194
|
+
gesture_options = options.fetch(:gesture_options, {})
|
195
|
+
http_options = options.fetch(:http_options, http_options())
|
196
|
+
request = coordinate_gesture_request(name, x, y, gesture_options)
|
197
|
+
client = client(http_options)
|
154
198
|
response = client.post(request)
|
155
199
|
expect_200_response(response)
|
156
200
|
end
|
@@ -162,7 +206,7 @@ module RunLoop
|
|
162
206
|
:orientation => orientation
|
163
207
|
}
|
164
208
|
request = request("rotate_home_button_to", parameters)
|
165
|
-
client(http_options)
|
209
|
+
client = client(http_options)
|
166
210
|
response = client.post(request)
|
167
211
|
json = expect_200_response(response)
|
168
212
|
sleep(sleep_for)
|
@@ -179,23 +223,46 @@ module RunLoop
|
|
179
223
|
:options => options
|
180
224
|
}
|
181
225
|
|
226
|
+
RunLoop.log_debug(%Q[
|
227
|
+
Sending request to perform '#{gesture}' with:
|
228
|
+
|
229
|
+
#{JSON.pretty_generate(parameters)}
|
230
|
+
|
231
|
+
])
|
182
232
|
request = request("gesture", parameters)
|
183
|
-
client(http_options)
|
233
|
+
client = client(http_options)
|
184
234
|
response = client.post(request)
|
185
235
|
expect_200_response(response)
|
186
236
|
end
|
187
237
|
|
188
238
|
# @!visibility private
|
189
|
-
def
|
190
|
-
|
239
|
+
def coordinate_from_query_result(hash)
|
240
|
+
matches = hash["result"]
|
241
|
+
|
242
|
+
if matches.nil? || matches.empty?
|
243
|
+
raise "Expected #{hash} to contain some results"
|
244
|
+
end
|
245
|
+
|
246
|
+
rect = matches.first["rect"]
|
191
247
|
h = rect["height"]
|
192
248
|
w = rect["width"]
|
193
249
|
x = rect["x"]
|
194
250
|
y = rect["y"]
|
195
251
|
|
196
|
-
touchx = x + (
|
197
|
-
touchy = y + (
|
198
|
-
|
252
|
+
touchx = x + (w/2.0)
|
253
|
+
touchy = y + (h/2.0)
|
254
|
+
|
255
|
+
new_rect = rect.dup
|
256
|
+
new_rect[:center_x] = touchx
|
257
|
+
new_rect[:center_y] = touchy
|
258
|
+
|
259
|
+
RunLoop.log_debug(%Q[Rect from query:
|
260
|
+
|
261
|
+
#{JSON.pretty_generate(new_rect)}
|
262
|
+
|
263
|
+
])
|
264
|
+
{:x => touchx,
|
265
|
+
:y => touchy}
|
199
266
|
end
|
200
267
|
|
201
268
|
private
|
@@ -223,7 +290,7 @@ module RunLoop
|
|
223
290
|
:undef => :replace, # Replace anything not defined in ASCII
|
224
291
|
:replace => "" # Use a blank for those replacements
|
225
292
|
}
|
226
|
-
encoded = device_name.encode(Encoding.find("ASCII"), encoding_options)
|
293
|
+
encoded = device_name.encode(::Encoding.find("ASCII"), encoding_options)
|
227
294
|
"http://#{encoded}.local:27753/"
|
228
295
|
end
|
229
296
|
end
|
@@ -296,14 +363,6 @@ module RunLoop
|
|
296
363
|
response = client.post(request)
|
297
364
|
body = response.body
|
298
365
|
RunLoop.log_debug("CBX-Runner says, \"#{body}\"")
|
299
|
-
5.times do
|
300
|
-
begin
|
301
|
-
health
|
302
|
-
sleep(1.0)
|
303
|
-
rescue => _
|
304
|
-
break
|
305
|
-
end
|
306
|
-
end
|
307
366
|
body
|
308
367
|
rescue => e
|
309
368
|
RunLoop.log_debug("CBX-Runner shutdown error: #{e}")
|
@@ -323,65 +382,22 @@ module RunLoop
|
|
323
382
|
body
|
324
383
|
end
|
325
384
|
|
326
|
-
# @!visibility private
|
327
|
-
def xcodebuild
|
328
|
-
env = {
|
329
|
-
"COMMAND_LINE_BUILD" => "1"
|
330
|
-
}
|
331
|
-
|
332
|
-
args = [
|
333
|
-
"xcrun",
|
334
|
-
"xcodebuild",
|
335
|
-
"-scheme", "CBXAppStub",
|
336
|
-
"-workspace", workspace,
|
337
|
-
"-config", "Debug",
|
338
|
-
"-destination",
|
339
|
-
"id=#{device.udid}",
|
340
|
-
"clean",
|
341
|
-
"test"
|
342
|
-
]
|
343
|
-
|
344
|
-
log_file = XCUITest.xcodebuild_log_file
|
345
|
-
|
346
|
-
options = {
|
347
|
-
:out => log_file,
|
348
|
-
:err => log_file
|
349
|
-
}
|
350
|
-
|
351
|
-
command = "#{env.map.each { |k, v| "#{k}=#{v}" }.join(" ")} #{args.join(" ")}"
|
352
|
-
RunLoop.log_unix_cmd("#{command} >& #{log_file}")
|
353
|
-
|
354
|
-
pid = Process.spawn(env, *args, options)
|
355
|
-
Process.detach(pid)
|
356
|
-
pid
|
357
|
-
end
|
358
|
-
|
359
385
|
# @!visibility private
|
360
386
|
def launch_cbx_runner
|
361
|
-
# Fail fast if CBXWS is not defined.
|
362
|
-
# WIP - we will distribute the workspace somehow.
|
363
|
-
workspace
|
364
|
-
|
365
387
|
shutdown
|
366
388
|
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
# quits the simulator
|
372
|
-
sim = CoreSimulator.new(device, "")
|
373
|
-
sim.launch_simulator
|
374
|
-
else
|
375
|
-
# anything special about physical devices?
|
376
|
-
end
|
389
|
+
options = {:log_cmd => true}
|
390
|
+
exec(["pkill", "xctestctl"], options)
|
391
|
+
exec(["pkill", "testmanagerd"], options)
|
392
|
+
exec(["pkill", "xcodebuild"], options)
|
377
393
|
|
378
394
|
start = Time.now
|
379
|
-
|
380
|
-
|
395
|
+
RunLoop.log_debug("Waiting for CBX-Runner to launch...")
|
396
|
+
pid = cbx_launcher.launch
|
381
397
|
health
|
398
|
+
RunLoop.log_debug("Took #{Time.now - start} launch and respond to /health")
|
382
399
|
|
383
|
-
|
384
|
-
pid.to_i
|
400
|
+
pid
|
385
401
|
end
|
386
402
|
|
387
403
|
# @!visibility private
|
@@ -423,26 +439,28 @@ Something went wrong.
|
|
423
439
|
# @!visibility private
|
424
440
|
def expect_200_response(response)
|
425
441
|
body = response_body_to_hash(response)
|
426
|
-
|
442
|
+
if response.status_code < 300 && !body["error"]
|
443
|
+
return body
|
444
|
+
end
|
427
445
|
|
428
|
-
|
429
|
-
|
446
|
+
if response.status_code > 300
|
447
|
+
raise RunLoop::XCUITest::HTTPError,
|
448
|
+
%Q[Expected status code < 300, found #{response.status_code}.
|
430
449
|
|
431
450
|
Server replied with:
|
432
451
|
|
433
452
|
#{body}
|
453
|
+
|
434
454
|
]
|
435
|
-
|
455
|
+
else
|
456
|
+
raise RunLoop::XCUITest::HTTPError,
|
457
|
+
%Q[Expected JSON response with no error, but found
|
436
458
|
|
437
|
-
|
438
|
-
def self.dot_dir
|
439
|
-
path = File.join(RunLoop::DotDir.directory, "xcuitest")
|
459
|
+
#{body["error"]}
|
440
460
|
|
441
|
-
|
442
|
-
FileUtils.mkdir_p(path)
|
443
|
-
end
|
461
|
+
]
|
444
462
|
|
445
|
-
|
463
|
+
end
|
446
464
|
end
|
447
465
|
|
448
466
|
# @!visibility private
|
data/scripts/lib/log.js
CHANGED
@@ -17,7 +17,7 @@ var Log = (function () {
|
|
17
17
|
|
18
18
|
return {
|
19
19
|
result: function (status, data) {
|
20
|
-
log_json({"status": status, "value": data, "index":_actualIndex})
|
20
|
+
log_json({"status": status, "value": data, "index":_actualIndex});
|
21
21
|
},
|
22
22
|
output: function (msg) {
|
23
23
|
log_json({"output": msg,"last_index":_actualIndex});
|
data/scripts/lib/on_alert.js
CHANGED
@@ -5,9 +5,9 @@ function findAlertTitle(alert) {
|
|
5
5
|
var title = alert.name();
|
6
6
|
var staticTexts;
|
7
7
|
|
8
|
-
if (title
|
8
|
+
if (title === null) {
|
9
9
|
staticTexts = alert.staticTexts();
|
10
|
-
if (staticTexts
|
10
|
+
if (staticTexts !== null && staticTexts.length > 0) {
|
11
11
|
|
12
12
|
title = staticText[0].name();
|
13
13
|
}
|
@@ -49,31 +49,85 @@ function englishLocalizations() {
|
|
49
49
|
|
50
50
|
function danishLocalizations() {
|
51
51
|
return [
|
52
|
-
// Location
|
53
52
|
["Tillad", /bruge din lokalitet, når du bruger appen/],
|
54
53
|
["Tillad", /også når du ikke bruger appen/],
|
55
|
-
["OK", /vil bruge din aktuelle placering/]
|
54
|
+
["OK", /vil bruge din aktuelle placering/],
|
55
|
+
["OK", /vil bruge dine kontakter/],
|
56
|
+
["OK", /vil bruge mikrofonen/],
|
57
|
+
["OK", /vil bruge din kalender/],
|
58
|
+
["OK", /vil bruge dine påmindelser/],
|
59
|
+
["OK", /vil bruge dine fotos/],
|
60
|
+
["OK", /ønsker adgang til Twitter-konti/],
|
61
|
+
["OK", /vil bruge din fysiske aktivitet og din træningsaktivitet/],
|
62
|
+
["OK", /vil bruge kameraet/],
|
63
|
+
["OK", /vil gerne sende dig meddelelser/]
|
56
64
|
];
|
57
65
|
}
|
58
66
|
|
59
|
-
function
|
67
|
+
function euSpanishLocalizations() {
|
68
|
+
return [
|
69
|
+
["Permitir", /acceder a tu ubicación mientras utilizas la aplicación/],
|
70
|
+
["Permitir", /acceder a tu ubicación aunque no estés utilizando la aplicación/],
|
71
|
+
["OK", /quiere acceder a tus contactos/],
|
72
|
+
["OK", /quiere acceder a tu calendario/],
|
73
|
+
["OK", /quiere acceder a tus recordatorios/],
|
74
|
+
["OK", /quiere acceder a tus fotos/],
|
75
|
+
["OK", /quiere obtener acceso a cuentas Twitter/],
|
76
|
+
["OK", /quiere acceder al micrófono/],
|
77
|
+
["OK", /desea acceder a tu actividad física y deportiva/],
|
78
|
+
["OK", /quiere acceder a la cámara/],
|
79
|
+
["OK", /quiere enviarte notificaciones/]
|
80
|
+
];
|
81
|
+
}
|
82
|
+
|
83
|
+
function es419SpanishLocalizations() {
|
60
84
|
return [
|
61
|
-
|
62
|
-
["
|
85
|
+
["Permitir", /acceda a tu ubicación mientras la app está en uso/],
|
86
|
+
["Permitir", /acceda a tu ubicación incluso cuando la app no está en uso/],
|
87
|
+
["OK", /quiere acceder a tu condición y actividad física/]
|
63
88
|
];
|
64
89
|
}
|
65
90
|
|
91
|
+
function spanishLocalizations() {
|
92
|
+
return [].concat(
|
93
|
+
euSpanishLocalizations(),
|
94
|
+
es419SpanishLocalizations()
|
95
|
+
);
|
96
|
+
}
|
97
|
+
|
66
98
|
function germanLocalizations() {
|
67
99
|
return [
|
68
|
-
|
69
|
-
["
|
100
|
+
["Ja", /Darf (?:.)+ Ihren aktuellen Ort verwenden/],
|
101
|
+
["Erlauben", /auf Ihren Standort zugreifen, wenn Sie die App benutzen/],
|
102
|
+
["Erlauben", /auch auf Ihren Standort zugreifen, wenn Sie die App nicht benutzen/],
|
103
|
+
["Erlauben", /auf Ihren Standort zugreifen, selbst wenn Sie die App nicht benutzen/],
|
104
|
+
["Ja", /auf Ihre Kontakte zugreifen/],
|
105
|
+
["Ja", /auf Ihren Kalender zugreifen/],
|
106
|
+
["Ja", /auf Ihre Erinnerungen zugreifen/],
|
107
|
+
["Ja", /auf Ihre Fotos zugreifen/],
|
108
|
+
["Erlauben", /möchte auf Twitter-Accounts zugreifen/],
|
109
|
+
["Ja", /auf das Mikrofon zugreifen/],
|
110
|
+
["Ja", /möchte auf Ihre Bewegungs- und Fitnessdaten zugreifen/],
|
111
|
+
["Ja", /auf Ihre Kamera zugreifen/],
|
112
|
+
["OK", /Ihnen Mitteilungen senden/]
|
70
113
|
];
|
71
114
|
}
|
72
115
|
|
73
116
|
function dutchLocalizations() {
|
74
117
|
return [
|
75
|
-
|
76
|
-
["
|
118
|
+
["Sta toe", /tot uw locatie toestaan terwijl u de app gebruikt/],
|
119
|
+
["Sta toe", /toegang tot uw locatie toestaan terwijl u de app gebruikt/],
|
120
|
+
["Sta toe", /ook toegang tot uw locatie toestaan, zelfs als u de app niet gebruikt/],
|
121
|
+
["Sta toe", /toegang tot uw locatie toestaan, zelfs als u de app niet gebruikt/],
|
122
|
+
["OK", /wil toegang tot uw contacten/],
|
123
|
+
["OK", /wil toegang tot uw agenda/],
|
124
|
+
["OK", /wil toegang tot uw herinneringen/],
|
125
|
+
["OK", /wil toegang tot uw foto's/],
|
126
|
+
["OK", /wil toegang tot Twitter-accounts/],
|
127
|
+
["OK", /wil toegang tot de microfoon/],
|
128
|
+
["OK", /wil toegang tot uw bewegings- en fitnessactiviteit/],
|
129
|
+
["OK", /wil toegang tot de camera/],
|
130
|
+
["OK", /wil u berichten sturen/]
|
77
131
|
];
|
78
132
|
}
|
79
133
|
|
@@ -89,13 +143,15 @@ function frenchLocalizations() {
|
|
89
143
|
["OK", /vous envoyer des notifications/],
|
90
144
|
["Autoriser", /à accéder à vos données de localisation lorsque vous utilisez l’app/],
|
91
145
|
["Autoriser", /à accéder à vos données de localisation même lorsque vous n’utilisez pas l’app/],
|
146
|
+
["Autoriser", /à accéder aussi à vos données de localisation lorsque vous n’utilisez pas l’app/],
|
92
147
|
["OK", /souhaite accéder à vos contacts/],
|
93
148
|
["OK", /souhaite accéder à votre calendrier/],
|
94
149
|
["OK", /souhaite accéder à vos rappels/],
|
95
150
|
["OK", /souhaite accéder à vos mouvements et vos activités physiques/],
|
96
151
|
["OK", /souhaite accéder à vos photos/],
|
97
152
|
["OK", /souhaite accéder à l’appareil photo/],
|
98
|
-
["OK", /souhaite accéder aux comptes Twitter/]
|
153
|
+
["OK", /souhaite accéder aux comptes Twitter/],
|
154
|
+
["OK", /souhaite accéder au micro/]
|
99
155
|
];
|
100
156
|
}
|
101
157
|
|
@@ -117,13 +173,42 @@ function isPrivacyAlert(alert) {
|
|
117
173
|
|
118
174
|
var title = findAlertTitle(alert);
|
119
175
|
|
120
|
-
// Comment this out
|
121
|
-
Log.output({"
|
176
|
+
// Comment this out when capturing new regexes. See the comment below.
|
177
|
+
Log.output({"alert":title});
|
122
178
|
|
123
179
|
// When debugging or trying to capture the regexes for a new
|
124
|
-
// localization, uncomment
|
125
|
-
//
|
126
|
-
//
|
180
|
+
// localization, uncomment the logging below.
|
181
|
+
//
|
182
|
+
// Notes:
|
183
|
+
// * Microphone alerts only appear on physical devices.
|
184
|
+
// * You have to click through the Health alert; it is completely blocking -
|
185
|
+
// tests will not proceed.
|
186
|
+
// * Generating bluetooth alerts is NYI.
|
187
|
+
// * In general, there will be a different alert on device for using location
|
188
|
+
// in background mode.
|
189
|
+
// * Alerts vary by iOS.
|
190
|
+
// * To reset notifications on devices:
|
191
|
+
// General > Settings > Reset > Reset Location + Privacy
|
192
|
+
// - These are the last table rows
|
193
|
+
// - APNS permissions are reset once a day.
|
194
|
+
// * On devices, set the device language in Settings.
|
195
|
+
//
|
196
|
+
// Use the Permission.app.
|
197
|
+
//
|
198
|
+
// * Alert text is printed at the end of every test.
|
199
|
+
// * Alert text is written to a file in Permissions/tmp.
|
200
|
+
//
|
201
|
+
// Examples:
|
202
|
+
//
|
203
|
+
// # Simulator running Mexican Spanish
|
204
|
+
// $ APP_LANG="es-MX" APP_LOCALE="es_MX" be cucumber -t @supported
|
205
|
+
//
|
206
|
+
// # Device running Dutch
|
207
|
+
// $ APP_LANG="nl" APP_LOCALE="nl" be cucumber -t @supported -p macmini
|
208
|
+
|
209
|
+
// This is very slow, so only do this if you are trying to capture regexes.
|
210
|
+
//var buttonNames = findAlertButtonNames(alert);
|
211
|
+
//Log.output({"alert":{"title":title, "buttons":buttonNames, "capture":"YES"}});
|
127
212
|
|
128
213
|
var answer;
|
129
214
|
var expression;
|