flaky 0.1.2 → 0.1.3
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/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 [](http://rubygems.org/gems/flaky) [](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
|
-

|
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
|