flaky 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/flake +1 -4
- data/lib/flaky.rb +5 -2
- data/lib/flaky/appium.rb +32 -68
- data/lib/flaky/cmd.rb +20 -0
- data/lib/flaky/run/two_pass.rb +1 -1
- data/lib/screen_recording.rb +1 -12
- data/lib/trace.rb +48 -0
- data/readme.md +1 -19
- data/release_notes.md +9 -0
- metadata +3 -2
- data/lib/flaky/applescript.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df6cf2366a73e86a75c22f82a20519da80d5caaf
|
4
|
+
data.tar.gz: 8a80ee4a3a491174e8177b66e35645b6defbff24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87923fe2388c06cc5aee655ef04848296595f7d5f9fcf63404353c15623fd87a759179518eb2fedc69150e607dac65bd92f1d833b5c1139b215c75e4b712259f
|
7
|
+
data.tar.gz: e942862e8c9fa4ce05aa116580858f2be63c3a44f68e12a6c4a0ce72fed5538644bfe9bdb6bd7131c95195bbfe7d1d0fe437188833b3135f7a8f05a9d88988bd
|
data/bin/flake
CHANGED
@@ -30,10 +30,7 @@ Flaky.no_video = true if ENV['SAUCE_USERNAME'] && ENV['SAUCE_ACCESS_KEY']
|
|
30
30
|
|
31
31
|
puts "Recording Video: #{!Flaky.no_video}"
|
32
32
|
|
33
|
-
if args && args.length ===
|
34
|
-
Flaky::AppleScript.beat_security_agent
|
35
|
-
exit
|
36
|
-
elsif args && args.length === 3
|
33
|
+
if args && args.length === 3
|
37
34
|
# .to_i will convert any string to 0 so check using a match regex.
|
38
35
|
if args[0].match(/\d+/) && args[1].match(/\d+/)
|
39
36
|
raise 'First pass must be 1' unless args[0].to_i == 1
|
data/lib/flaky.rb
CHANGED
@@ -9,8 +9,11 @@ require 'posix/spawn' # http://rubygems.org/gems/posix-spawn
|
|
9
9
|
require 'digest/md5'
|
10
10
|
require 'toml'
|
11
11
|
|
12
|
+
require_relative 'trace'
|
13
|
+
# Flaky.trace_specs trace: Dir.glob(File.join(__dir__, '**', '*.rb')) # verbose logging
|
14
|
+
|
12
15
|
module Flaky
|
13
|
-
VERSION = '0.1.
|
16
|
+
VERSION = '0.1.3' unless defined? ::Flaky::VERSION
|
14
17
|
DATE = '2015-04-28' unless defined? ::Flaky::DATE
|
15
18
|
|
16
19
|
class << self; attr_accessor :no_video; end
|
@@ -18,7 +21,7 @@ module Flaky
|
|
18
21
|
|
19
22
|
# require internal files
|
20
23
|
require_relative 'flaky/appium'
|
21
|
-
require_relative 'flaky/
|
24
|
+
require_relative 'flaky/cmd'
|
22
25
|
require_relative 'flaky/run'
|
23
26
|
|
24
27
|
require_relative 'flaky/run/all_tests'
|
data/lib/flaky/appium.rb
CHANGED
@@ -1,25 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Flaky
|
3
|
-
|
4
|
-
class Cmd
|
5
|
-
attr_reader :pid, :in, :out, :err
|
6
|
-
|
7
|
-
def initialize cmd
|
8
|
-
# redirect err to child's out
|
9
|
-
@pid, @in, @out, @err = POSIX::Spawn::popen4 cmd, {:err => [:child, :out]}
|
10
|
-
@in.close
|
11
|
-
end
|
12
|
-
|
13
|
-
def stop
|
14
|
-
[@in, @out, @err].each { |io| io.close unless io.nil? || io.closed? }
|
15
|
-
begin
|
16
|
-
Process.kill 'KILL', @pid
|
17
|
-
Process.waitpid @pid
|
18
|
-
rescue # no such process
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
3
|
#noinspection RubyResolve
|
24
4
|
class Appium
|
25
5
|
include POSIX::Spawn
|
@@ -27,50 +7,25 @@ module Flaky
|
|
27
7
|
@@thread = nil
|
28
8
|
|
29
9
|
def self.remove_ios_apps
|
30
|
-
|
31
|
-
raise 'User must be defined' unless user
|
32
|
-
|
33
|
-
# Must kill iPhone simulator or strange install errors will occur.
|
34
|
-
self.kill_all 'iPhone Simulator'
|
35
|
-
|
36
|
-
app_glob = "/Users/#{user}/Library/Application Support/iPhone Simulator/**/Applications"
|
37
|
-
Dir.glob(app_glob) do |ios_app_folder|
|
38
|
-
FileUtils.rm_rf ios_app_folder
|
39
|
-
root = File.dirname ios_app_folder
|
40
|
-
FileUtils.rm_rf File.join(root, 'Library/TCC')
|
41
|
-
FileUtils.rm_rf File.join(root, 'Library/Caches')
|
42
|
-
FileUtils.rm_rf File.join(root, 'Library/Media')
|
43
|
-
end
|
10
|
+
# nop -- this feature has moved into the appium server
|
44
11
|
end
|
45
12
|
|
46
13
|
def self.kill_all process_name
|
47
|
-
|
48
|
-
_pid, _in, _out, _err = POSIX::Spawn::popen4('killall', '-9', process_name)
|
49
|
-
raise "Unable to kill #{process_name}" unless _pid
|
50
|
-
_in.close
|
51
|
-
_out.read
|
52
|
-
_err.read
|
53
|
-
rescue Errno::EAGAIN
|
54
|
-
# POSIX::Spawn::popen4 may raise EAGAIN. If it does, retry after a second.
|
55
|
-
sleep 1
|
56
|
-
retry
|
57
|
-
ensure
|
58
|
-
[_in, _out, _err].each { |io| io.close unless io.nil? || io.closed? }
|
59
|
-
Process::waitpid(_pid) if _pid
|
60
|
-
end
|
14
|
+
POSIX::Spawn::Child.new("killall -9 #{process_name}")
|
61
15
|
end
|
62
16
|
|
63
17
|
# android: true to activate Android mode
|
64
18
|
def initialize opts={}
|
65
|
-
@ready
|
19
|
+
@ready = false
|
66
20
|
@pid, @in, @out, @err = nil
|
67
|
-
@log
|
68
|
-
@buffer
|
69
|
-
@android
|
70
|
-
@ios
|
21
|
+
@log = ''
|
22
|
+
@buffer = ''
|
23
|
+
@android = opts.fetch(:android, false)
|
24
|
+
@ios = !@android
|
71
25
|
end
|
72
26
|
|
73
27
|
def start
|
28
|
+
@ready = false
|
74
29
|
self.stop # stop existing process
|
75
30
|
@log = '/tmp/flaky/appium_tmp_log.txt'
|
76
31
|
File.delete(@log) if File.exists? @log
|
@@ -84,16 +39,17 @@ module Flaky
|
|
84
39
|
end
|
85
40
|
|
86
41
|
begin
|
87
|
-
timeout
|
88
|
-
while
|
42
|
+
timeout 30 do # timeout in seconds
|
43
|
+
while !@ready
|
89
44
|
sleep 0.5
|
90
45
|
end
|
91
46
|
end
|
92
|
-
rescue Timeout::Error
|
47
|
+
rescue Timeout::Error => ex
|
93
48
|
# try again if appium fails to become ready
|
94
49
|
# sometimes the simulator never launches.
|
95
50
|
# the sim crashes or any number of issues.
|
96
|
-
self.start
|
51
|
+
#self.start
|
52
|
+
raise ex
|
97
53
|
end
|
98
54
|
|
99
55
|
# -e = -A = include other user's processes
|
@@ -129,16 +85,23 @@ module Flaky
|
|
129
85
|
raise 'Appium never spawned' if io_array.nil?
|
130
86
|
|
131
87
|
ready_for_reading = io_array[0]
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
88
|
+
stream = ready_for_reading[0]
|
89
|
+
|
90
|
+
begin
|
91
|
+
capture = stream.readpartial 999_999
|
92
|
+
if capture
|
93
|
+
# $stdout.puts "#{capture}" # verbose logging
|
94
|
+
update_buffer(capture)
|
95
|
+
|
96
|
+
# info: Appium REST http interface listener started on 0.0.0.0:4723
|
97
|
+
if capture.include?('Appium REST http interface listener started')
|
98
|
+
# $stdout.puts 'Appium server successfully started' # verbose logging
|
99
|
+
@ready = true
|
100
|
+
end
|
141
101
|
end
|
102
|
+
rescue EOFError
|
103
|
+
out_err.delete stream
|
104
|
+
stream.close
|
142
105
|
end
|
143
106
|
end
|
144
107
|
end
|
@@ -157,19 +120,20 @@ module Flaky
|
|
157
120
|
|
158
121
|
# Invoked inside a thread by `self.go`
|
159
122
|
def launch
|
160
|
-
self.end_all_nodes
|
161
123
|
@ready = false
|
124
|
+
self.end_all_nodes
|
162
125
|
appium_home = ENV['APPIUM_HOME']
|
163
126
|
raise "ENV['APPIUM_HOME'] must be set!" if appium_home.nil? || appium_home.empty?
|
164
127
|
contains_appium = File.exists?(File.join(ENV['APPIUM_HOME'], 'bin', 'appium.js'))
|
165
128
|
raise "Appium home `#{appium_home}` doesn't contain bin/appium.js!" unless contains_appium
|
166
|
-
cmd
|
129
|
+
cmd = %Q(node "#{appium_home}" --log-level debug)
|
167
130
|
@pid, @in, @out, @err = popen4 cmd
|
168
131
|
@in.close
|
169
132
|
self # used to chain `launch.wait`
|
170
133
|
end
|
171
134
|
|
172
135
|
def stop
|
136
|
+
@ready = false
|
173
137
|
# https://github.com/tmm1/pygments.rb/blob/master/lib/pygments/popen.rb
|
174
138
|
begin
|
175
139
|
Process.kill 'KILL', @pid
|
data/lib/flaky/cmd.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Flaky
|
2
|
+
class Cmd
|
3
|
+
attr_reader :pid, :in, :out, :err
|
4
|
+
|
5
|
+
def initialize cmd
|
6
|
+
# redirect err to child's out
|
7
|
+
@pid, @in, @out, @err = POSIX::Spawn::popen4 cmd, { :err => [:child, :out] }
|
8
|
+
@in.close
|
9
|
+
end
|
10
|
+
|
11
|
+
def stop
|
12
|
+
[@in, @out, @err].each { |io| io.close unless io.nil? || io.closed? }
|
13
|
+
begin
|
14
|
+
Process.kill 'KILL', @pid
|
15
|
+
Process.waitpid @pid
|
16
|
+
rescue # no such process
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/flaky/run/two_pass.rb
CHANGED
@@ -51,7 +51,7 @@ module Flaky
|
|
51
51
|
|
52
52
|
result_dir_postfix = '2' # /tmp/flaky/1
|
53
53
|
flaky = Flaky::Run.new(result_dir_postfix)
|
54
|
-
appium = Appium.new unless running_on_sauce
|
54
|
+
appium = Appium.new(android: is_android) unless running_on_sauce
|
55
55
|
|
56
56
|
fails.split("\n").each do |test_file|
|
57
57
|
file = test_file
|
data/lib/screen_recording.rb
CHANGED
@@ -10,18 +10,7 @@ module Flaky
|
|
10
10
|
# app_name for example MyApp.app
|
11
11
|
#
|
12
12
|
def capture_ios_app_log app_name
|
13
|
-
|
14
|
-
app_glob = "/Users/#{ENV['USER']}/Library/Application Support/iPhone Simulator/7.0.3/Applications/*/#{app_name}"
|
15
|
-
app_folder = File.dirname Dir.glob(app_glob).first
|
16
|
-
|
17
|
-
tmp_log_folder = '/tmp/flaky_tmp_log_folder'
|
18
|
-
FileUtils.rm_rf tmp_log_folder if File.exists? tmp_log_folder
|
19
|
-
FileUtils.mkdir_p tmp_log_folder
|
20
|
-
|
21
|
-
log_glob = File.join app_folder, 'Library/Caches/Logs/*'
|
22
|
-
Dir.glob(log_glob).each { |log| FileUtils.cp log, tmp_log_folder }
|
23
|
-
rescue # folder may not exist. or there could be no longs
|
24
|
-
end
|
13
|
+
# nop -- this feature has moved into the appium server
|
25
14
|
end
|
26
15
|
|
27
16
|
def screen_recording_binary
|
data/lib/trace.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
module Flaky
|
3
|
+
##
|
4
|
+
# Trace file source to :io (default $stdout)
|
5
|
+
#
|
6
|
+
# spec_opts = {}
|
7
|
+
#
|
8
|
+
# @param :trace [Array<String>] the files to trace
|
9
|
+
# @param :io [IO] io to print to
|
10
|
+
def self.trace_specs spec_opts
|
11
|
+
targets = []
|
12
|
+
files = {}
|
13
|
+
last_file = ''
|
14
|
+
last_line = -1
|
15
|
+
|
16
|
+
files_to_trace = spec_opts.fetch(:trace, []);
|
17
|
+
io = spec_opts.fetch(:io, $stdout)
|
18
|
+
color = spec_opts.fetch(:color, "\e[32m") # ANSI.green default
|
19
|
+
# target only existing readable files
|
20
|
+
files_to_trace.each do |f|
|
21
|
+
if File.exists?(f) && File.readable?(f)
|
22
|
+
targets.push File.expand_path f
|
23
|
+
targets.push File.basename f # sometimes the file is relative
|
24
|
+
end
|
25
|
+
end
|
26
|
+
return if targets.empty?
|
27
|
+
|
28
|
+
set_trace_func(lambda do |event, file, line, id, binding, classname|
|
29
|
+
return unless targets.include?(file)
|
30
|
+
|
31
|
+
# never repeat a line
|
32
|
+
return if file == last_file && line == last_line
|
33
|
+
|
34
|
+
file_sym = file.intern
|
35
|
+
files[file_sym] = IO.readlines(file) if files[file_sym].nil?
|
36
|
+
lines = files[file_sym]
|
37
|
+
|
38
|
+
# arrays are 0 indexed and line numbers start at one.
|
39
|
+
io.print color if color # ANSI code
|
40
|
+
io.puts lines[line - 1]
|
41
|
+
io.print "\e[0m" if color # ANSI.clear
|
42
|
+
|
43
|
+
last_file = file
|
44
|
+
last_line = line
|
45
|
+
|
46
|
+
end)
|
47
|
+
end
|
48
|
+
end
|
data/readme.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#### flaky [![Gem Version](https://badge.fury.io/rb/flaky.
|
1
|
+
#### flaky [![Gem Version](https://badge.fury.io/rb/flaky.svg)](http://rubygems.org/gems/flaky) [![Dependency Status](https://gemnasium.com/appium/flaky.svg)](https://gemnasium.com/appium/flaky)
|
2
2
|
|
3
3
|
Run Appium iOS/Android tests on OS X to measure flakiness.
|
4
4
|
|
@@ -20,23 +20,6 @@ This only works with:
|
|
20
20
|
- iOS iPhone Simulator 6.1 +
|
21
21
|
- Unique test file names per platform
|
22
22
|
|
23
|
-
#### Security dialogs
|
24
|
-
|
25
|
-
Instruments prompts for security authorization when testing on iOS.
|
26
|
-
Set the following environment variables in `~/.bash_profile`.
|
27
|
-
If you don't know your username, type `whoami` in the Terminal and use that value.
|
28
|
-
|
29
|
-
```
|
30
|
-
export FLAKY_USER="username"
|
31
|
-
export FLAKY_PASSWORD="password"
|
32
|
-
```
|
33
|
-
|
34
|
-
Ensure that Terminal has been granted permission to control the computer. This is set in Security & Privacy -> Accessibility.
|
35
|
-
|
36
|
-
![](doc/accessibility_terminal.jpg)
|
37
|
-
|
38
|
-
Run `flake auth` to automatically dismiss security dialogs.
|
39
|
-
|
40
23
|
--
|
41
24
|
|
42
25
|
#### For each test:
|
@@ -72,4 +55,3 @@ Run `flake auth` to automatically dismiss security dialogs.
|
|
72
55
|
end
|
73
56
|
end
|
74
57
|
```
|
75
|
-
|
data/release_notes.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
#### v0.1.2 2015-04-28
|
2
|
+
|
3
|
+
- [8df75d3](https://github.com/appium/flaky/commit/8df75d344c5f963985637c3128bf1173cb34877f) Release 0.1.2
|
4
|
+
- [bc3375e](https://github.com/appium/flaky/commit/bc3375e4a8f68d632e09df981590eeeb9532c43f) Update adb test
|
5
|
+
- [0c18668](https://github.com/appium/flaky/commit/0c18668ae7c3f394fe4b8544a2b1cbca22904407) Add adb test
|
6
|
+
- [171333c](https://github.com/appium/flaky/commit/171333c172d26a3ef2da0165170894a66170cff2) Capture debug logs from appium server
|
7
|
+
- [7177da4](https://github.com/appium/flaky/commit/7177da4e14f711710bfec1d53e260dabcd92e3d0) Add flaky.txt support to run/one_test.rb
|
8
|
+
|
9
|
+
|
1
10
|
#### v0.1.1 2014-05-19
|
2
11
|
|
3
12
|
- [98f3c87](https://github.com/appium/flaky/commit/98f3c87c1caa7c64b1d1da26f43642f4bdef04d1) Release 0.1.1
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flaky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- code@bootstraponline.com
|
@@ -83,7 +83,7 @@ files:
|
|
83
83
|
- lib/BeatSecurityAgent.applescript
|
84
84
|
- lib/flaky.rb
|
85
85
|
- lib/flaky/appium.rb
|
86
|
-
- lib/flaky/
|
86
|
+
- lib/flaky/cmd.rb
|
87
87
|
- lib/flaky/run.rb
|
88
88
|
- lib/flaky/run/all_tests.rb
|
89
89
|
- lib/flaky/run/from_file.rb
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- lib/flaky/run/two_pass.rb
|
92
92
|
- lib/screen-recording
|
93
93
|
- lib/screen_recording.rb
|
94
|
+
- lib/trace.rb
|
94
95
|
- readme.md
|
95
96
|
- release_notes.md
|
96
97
|
- test/adb.rb
|
data/lib/flaky/applescript.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
module Flaky
|
3
|
-
class AppleScript
|
4
|
-
def self.beat_security_agent
|
5
|
-
flaky_password = ENV['FLAKY_PASSWORD']
|
6
|
-
raise 'FLAKY_PASSWORD must be defined' if flaky_password.nil? || flaky_password.empty?
|
7
|
-
flaky_user = ENV['FLAKY_USER']
|
8
|
-
raise 'FLAKY_USER must be defined' if flaky_user.nil? || flaky_user.empty?
|
9
|
-
|
10
|
-
script = File.expand_path('../../BeatSecurityAgent.applescript', __FILE__)
|
11
|
-
osascript = 'osascript'
|
12
|
-
Appium.kill_all osascript
|
13
|
-
Process::waitpid(POSIX::Spawn::spawn("/usr/bin/#{osascript} #{script} #{flaky_user} #{flaky_password}"))
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|