watchdoge 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: dc87007d94c7fcac5e1eafccc71c3aae806adf2b3e7448a1f65e126bb10e049b
4
+ data.tar.gz: 1e194cbde4a75ecd82f365bff1be0e736c07b92e5555491e32ab20bda7a1412a
5
+ SHA512:
6
+ metadata.gz: e27a802f2ea1a8b79d7ddf9638f3af28bacc90cbdf9a060d48e42c646ff334aae9431e0b898ef6c23d8311db2af06826edff0b321f393f3d652f8d4927cd639a
7
+ data.tar.gz: 50bd1bc2d8c3e21deb6e8bb112d2c1f68f3d518017d55be020617fd938dae623a41b99b89f46f0a55cec83e24b7d40783303a50d5a2cd71b155ecbde718c26aa
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .doge_cookie/
2
+ .webdrivers/
3
+ lib/test.rb
@@ -0,0 +1,28 @@
1
+ require 'watir'
2
+
3
+ module WatchDoge
4
+ class Configuration
5
+ attr_accessor :base_dir
6
+ attr_accessor :web_drivers_dir
7
+ attr_accessor :engine
8
+ attr_accessor :cookie_pool
9
+ attr_accessor :notifications
10
+
11
+ def initialize
12
+ @base_dir = File.expand_path(File.dirname(__FILE__) + '/..')
13
+
14
+ @web_drivers_dir = @base_dir + "/.webdrivers"
15
+
16
+ # cuurently using local fs, probably support NoSQL also maybe?
17
+ @cookie_pool = @base_dir + '/.doge_cookie'
18
+
19
+ @engine = Watir::Browser
20
+
21
+ @notifications = {
22
+ # slack: {
23
+ # incoming_url: SLACK_WEBHOOK
24
+ # }
25
+ }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ require 'yaml'
2
+ require 'digest'
3
+
4
+ module WatchDoge
5
+ module CookiePool
6
+ class << self
7
+ def source uuid, uri = nil
8
+ suffix = "_#{Digest::MD5.hexdigest(uri.to_s)[0..5]}" if uri
9
+
10
+ "#{WatchDoge.configuration.cookie_pool}/#{uuid}#{suffix}"
11
+ end
12
+
13
+ # TODO: implement these two methods return Cookie object in future.
14
+ # def save uuid, json
15
+ # File.write source(uuid), json
16
+ # end
17
+
18
+ # def load uuid
19
+ # return "" unless File.exist? source(uuid)
20
+
21
+ # JSON.parse File.read(source(uuid))
22
+ # end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ module WatchDoge
2
+ module ImageDiff
3
+ OPACITY = 0.6
4
+ HIGHLIGHT_COLOR = "#F163FF#{(OPACITY * 256).to_i.to_s(16).upcase}"
5
+
6
+ class << self
7
+ def diff input_image, golden_image
8
+ return nil if input_image.pixels.hash == golden_image.pixels.hash
9
+
10
+ input_image.height.times do |y|
11
+ pixels = input_image.row(y)
12
+
13
+ if y >= golden_image.height
14
+ pixels.each_with_index do |pixel, x|
15
+ input_image.compose_pixel(x, y, HIGHLIGHT_COLOR)
16
+ end
17
+ else
18
+ golden_pixels = golden_image.row(y)
19
+
20
+ next if (pixels.hash == golden_pixels.hash)
21
+
22
+ pixels.each_with_index do |pixel, x|
23
+ input_image.compose_pixel(x, y, HIGHLIGHT_COLOR) if pixels[x] != golden_pixels[x]
24
+ end
25
+ end
26
+ end
27
+
28
+ input_image
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ require 'net_http_ssl_fix'
2
+ require 'webdrivers'
3
+
4
+ module WatchDoge
5
+ class << self
6
+ def install
7
+ Webdrivers.install_dir = configuration.web_drivers_dir
8
+
9
+ # TODO: Support other browser maybe?
10
+ Webdrivers::Geckodriver.update
11
+
12
+ Dir.mkdir configuration.cookie_pool unless File.directory? configuration.cookie_pool
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,40 @@
1
+ require 'chunky_png'
2
+ require 'json'
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ module WatchDoge
7
+ module Notification
8
+ class Slack
9
+ def initialize opt
10
+ @incoming_url = opt[:incoming_url]
11
+ end
12
+
13
+ def push message
14
+ body = _slack_body(message).to_json
15
+ Net::HTTP.post URI(@incoming_url),
16
+ body,
17
+ "Content-Type" => "application/json"
18
+ end
19
+
20
+ private
21
+
22
+ def _slack_body message
23
+ case message
24
+ when String
25
+ {
26
+ text: message
27
+ }
28
+ when ChunkyPNG::Image
29
+ data = ['data:image/png;base64,', message.to_blob].pack('A*m').gsub(/\n/, '')
30
+
31
+ {
32
+ attachments: [{
33
+ image_url: data
34
+ }]
35
+ }
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,28 @@
1
+ module WatchDoge
2
+ module Notification
3
+ Dir["#{File.expand_path File.dirname(__FILE__)}/notification/*.rb"].each {|file| require file }
4
+
5
+ class << self
6
+ def push message
7
+ sources = WatchDoge.configuration.notifications
8
+
9
+ raise "can't find notification sources in configuration" if sources.empty?
10
+
11
+ sources.each do |source_sym, source_args|
12
+ source_class = get_source_class source_sym
13
+ source = source_class.new source_args
14
+ source.push message
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def get_source_class source_sym
21
+ case source_sym
22
+ when :slack
23
+ WatchDoge::Notification::Slack
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module WatchDoge
2
+ Version = '0.0.1'
3
+ end
@@ -0,0 +1,118 @@
1
+ module WatchDoge
2
+ module PDFUtil
3
+ def pdf_screenshot
4
+ # no such thing as on_loaded for gecko pdf-viewer
5
+ sleep 3
6
+
7
+ firefox_pdf_viewer_id = 'viewer'
8
+ firefox_scaler_id = 'scaleSelect'
9
+ scale_factor = '0.75'
10
+
11
+ #resize to 75%
12
+ @core.select({id: firefox_scaler_id}).select(scale_factor)
13
+
14
+ fullpage_screenshot({id: firefox_pdf_viewer_id})
15
+ end
16
+ end
17
+
18
+ class Worker
19
+ include WatchDoge::PDFUtil
20
+
21
+ def initialize uuid, opt={}
22
+ _before_initialize
23
+
24
+ @uuid = uuid
25
+
26
+ default_opt = {
27
+ width: 1024,
28
+ height: 768,
29
+ headless: true
30
+ }.merge(opt)
31
+
32
+ @core = WatchDoge.configuration.engine.new :firefox, default_opt
33
+
34
+ # for generate uri hash
35
+ @landed_page = nil
36
+
37
+ # flag that cookie is loaded
38
+ @cookie_loaded = false
39
+
40
+ @width = default_opt[:width]
41
+ @height = default_opt[:height]
42
+
43
+ # initilize width/height
44
+ @core.window.resize_to @width, @height
45
+
46
+ _after_initialize
47
+ end
48
+
49
+ def fullpage_screenshot **kwargs
50
+ _resize_by_document(kwargs) do
51
+ return @core.screenshot
52
+ end
53
+ end
54
+
55
+ def close
56
+ _save_cookie
57
+ @core.close
58
+ end
59
+
60
+ def goto uri
61
+ @core.goto uri
62
+
63
+ @landed_page = uri
64
+
65
+ _load_cookie unless _cookie_loaded?
66
+
67
+ @core.refresh
68
+ end
69
+
70
+ # for dev only
71
+ def core
72
+ @core
73
+ end
74
+
75
+ private
76
+ # callbacks before/after init
77
+ def _before_initialize
78
+ Selenium::WebDriver::Firefox::Service.driver_path = WatchDoge.configuration.web_drivers_dir + "/geckodriver"
79
+ end
80
+ def _after_initialize
81
+ end
82
+
83
+ # for cookie load/save
84
+ def _cookie_loaded?
85
+ @cookie_loaded
86
+ end
87
+ def _save_cookie
88
+ @core.cookies.save WatchDoge::CookiePool.source(@uuid, @landed_page)
89
+ end
90
+ def _load_cookie
91
+ source = WatchDoge::CookiePool.source(@uuid, @landed_page)
92
+ return unless File.exist? source
93
+
94
+ @core.cookies.load source
95
+ @cookie_loaded = true
96
+ end
97
+
98
+ def _resize_by_document **kwargs
99
+ target =
100
+ if kwargs.empty?
101
+ @core.body
102
+ else
103
+ @core.element(**kwargs)
104
+ end
105
+
106
+ @core.window.resize_to [target.width, 5000].min, [target.height, 20000].min
107
+ yield
108
+ @core.window.resize_to @width, @height
109
+ end
110
+
111
+ # try delegate all methods to @core
112
+ def method_missing(method_name, *args)
113
+ result = @core.__send__(method_name, *args)
114
+
115
+ result
116
+ end
117
+ end
118
+ end
data/lib/watchdoge.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'pry'
2
+ require 'watchdoge/install'
3
+ require 'watchdoge/version'
4
+ require 'watchdoge/configuration'
5
+ require 'watchdoge/cookie_pool'
6
+ require 'watchdoge/worker'
7
+ require 'watchdoge/notification'
8
+ require 'watchdoge/image_diff'
9
+
10
+ module WatchDoge
11
+ class << self
12
+ def base_dir
13
+ configuration.base_dir
14
+ end
15
+
16
+ def configure(&block)
17
+ yield(configuration)
18
+ configuration
19
+ end
20
+
21
+ def configuration
22
+ @_configuration ||= Configuration.new
23
+ end
24
+ end
25
+ end
data/watchdoge.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'watchdoge'
3
+ s.version = '0.0.1'
4
+ s.date = '2019-07-22'
5
+ s.summary = "dogi"
6
+ s.description = "A collection of web test tools"
7
+ s.authors = ["Shen Lee"]
8
+ s.email = 'no-reply@gmail.com'
9
+ s.files = ["lib/watchdoge.rb"]
10
+ s.license = 'MIT'
11
+
12
+ s.files = `git ls-files`.split($/)
13
+ s.require_paths = ["lib"]
14
+
15
+ s.add_dependency "chunky_png", "~> 1.3", "> 1.3.10"
16
+ s.add_dependency "net_http_ssl_fix", "~> 0.0.10"
17
+ s.add_dependency "webdrivers", "~> 4.1", "> 4.1.0"
18
+ s.add_dependency "watir", "~> 6.16", "> 6.16.0"
19
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: watchdoge
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Shen Lee
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-07-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: chunky_png
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ - - ">"
21
+ - !ruby/object:Gem::Version
22
+ version: 1.3.10
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - - ">"
31
+ - !ruby/object:Gem::Version
32
+ version: 1.3.10
33
+ - !ruby/object:Gem::Dependency
34
+ name: net_http_ssl_fix
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 0.0.10
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.0.10
47
+ - !ruby/object:Gem::Dependency
48
+ name: webdrivers
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">"
52
+ - !ruby/object:Gem::Version
53
+ version: 4.1.0
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '4.1'
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">"
62
+ - !ruby/object:Gem::Version
63
+ version: 4.1.0
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '4.1'
67
+ - !ruby/object:Gem::Dependency
68
+ name: watir
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">"
72
+ - !ruby/object:Gem::Version
73
+ version: 6.16.0
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '6.16'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">"
82
+ - !ruby/object:Gem::Version
83
+ version: 6.16.0
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '6.16'
87
+ description: A collection of web test tools
88
+ email: no-reply@gmail.com
89
+ executables: []
90
+ extensions: []
91
+ extra_rdoc_files: []
92
+ files:
93
+ - ".gitignore"
94
+ - lib/watchdoge.rb
95
+ - lib/watchdoge/configuration.rb
96
+ - lib/watchdoge/cookie_pool.rb
97
+ - lib/watchdoge/image_diff.rb
98
+ - lib/watchdoge/install.rb
99
+ - lib/watchdoge/notification.rb
100
+ - lib/watchdoge/notification/slack.rb
101
+ - lib/watchdoge/version.rb
102
+ - lib/watchdoge/worker.rb
103
+ - watchdoge.gemspec
104
+ homepage:
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubygems_version: 3.0.3
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: dogi
127
+ test_files: []