run_loop 1.0.0.pre6 → 1.0.0.pre7
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/lib/run_loop/core.rb +63 -47
- data/lib/run_loop/version.rb +1 -1
- data/scripts/calabash-uia-min.js +7 -0
- data/scripts/run_loop_basic.js +243 -0
- data/scripts/run_loop_fast_uia.js +0 -19
- data/scripts/run_loop_host.js +10 -11
- metadata +32 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b994124cd00426192ac1b1a472240aefb2b73d4
|
4
|
+
data.tar.gz: 3befda188493d2497c5a67d771af54930f546be6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bae24d78425be262be8fdfbbc69810bbe3c7018c13a61e8f499aaaf29d50f406b6d7b01e54d94438a93915467ba338891e8e476fce119b45b558778fab0f9a7
|
7
|
+
data.tar.gz: 55bdff09ded29ade3098fa8152a19810d38405973d4e93b015e27771020da923df078db44a1d0f7693679e04e42c43cf7e1f02af1a6d76ac79279f1fa98039cd
|
data/lib/run_loop/core.rb
CHANGED
@@ -19,7 +19,8 @@ module RunLoop
|
|
19
19
|
SCRIPTS = {
|
20
20
|
:dismiss => 'run_dismiss_location.js',
|
21
21
|
:run_loop_fast_uia => 'run_loop_fast_uia.js',
|
22
|
-
:run_loop_host => 'run_loop_host.js'
|
22
|
+
:run_loop_host => 'run_loop_host.js',
|
23
|
+
:run_loop_basic => 'run_loop_basic.js'
|
23
24
|
}
|
24
25
|
|
25
26
|
READ_SCRIPT_PATH = File.join(SCRIPTS_PATH, 'read-cmd.sh')
|
@@ -196,15 +197,18 @@ module RunLoop
|
|
196
197
|
before = Time.now
|
197
198
|
begin
|
198
199
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
200
|
+
if options[:validate_channel]
|
201
|
+
options[:validate_channel].call(run_loop, 0, uia_timeout)
|
202
|
+
else
|
203
|
+
File.open(repl_path, 'w') { |file| file.puts "0:UIALogger.logMessage('Listening for run loop commands');" }
|
204
|
+
Timeout::timeout(timeout, TimeoutError) do
|
205
|
+
read_response(run_loop, 0, uia_timeout)
|
206
|
+
end
|
203
207
|
end
|
204
208
|
|
205
209
|
# inject_dylib will be nil or a path to a dylib
|
206
210
|
if inject_dylib
|
207
|
-
lldb_template_file = File.join(scripts_path,'calabash.lldb.erb')
|
211
|
+
lldb_template_file = File.join(scripts_path, 'calabash.lldb.erb')
|
208
212
|
lldb_template = ::ERB.new(File.read(lldb_template_file))
|
209
213
|
lldb_template.filename = lldb_template_file
|
210
214
|
|
@@ -218,9 +222,9 @@ module RunLoop
|
|
218
222
|
lldb_cmd = lldb_template.result(binding)
|
219
223
|
|
220
224
|
tmpdir = Dir.mktmpdir('lldb_cmd')
|
221
|
-
lldb_script = File.join(tmpdir,'lldb')
|
225
|
+
lldb_script = File.join(tmpdir, 'lldb')
|
222
226
|
|
223
|
-
File.open(lldb_script,'w') {|f| f.puts(lldb_cmd)}
|
227
|
+
File.open(lldb_script, 'w') { |f| f.puts(lldb_cmd) }
|
224
228
|
|
225
229
|
if ENV['DEBUG'] == '1'
|
226
230
|
puts "lldb script #{lldb_script}"
|
@@ -323,7 +327,7 @@ module RunLoop
|
|
323
327
|
unless File.directory?(bundle_dir_or_bundle_id)
|
324
328
|
raise "Injecting dylibs currently only works with simulator and app bundles"
|
325
329
|
end
|
326
|
-
info_plist = Dir[File.join(bundle_dir_or_bundle_id,'Info.plist')].first
|
330
|
+
info_plist = Dir[File.join(bundle_dir_or_bundle_id, 'Info.plist')].first
|
327
331
|
raise "Unable to find Info.plist in #{bundle_dir_or_bundle_id}" if info_plist.nil?
|
328
332
|
`/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "#{info_plist}"`.strip
|
329
333
|
end
|
@@ -392,7 +396,7 @@ module RunLoop
|
|
392
396
|
def self.write_request(run_loop, cmd)
|
393
397
|
repl_path = run_loop[:repl_path]
|
394
398
|
index = run_loop[:index]
|
395
|
-
File.open(repl_path, 'w') {|f| f.puts("#{index}:#{cmd}")}
|
399
|
+
File.open(repl_path, 'w') { |f| f.puts("#{index}:#{cmd}") }
|
396
400
|
run_loop[:index] = index + 1
|
397
401
|
|
398
402
|
index
|
@@ -580,7 +584,7 @@ module RunLoop
|
|
580
584
|
descripts = `xcrun ps x -o pid,command | grep "lldb" | grep -v grep`.strip.split("\n")
|
581
585
|
descripts.each do |process_desc|
|
582
586
|
pid = process_desc.split(' ').first
|
583
|
-
Open3.popen3("xcrun kill -9 #{pid} && xcrun wait #{pid}") do
|
587
|
+
Open3.popen3("xcrun kill -9 #{pid} && xcrun wait #{pid}") do |_, stdout, stderr, _|
|
584
588
|
out = stdout.read.strip
|
585
589
|
err = stderr.read.strip
|
586
590
|
next if out.to_s.empty? and err.to_s.empty?
|
@@ -591,19 +595,49 @@ module RunLoop
|
|
591
595
|
end
|
592
596
|
end
|
593
597
|
|
598
|
+
def self.default_script_for_uia_strategy(uia_strategy)
|
599
|
+
case uia_strategy
|
600
|
+
when :preferences
|
601
|
+
Core.script_for_key(:run_loop_fast_uia)
|
602
|
+
when :host
|
603
|
+
Core.script_for_key(:run_loop_host)
|
604
|
+
else
|
605
|
+
Core.script_for_key(:run_loop_basic)
|
606
|
+
end
|
607
|
+
end
|
594
608
|
|
595
609
|
def self.run(options={})
|
596
|
-
|
597
610
|
uia_strategy = options[:uia_strategy]
|
598
|
-
if
|
599
|
-
|
600
|
-
|
611
|
+
if options[:script]
|
612
|
+
script = validate_script(options[:script])
|
613
|
+
else
|
614
|
+
if uia_strategy
|
615
|
+
script = default_script_for_uia_strategy(uia_strategy)
|
601
616
|
else
|
602
|
-
|
617
|
+
if options[:calabash_lite]
|
618
|
+
uia_strategy = :host
|
619
|
+
script = Core.script_for_key(:run_loop_host)
|
620
|
+
else
|
621
|
+
uia_strategy = :preferences
|
622
|
+
script = default_script_for_uia_strategy(uia_strategy)
|
623
|
+
end
|
603
624
|
end
|
604
|
-
else
|
605
|
-
uia_strategy, script = validate_script(options)
|
606
625
|
end
|
626
|
+
# At this point, 'script' has been chosen, but uia_strategy might not
|
627
|
+
unless uia_strategy
|
628
|
+
desired_script = options[:script]
|
629
|
+
if desired_script.is_a?(String) #custom path to script
|
630
|
+
uia_strategy = :host
|
631
|
+
elsif desired_script == :run_loop_host
|
632
|
+
uia_strategy = :host
|
633
|
+
elsif desired_script == :run_loop_fast_uia
|
634
|
+
uia_strategy = :preferences
|
635
|
+
else
|
636
|
+
raise "Inconsistent state: desired script #{desired_script} has not uia_strategy"
|
637
|
+
end
|
638
|
+
end
|
639
|
+
# At this point script and uia_strategy selected
|
640
|
+
|
607
641
|
options[:script] = script
|
608
642
|
options[:uia_strategy] = uia_strategy
|
609
643
|
|
@@ -655,38 +689,20 @@ module RunLoop
|
|
655
689
|
end
|
656
690
|
|
657
691
|
|
658
|
-
def self.validate_script(
|
659
|
-
if
|
660
|
-
|
661
|
-
|
662
|
-
uia_strategy = options[:uia_strategy]
|
663
|
-
if uia_strategy
|
664
|
-
if uia_strategy == :host
|
665
|
-
script = :run_loop_host
|
666
|
-
elsif uia_strategy == :preferences
|
667
|
-
script = :run_loop_fast_uia
|
668
|
-
else
|
669
|
-
raise "Invalid :uia_strategy #{uia_strategy}"
|
692
|
+
def self.validate_script(script)
|
693
|
+
if script.is_a?(String)
|
694
|
+
unless File.exist?(script)
|
695
|
+
raise "Unable to find file: #{script}"
|
670
696
|
end
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
if script
|
676
|
-
if script.is_a?(Symbol)
|
677
|
-
uia_strategy = (script == :run_loop_fast_uia ? :preferences : :host)
|
678
|
-
script = Core.script_for_key(script)
|
679
|
-
unless script
|
680
|
-
raise "Unknown script for symbol: #{options[:script]}. Options: #{Core::SCRIPTS.keys.join(', ')}"
|
681
|
-
end
|
682
|
-
else
|
683
|
-
raise "Script must be a symbol: #{script}"
|
697
|
+
elsif script.is_a?(Symbol)
|
698
|
+
script = Core.script_for_key(script)
|
699
|
+
unless script
|
700
|
+
raise "Unknown script for symbol: #{script}. Options: #{Core::SCRIPTS.keys.join(', ')}"
|
684
701
|
end
|
685
702
|
else
|
686
|
-
|
687
|
-
uia_strategy = :preferences
|
703
|
+
raise "Script must be a symbol or path: #{script}"
|
688
704
|
end
|
689
|
-
|
705
|
+
script
|
690
706
|
end
|
691
707
|
|
692
|
-
end
|
708
|
+
end
|
data/lib/run_loop/version.rb
CHANGED
@@ -0,0 +1,7 @@
|
|
1
|
+
(function(){function m(){return h.frontMostApp()}function r(){return m().mainWindow()}function s(){return m().windows().toArray()}function n(){return m().keyboard()}function l(a,c){this.reason=a;this.a=c||"";this.message=this.toString()}function k(a){return!a||a instanceof UIAElementNil}function t(a,c){var b=c||[],e,d;if(k(a))return b;e=a.elements();for(var f=0,g=e.length;f<g;f+=1)d=e[f],b.push(d),t(d,b);return b}function q(a,c){for(var b=0,e=c.length;b<e;b+=1)a.push(c[b])}function u(a,c){var b=[];
|
2
|
+
if(k(c))return b;c instanceof this[a]&&b.push(c);for(var e=c.elements(),d=0,f=e.length;d<f;d+=1)q(b,u(a,e[d]));return b}function x(a,c){var b=null;if(a instanceof Array){if(3===a.length){var e=a[0],b=a[1],d=a[2];if("string"==typeof d)if(-1==d.indexOf("'"))d="'"+d+"'";else if(-1==d.indexOf('"'))d='"'+d+'"';else throw new l("Escaping for filters not supported yet.");b=c.withPredicate(e+" "+b+" "+d);return!k(b)}return!1}for(e in a)if(a.hasOwnProperty(e))if(b=a[e],"marked"==e){if(c.name()!=b&&c.label()!=
|
3
|
+
b&&(!c.value||c.value!=b))return!1}else if(b=c.withValueForKey(b,e),k(b))return!1;return!0}function v(a,c){if(c(a))return a;var b,e;if(k(a))return null;b=a.elements();for(var d=0,f=b.length;d<f;d+=1)if(e=b[d],v(e,c))return e;return null}function w(a){h.delay(a);return h}var g={},h=UIATarget.localTarget();h.setTimeout(0);l.prototype=error();l.prototype.toString=function(){var a="UIAutomationError[reason="+this.reason;0<this.a.length&&(a+=", details="+this.a);return a+"]"};g.sleep=w;g.query=function(a,
|
4
|
+
c){if(!c)return g.query(a,s());c instanceof UIAElement&&(c=[c]);var b=c,e=null,d=null,f=[],p,h,k,l;p=0;for(k=a.length;p<k;p+=1){e=a[p];h=0;for(l=b.length;h<l;h+=1)d=b[h],"string"===typeof e?"*"===e||"view"==e||"UIAElement"===e?q(f,t(d,[d])):q(f,u(e,d)):x(e,d)&&f.push(d);b=f;f=[]}return b};g.keyboard_visible=function(){return!k(n())};g.keyboard_enter_text=function(a,c){if(!g.keyboard_visible())throw new l("Keyboard not visible");c=c||{};if(c.unsafe)return n().typeString(a),!0;var b=v(r(),function(a){return 1==
|
5
|
+
a.hasKeyboardFocus()});if(k(b))return n().typeString(a),!0;var e=c.initial_text||"",d=new Date,f=c.timeout||60,h=n();do try{return h.typeString(a),!0}catch(m){UIALogger.logMessage("keyboard_enter_text failed: "+m),UIALogger.logMessage("keyboard_enter_text retrying with restore to: "+e),b.setValue(e)}while(!(new Date-d>=1E3*f));throw new l("Unable to enter text","text: "+a+" failed after retrying for "+f);};g.deactivate=function(a){h.deactivateAppForDuration(a)};g.tap_offset=function(a,c,b){b=b||{};
|
6
|
+
return b.unsafe?function(){return c.apply(this,arguments)}:function(){var e=new Date,d=b.timeout||60,f=b.frequency||.1;do try{return c.apply(this,arguments)}catch(g){UIALogger.logMessage(a+"Error: "+g+". Arguments: "+arguments[0]+", "+arguments[1]),w(f)}while(!(new Date-e>=1E3*d));throw new l(a,"Arguments: "+arguments[0]+", "+arguments[1]);}}("tap_offset failed",function(a,c){h.tapWithOptions(a,c||{})},{timeout:60,frequency:.5});this.target=h;this.uia=g;g.app=m;g.window=r;g.windows=s;g.keyboard=n;
|
7
|
+
g.alert=function(){return m().alert()}})();
|
@@ -0,0 +1,243 @@
|
|
1
|
+
if (typeof JSON !== 'object') {
|
2
|
+
JSON = {};
|
3
|
+
}
|
4
|
+
(function () {
|
5
|
+
'use strict';
|
6
|
+
function f(n) {
|
7
|
+
return n < 10 ? '0' + n : n;
|
8
|
+
}
|
9
|
+
|
10
|
+
if (typeof Date.prototype.toJSON !== 'function') {
|
11
|
+
Date.prototype.toJSON = function (key) {
|
12
|
+
return isFinite(this.valueOf()) ? this.getUTCFullYear() + '-' +
|
13
|
+
f(this.getUTCMonth() + 1) + '-' +
|
14
|
+
f(this.getUTCDate()) + 'T' +
|
15
|
+
f(this.getUTCHours()) + ':' +
|
16
|
+
f(this.getUTCMinutes()) + ':' +
|
17
|
+
f(this.getUTCSeconds()) + 'Z' : null;
|
18
|
+
};
|
19
|
+
String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function (key) {
|
20
|
+
return this.valueOf();
|
21
|
+
};
|
22
|
+
}
|
23
|
+
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, gap, indent, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"': '\\"', '\\': '\\\\'}, rep;
|
24
|
+
|
25
|
+
function quote(string) {
|
26
|
+
escapable.lastIndex = 0;
|
27
|
+
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
|
28
|
+
var c = meta[a];
|
29
|
+
return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
30
|
+
}) + '"' : '"' + string + '"';
|
31
|
+
}
|
32
|
+
|
33
|
+
function str(key, holder) {
|
34
|
+
var i, k, v, length, mind = gap, partial, value = holder[key];
|
35
|
+
if (value && typeof value === 'object' && typeof value.toJSON === 'function') {
|
36
|
+
value = value.toJSON(key);
|
37
|
+
}
|
38
|
+
if (typeof rep === 'function') {
|
39
|
+
value = rep.call(holder, key, value);
|
40
|
+
}
|
41
|
+
switch (typeof value) {
|
42
|
+
case'string':
|
43
|
+
return quote(value);
|
44
|
+
case'number':
|
45
|
+
return isFinite(value) ? String(value) : 'null';
|
46
|
+
case'boolean':
|
47
|
+
case'null':
|
48
|
+
return String(value);
|
49
|
+
case'object':
|
50
|
+
if (!value) {
|
51
|
+
return'null';
|
52
|
+
}
|
53
|
+
gap += indent;
|
54
|
+
partial = [];
|
55
|
+
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
56
|
+
length = value.length;
|
57
|
+
for (i = 0; i < length; i += 1) {
|
58
|
+
partial[i] = str(i, value) || 'null';
|
59
|
+
}
|
60
|
+
v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']';
|
61
|
+
gap = mind;
|
62
|
+
return v;
|
63
|
+
}
|
64
|
+
if (rep && typeof rep === 'object') {
|
65
|
+
length = rep.length;
|
66
|
+
for (i = 0; i < length; i += 1) {
|
67
|
+
if (typeof rep[i] === 'string') {
|
68
|
+
k = rep[i];
|
69
|
+
v = str(k, value);
|
70
|
+
if (v) {
|
71
|
+
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
} else {
|
76
|
+
for (k in value) {
|
77
|
+
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
78
|
+
v = str(k, value);
|
79
|
+
if (v) {
|
80
|
+
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}';
|
86
|
+
gap = mind;
|
87
|
+
return v;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
if (typeof JSON.stringify !== 'function') {
|
92
|
+
JSON.stringify = function (value, replacer, space) {
|
93
|
+
var i;
|
94
|
+
gap = '';
|
95
|
+
indent = '';
|
96
|
+
if (typeof space === 'number') {
|
97
|
+
for (i = 0; i < space; i += 1) {
|
98
|
+
indent += ' ';
|
99
|
+
}
|
100
|
+
} else if (typeof space === 'string') {
|
101
|
+
indent = space;
|
102
|
+
}
|
103
|
+
rep = replacer;
|
104
|
+
if (replacer && typeof replacer !== 'function' && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) {
|
105
|
+
throw new Error('JSON.stringify');
|
106
|
+
}
|
107
|
+
return str('', {'': value});
|
108
|
+
};
|
109
|
+
}
|
110
|
+
if (typeof JSON.parse !== 'function') {
|
111
|
+
JSON.parse = function (text, reviver) {
|
112
|
+
var j;
|
113
|
+
|
114
|
+
function walk(holder, key) {
|
115
|
+
var k, v, value = holder[key];
|
116
|
+
if (value && typeof value === 'object') {
|
117
|
+
for (k in value) {
|
118
|
+
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
119
|
+
v = walk(value, k);
|
120
|
+
if (v !== undefined) {
|
121
|
+
value[k] = v;
|
122
|
+
} else {
|
123
|
+
delete value[k];
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
return reviver.call(holder, key, value);
|
129
|
+
}
|
130
|
+
|
131
|
+
text = String(text);
|
132
|
+
cx.lastIndex = 0;
|
133
|
+
if (cx.test(text)) {
|
134
|
+
text = text.replace(cx, function (a) {
|
135
|
+
return'\\u' +
|
136
|
+
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
137
|
+
});
|
138
|
+
}
|
139
|
+
if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
140
|
+
j = eval('(' + text + ')');
|
141
|
+
return typeof reviver === 'function' ? walk({'': j}, '') : j;
|
142
|
+
}
|
143
|
+
throw new SyntaxError('JSON.parse');
|
144
|
+
};
|
145
|
+
}
|
146
|
+
}());
|
147
|
+
|
148
|
+
|
149
|
+
var Log = (function () {
|
150
|
+
var forceFlush = [],
|
151
|
+
N = 16384,
|
152
|
+
i = N;
|
153
|
+
while (i--) {
|
154
|
+
forceFlush[i] = "*";
|
155
|
+
}
|
156
|
+
forceFlush = forceFlush.join('');
|
157
|
+
|
158
|
+
function log_json(object, flush)
|
159
|
+
{
|
160
|
+
UIALogger.logMessage("OUTPUT_JSON:\n"+JSON.stringify(object)+"\nEND_OUTPUT");
|
161
|
+
if (flush) {
|
162
|
+
UIALogger.logMessage(forceFlush);
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
return {
|
167
|
+
result: function (status, data, flush) {
|
168
|
+
log_json({"status": status, "value": data, "index":_actualIndex}, flush)
|
169
|
+
},
|
170
|
+
output: function (msg, flush) {
|
171
|
+
log_json({"output": msg,"last_index":_actualIndex}, flush);
|
172
|
+
}
|
173
|
+
};
|
174
|
+
})();
|
175
|
+
|
176
|
+
|
177
|
+
function findAlertViewText(alert) {
|
178
|
+
if (!alert) {
|
179
|
+
return false;
|
180
|
+
}
|
181
|
+
var txt = alert.name(),
|
182
|
+
txts;
|
183
|
+
if (txt == null) {
|
184
|
+
txts = alert.staticTexts();
|
185
|
+
if (txts != null && txts.length > 0) {
|
186
|
+
txt = txts[0].name();
|
187
|
+
}
|
188
|
+
}
|
189
|
+
return txt;
|
190
|
+
}
|
191
|
+
|
192
|
+
function isLocationPrompt(alert) {
|
193
|
+
var exps = [
|
194
|
+
["OK", /vil bruge din aktuelle placering/],
|
195
|
+
["OK", /Would Like to Use Your Current Location/],
|
196
|
+
["Ja", /Darf (?:.)+ Ihren aktuellen Ort verwenden/],
|
197
|
+
["OK", /Would Like to Access Your Photos/]
|
198
|
+
],
|
199
|
+
ans, exp,
|
200
|
+
txt;
|
201
|
+
|
202
|
+
txt = findAlertViewText(alert);
|
203
|
+
Log.output({"output":"alert: "+txt}, true);
|
204
|
+
for (var i = 0; i < exps.length; i++) {
|
205
|
+
ans = exps[i][0];
|
206
|
+
exp = exps[i][1];
|
207
|
+
if (exp.test(txt)) {
|
208
|
+
return ans;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
return false;
|
212
|
+
}
|
213
|
+
|
214
|
+
UIATarget.onAlert = function (alert) {
|
215
|
+
Log.output({"output":"on alert"}, true);
|
216
|
+
var target = UIATarget.localTarget();
|
217
|
+
target.pushTimeout(10);
|
218
|
+
function attemptTouchOKOnLocation(retry_count) {
|
219
|
+
retry_count = retry_count || 0;
|
220
|
+
if (retry_count >= 5) {
|
221
|
+
Log.output("Maxed out retry (5) - unable to dismiss location dialog.");
|
222
|
+
return;
|
223
|
+
}
|
224
|
+
try {
|
225
|
+
var answer = isLocationPrompt(alert);
|
226
|
+
if (answer) {
|
227
|
+
alert.buttons()[answer].tap();
|
228
|
+
}
|
229
|
+
}
|
230
|
+
catch (e) {
|
231
|
+
Log.output("Exception while trying to touch alert dialog. Retrying...");
|
232
|
+
if (e && typeof e.toString == 'function') {
|
233
|
+
Log.output(e.toString());
|
234
|
+
}
|
235
|
+
target.delay(1);
|
236
|
+
attemptTouchOKOnLocation(retry_count + 1);
|
237
|
+
}
|
238
|
+
}
|
239
|
+
|
240
|
+
attemptTouchOKOnLocation(0);
|
241
|
+
target.popTimeout();
|
242
|
+
return true;
|
243
|
+
};
|
@@ -247,25 +247,6 @@ UIATarget.onAlert = function (alert) {
|
|
247
247
|
return true;
|
248
248
|
};
|
249
249
|
|
250
|
-
/*
|
251
|
-
(defn sanitize
|
252
|
-
"Removes elements not serializable to preferences"
|
253
|
-
[x]
|
254
|
-
|
255
|
-
(cond
|
256
|
-
(nil? x) ":nil"
|
257
|
-
(string? x) x
|
258
|
-
(keyword? x) (name x)
|
259
|
-
(map? x) (into {}
|
260
|
-
(map (fn [[k v]]
|
261
|
-
[k (sanitize v)])
|
262
|
-
x))
|
263
|
-
(coll? x) (map sanitize x)
|
264
|
-
(instance? js/UIAElement x) (.toString x)
|
265
|
-
:else x))
|
266
|
-
|
267
|
-
*/
|
268
|
-
|
269
250
|
var target = null,
|
270
251
|
failureMessage = null,
|
271
252
|
preferences = null,
|
data/scripts/run_loop_host.js
CHANGED
@@ -167,8 +167,6 @@ var _expectedIndex = 0,//expected index of next command
|
|
167
167
|
_process;//host command process
|
168
168
|
|
169
169
|
var Log = (function () {
|
170
|
-
// According to Appium,
|
171
|
-
//16384 is the buffer size used by instruments
|
172
170
|
var forceFlush = [],
|
173
171
|
N = "$MODE" == "FLUSH" ? 16384 : 0,
|
174
172
|
i = N;
|
@@ -218,13 +216,14 @@ function isLocationPrompt(alert) {
|
|
218
216
|
var exps = [
|
219
217
|
["OK", /vil bruge din aktuelle placering/],
|
220
218
|
["OK", /Would Like to Use Your Current Location/],
|
221
|
-
["Ja", /Darf (?:.)+ Ihren aktuellen Ort verwenden/]
|
219
|
+
["Ja", /Darf (?:.)+ Ihren aktuellen Ort verwenden/],
|
220
|
+
["OK", /Would Like to Access Your Photos/]
|
222
221
|
],
|
223
222
|
ans, exp,
|
224
|
-
txt
|
225
|
-
txts;
|
223
|
+
txt;
|
226
224
|
|
227
225
|
txt = findAlertViewText(alert);
|
226
|
+
Log.output({"output":"alert: "+txt}, true);
|
228
227
|
for (var i = 0; i < exps.length; i++) {
|
229
228
|
ans = exps[i][0];
|
230
229
|
exp = exps[i][1];
|
@@ -236,6 +235,7 @@ function isLocationPrompt(alert) {
|
|
236
235
|
}
|
237
236
|
|
238
237
|
UIATarget.onAlert = function (alert) {
|
238
|
+
Log.output({"output":"on alert"}, true);
|
239
239
|
var target = UIATarget.localTarget();
|
240
240
|
target.pushTimeout(10);
|
241
241
|
function attemptTouchOKOnLocation(retry_count) {
|
@@ -279,14 +279,16 @@ while (true) {
|
|
279
279
|
_process = host.performTaskWithPathArgumentsTimeout("/bin/bash",
|
280
280
|
[blockingReadScriptPath, commandPath],
|
281
281
|
//[commandPath],
|
282
|
-
|
282
|
+
5);
|
283
283
|
|
284
284
|
} catch (e) {
|
285
285
|
Log.output("Timeout on read command...");
|
286
286
|
continue;
|
287
287
|
}
|
288
288
|
if (_process.exitCode != 0) {
|
289
|
-
|
289
|
+
if (_process.exitCode != 15) {
|
290
|
+
Log.output("unable to execute: " + blockingReadScriptPath + " " + commandPath + " exitCode " + _process.exitCode + ". Error: " + _process.stderr + _process.stdout);
|
291
|
+
}
|
290
292
|
}
|
291
293
|
else {
|
292
294
|
_input = _process.stdout;
|
@@ -298,7 +300,6 @@ while (true) {
|
|
298
300
|
_exp = _input.substring(_index + 1, _input.length);
|
299
301
|
Log.output("Execute: "+_exp);
|
300
302
|
_result = eval(_exp);
|
301
|
-
Log.output("res: "+_result);
|
302
303
|
}
|
303
304
|
else {//likely old command is lingering...
|
304
305
|
continue;
|
@@ -315,9 +316,7 @@ while (true) {
|
|
315
316
|
continue;
|
316
317
|
}
|
317
318
|
|
318
|
-
_expectedIndex
|
319
|
-
Log.output("log result: "+_result);
|
319
|
+
_expectedIndex = Math.max(_actualIndex+1, _expectedIndex+1);
|
320
320
|
Log.result("success", _result);
|
321
|
-
|
322
321
|
}
|
323
322
|
}
|
metadata
CHANGED
@@ -1,195 +1,195 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: run_loop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.pre7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Karl Krukow
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.18'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.18'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: json
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.8'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.8'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: retriable
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 1.3.3.1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 1.3.3.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: CFPropertyList
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '2.2'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '2.2'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ~>
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '1.6'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ~>
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '1.6'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: travis
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ~>
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '1.7'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ~>
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '1.7'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rspec
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ~>
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '3.0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ~>
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '3.0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: rake
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ~>
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '10.3'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ~>
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '10.3'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: awesome_print
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- -
|
129
|
+
- - ~>
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '1.2'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - ~>
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '1.2'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: guard-rspec
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- -
|
143
|
+
- - ~>
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '4.3'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- -
|
150
|
+
- - ~>
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '4.3'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: guard-bundler
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- -
|
157
|
+
- - ~>
|
158
158
|
- !ruby/object:Gem::Version
|
159
159
|
version: '2.0'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
|
-
- -
|
164
|
+
- - ~>
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '2.0'
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
168
|
name: growl
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
170
170
|
requirements:
|
171
|
-
- -
|
171
|
+
- - ~>
|
172
172
|
- !ruby/object:Gem::Version
|
173
173
|
version: '1.0'
|
174
174
|
type: :development
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
|
-
- -
|
178
|
+
- - ~>
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '1.0'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: rb-readline
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- -
|
185
|
+
- - ~>
|
186
186
|
- !ruby/object:Gem::Version
|
187
187
|
version: '0.5'
|
188
188
|
type: :development
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
|
-
- -
|
192
|
+
- - ~>
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '0.5'
|
195
195
|
description: calabash-cucumber drives tests for native iOS apps. RunLoop provides
|
@@ -211,12 +211,14 @@ files:
|
|
211
211
|
- lib/run_loop/sim_control.rb
|
212
212
|
- lib/run_loop/version.rb
|
213
213
|
- lib/run_loop/xctools.rb
|
214
|
+
- scripts/calabash-uia-min.js
|
214
215
|
- scripts/calabash.lldb.erb
|
215
216
|
- scripts/calabash_script_uia.js
|
216
217
|
- scripts/json2-min.js
|
217
218
|
- scripts/json2.js
|
218
219
|
- scripts/read-cmd.sh
|
219
220
|
- scripts/run_dismiss_location.js
|
221
|
+
- scripts/run_loop_basic.js
|
220
222
|
- scripts/run_loop_fast_uia.js
|
221
223
|
- scripts/run_loop_host.js
|
222
224
|
- scripts/udidetect
|
@@ -230,12 +232,12 @@ require_paths:
|
|
230
232
|
- lib
|
231
233
|
required_ruby_version: !ruby/object:Gem::Requirement
|
232
234
|
requirements:
|
233
|
-
- -
|
235
|
+
- - '>='
|
234
236
|
- !ruby/object:Gem::Version
|
235
237
|
version: '1.9'
|
236
238
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
239
|
requirements:
|
238
|
-
- -
|
240
|
+
- - '>'
|
239
241
|
- !ruby/object:Gem::Version
|
240
242
|
version: 1.3.1
|
241
243
|
requirements: []
|