wraith 3.1.0 → 3.1.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 +4 -4
- data/lib/wraith/cli.rb +6 -5
- data/lib/wraith/crop.rb +17 -11
- data/lib/wraith/folder.rb +7 -1
- data/lib/wraith/gallery.rb +7 -9
- data/lib/wraith/helpers/capture_options.rb +6 -6
- data/lib/wraith/helpers/logger.rb +4 -4
- data/lib/wraith/helpers/utilities.rb +5 -2
- data/lib/wraith/save_images.rb +10 -11
- data/lib/wraith/spider.rb +17 -18
- data/lib/wraith/validate.rb +22 -25
- data/lib/wraith/version.rb +1 -1
- data/lib/wraith/wraith.rb +21 -15
- data/spec/before_capture_spec.rb +19 -19
- data/spec/config_spec.rb +11 -11
- data/spec/construct_command_spec.rb +5 -5
- data/spec/gallery_spec.rb +9 -15
- data/spec/helper_spec.rb +31 -0
- data/spec/resize_reload_spec.rb +1 -1
- data/spec/save_images_spec.rb +1 -1
- data/spec/validate_spec.rb +14 -14
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cfd12ddc2a452f6dffc57109d8941fee8d6e3f3
|
4
|
+
data.tar.gz: 6ea9037c3abd03977b8602bdbb8e34da62781a17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbd574be34e7d10ffebb118b1df7cee44f93031166afa35363e63996475ac2220c5ab651ef4c224b308ca3c18f2c49002bb2a8737b36da03324ff92f26986c8b
|
7
|
+
data.tar.gz: e18eda8062445c426268d3715e119f5e5f299b69ed8b220ba94266c6a6f56cbfa500fac358b09de2d7220fbcdbb5fdb7afc600c1f4914627fbb78d08abb73774
|
data/lib/wraith/cli.rb
CHANGED
@@ -45,7 +45,7 @@ class Wraith::CLI < Thor
|
|
45
45
|
desc "validate", "checks your configuration and validates that all required properties exist"
|
46
46
|
def validate(config_name)
|
47
47
|
within_acceptable_limits do
|
48
|
-
|
48
|
+
logger.info Wraith::Validate.new(config_name).validate
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -93,6 +93,7 @@ class Wraith::CLI < Thor
|
|
93
93
|
desc "crop_images [config_name]", "crops images to the same height"
|
94
94
|
def crop_images(config_name)
|
95
95
|
within_acceptable_limits do
|
96
|
+
logger.info "CROPPING IMAGES"
|
96
97
|
crop = Wraith::CropImages.new(config_name)
|
97
98
|
crop.crop_images
|
98
99
|
end
|
@@ -128,7 +129,7 @@ class Wraith::CLI < Thor
|
|
128
129
|
desc "capture [config_name]", "Capture paths against two domains, compare them, generate gallery"
|
129
130
|
def capture(config, multi = false)
|
130
131
|
within_acceptable_limits do
|
131
|
-
logger.info Wraith::Validate.new(config).validate(
|
132
|
+
logger.info Wraith::Validate.new(config).validate("capture")
|
132
133
|
reset_shots(config)
|
133
134
|
check_for_paths(config)
|
134
135
|
setup_folders(config)
|
@@ -153,7 +154,7 @@ class Wraith::CLI < Thor
|
|
153
154
|
desc "history [config_name]", "Setup a baseline set of shots"
|
154
155
|
def history(config)
|
155
156
|
within_acceptable_limits do
|
156
|
-
logger.info Wraith::Validate.new(config).validate(
|
157
|
+
logger.info Wraith::Validate.new(config).validate("history")
|
157
158
|
reset_shots(config)
|
158
159
|
check_for_paths(config)
|
159
160
|
setup_folders(config)
|
@@ -165,7 +166,7 @@ class Wraith::CLI < Thor
|
|
165
166
|
desc "latest [config_name]", "Capture new shots to compare with baseline"
|
166
167
|
def latest(config)
|
167
168
|
within_acceptable_limits do
|
168
|
-
logger.info Wraith::Validate.new(config).validate(
|
169
|
+
logger.info Wraith::Validate.new(config).validate("latest")
|
169
170
|
reset_shots(config)
|
170
171
|
save_images(config, true)
|
171
172
|
copy_base_images(config)
|
@@ -175,4 +176,4 @@ class Wraith::CLI < Thor
|
|
175
176
|
generate_gallery(config)
|
176
177
|
end
|
177
178
|
end
|
178
|
-
end
|
179
|
+
end
|
data/lib/wraith/crop.rb
CHANGED
@@ -16,25 +16,31 @@ class Wraith::CropImages
|
|
16
16
|
files = Dir.glob("#{wraith.directory}/*/*.png").sort
|
17
17
|
|
18
18
|
Parallel.each(files.each_slice(2), :in_processes => Parallel.processor_count) do |base, compare|
|
19
|
-
|
19
|
+
crop_if_necessary base, compare
|
20
|
+
end
|
21
|
+
end
|
20
22
|
|
21
|
-
|
23
|
+
def crop_if_necessary(base, compare)
|
24
|
+
base_width = image_dimensions(base)[0]
|
22
25
|
base_height = image_dimensions(base)[1]
|
26
|
+
compare_width = image_dimensions(compare)[0]
|
23
27
|
compare_height = image_dimensions(compare)[1]
|
24
28
|
|
25
|
-
if base_height
|
26
|
-
|
27
|
-
|
28
|
-
else
|
29
|
-
image_to_crop = base
|
30
|
-
height_to_crop_to = compare_height
|
29
|
+
if base_height == compare_height and base_width == compare_width
|
30
|
+
logger.debug "Both images are exactly #{base_width}x#{base_height} - no cropping required. (#{base}, #{compare})"
|
31
|
+
return true
|
31
32
|
end
|
32
33
|
|
33
|
-
|
34
|
-
|
34
|
+
max_width = [base_width, compare_width].max
|
35
|
+
max_height = [base_height, compare_height].max
|
36
|
+
|
37
|
+
logger.debug "Cropping both images to #{max_width}x#{max_height}. (#{base}, #{compare})"
|
38
|
+
[base, compare].each do |image_to_crop|
|
39
|
+
run_crop_task(image_to_crop, max_height, max_width)
|
40
|
+
end
|
35
41
|
end
|
36
42
|
|
37
|
-
def
|
43
|
+
def run_crop_task(crop, height, width)
|
38
44
|
`convert #{crop.shellescape} -background none -extent #{width}x#{height} #{crop.shellescape}`
|
39
45
|
end
|
40
46
|
|
data/lib/wraith/folder.rb
CHANGED
@@ -37,9 +37,15 @@ class Wraith::FolderManager
|
|
37
37
|
|
38
38
|
def copy_old_shots
|
39
39
|
if history_dir.nil?
|
40
|
-
logger.error
|
40
|
+
logger.error "no `history_dir` attribute found in config. Cannot copy files."
|
41
41
|
else
|
42
42
|
FileUtils.cp_r("#{dir}/.", "#{history_dir}/")
|
43
|
+
FileUtils.rm_rf("#{history_dir}/thumbnails") # thumbnails aren't generated until the gallery stage anyway
|
44
|
+
FileUtils.rm_rf("#{dir}") # get rid of the live folder
|
45
|
+
Dir["#{history_dir}/**/*.png"].each do |filepath|
|
46
|
+
new_name = filepath.gsub("latest.png", "base.png")
|
47
|
+
File.rename(filepath, new_name)
|
48
|
+
end
|
43
49
|
end
|
44
50
|
end
|
45
51
|
|
data/lib/wraith/gallery.rb
CHANGED
@@ -52,9 +52,7 @@ class Wraith::GalleryGenerator
|
|
52
52
|
@thumbnail = "thumbnails/#{category}/#{filename}"
|
53
53
|
@url = figure_out_url @group, category
|
54
54
|
|
55
|
-
if @dirs[category][@size].nil?
|
56
|
-
@dirs[category][@size] = { :variants => [] }
|
57
|
-
end
|
55
|
+
@dirs[category][@size] = { :variants => [] } if @dirs[category][@size].nil?
|
58
56
|
|
59
57
|
size_dict = @dirs[category][@size]
|
60
58
|
|
@@ -63,20 +61,20 @@ class Wraith::GalleryGenerator
|
|
63
61
|
|
64
62
|
def figure_out_url(group, category)
|
65
63
|
root = wraith.domains["#{group}"]
|
66
|
-
return
|
64
|
+
return "" if root.nil?
|
67
65
|
path = get_path(category)
|
68
66
|
url = root + path
|
69
67
|
url
|
70
68
|
end
|
71
69
|
|
72
70
|
def get_path(category)
|
73
|
-
wraith.paths[category][
|
71
|
+
wraith.paths[category]["path"] || wraith.paths[category]
|
74
72
|
end
|
75
73
|
|
76
74
|
def get_group_from_match(match)
|
77
75
|
group = match[2]
|
78
|
-
dash = match[2].rindex(
|
79
|
-
group = match[2][dash+1..-1] unless dash.nil?
|
76
|
+
dash = match[2].rindex("-")
|
77
|
+
group = match[2][dash + 1..-1] unless dash.nil?
|
80
78
|
group
|
81
79
|
end
|
82
80
|
|
@@ -159,7 +157,7 @@ class Wraith::GalleryGenerator
|
|
159
157
|
|
160
158
|
@dirs.each do |dir, sizes|
|
161
159
|
sizes.to_a.sort.each do |size, files|
|
162
|
-
file = dir.gsub(
|
160
|
+
file = dir.gsub("__", "/")
|
163
161
|
if !files.include?(:diff)
|
164
162
|
logger.warn "\t Unable to create a diff image for #{file}"
|
165
163
|
elsif files[:data] > wraith.threshold
|
@@ -176,7 +174,7 @@ class Wraith::GalleryGenerator
|
|
176
174
|
|
177
175
|
def prompt_user_to_open_gallery(dest)
|
178
176
|
logger.info "\nView the gallery in your browser:"
|
179
|
-
logger.info "\t file://" + Dir.pwd +
|
177
|
+
logger.info "\t file://" + Dir.pwd + "/" + dest
|
180
178
|
end
|
181
179
|
|
182
180
|
class ErbBinding < OpenStruct
|
@@ -10,7 +10,7 @@ class CaptureOptions
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def path
|
13
|
-
|
13
|
+
casper?(options)
|
14
14
|
end
|
15
15
|
|
16
16
|
def selector
|
@@ -19,15 +19,15 @@ class CaptureOptions
|
|
19
19
|
|
20
20
|
def resize
|
21
21
|
# path level, or YAML-file level `resize_or_reload` property value
|
22
|
-
if
|
23
|
-
(
|
22
|
+
if options["resize_or_reload"]
|
23
|
+
(options["resize_or_reload"] == "resize")
|
24
24
|
else
|
25
|
-
|
25
|
+
wraith.resize
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
def before_capture
|
30
|
-
|
30
|
+
options["before_capture"] ? convert_to_absolute(options["before_capture"]) : false
|
31
31
|
end
|
32
32
|
|
33
33
|
def base_url
|
@@ -46,7 +46,7 @@ class CaptureOptions
|
|
46
46
|
wraith.comp_domain + path unless wraith.comp_domain.nil?
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
49
|
+
def casper?(options)
|
50
50
|
options["path"] ? options["path"] : options
|
51
51
|
end
|
52
52
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Logging Module, credit: http://stackoverflow.com/a/6768164
|
2
|
-
require
|
2
|
+
require "logger"
|
3
3
|
|
4
4
|
module Logging
|
5
5
|
# This is the magical bit that gets mixed into your classes
|
@@ -11,10 +11,10 @@ module Logging
|
|
11
11
|
def self.logger
|
12
12
|
unless @logger
|
13
13
|
@logger = Logger.new(STDOUT)
|
14
|
-
@logger.formatter = proc do |severity,
|
15
|
-
(severity ==
|
14
|
+
@logger.formatter = proc do |severity, _datetime, _progname, msg|
|
15
|
+
(severity == "INFO") ? "#{msg}\n" : "#{severity}: #{msg}\n"
|
16
16
|
end
|
17
17
|
end
|
18
18
|
@logger
|
19
19
|
end
|
20
|
-
end
|
20
|
+
end
|
@@ -2,10 +2,13 @@ require "wraith/helpers/custom_exceptions"
|
|
2
2
|
|
3
3
|
def convert_to_absolute(filepath)
|
4
4
|
if !filepath
|
5
|
-
|
6
|
-
elsif filepath[0] ==
|
5
|
+
"false"
|
6
|
+
elsif filepath[0] == "/"
|
7
7
|
# filepath is already absolute. return unchanged
|
8
8
|
filepath
|
9
|
+
elsif filepath.match(/^[A-Z]:\/(.+)$/)
|
10
|
+
# filepath is an absolute Windows path, e.g. C:/Code/Wraith/javascript/global.js. return unchanged
|
11
|
+
filepath
|
9
12
|
else
|
10
13
|
# filepath is relative. it must be converted to absolute
|
11
14
|
"#{Dir.pwd}/#{filepath}"
|
data/lib/wraith/save_images.rb
CHANGED
@@ -36,10 +36,10 @@ class Wraith::SaveImages
|
|
36
36
|
settings = CaptureOptions.new(options, wraith)
|
37
37
|
|
38
38
|
if settings.resize
|
39
|
-
jobs
|
39
|
+
jobs += define_individual_job(label, settings, wraith.widths)
|
40
40
|
else
|
41
41
|
wraith.widths.each do |width|
|
42
|
-
jobs
|
42
|
+
jobs += define_individual_job(label, settings, width)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
@@ -59,7 +59,7 @@ class Wraith::SaveImages
|
|
59
59
|
|
60
60
|
def prepare_widths_for_cli(width)
|
61
61
|
# prepare for the command line. [30,40,50] => "30,40,50"
|
62
|
-
width = width.join(
|
62
|
+
width = width.join(",") if width.is_a? Array
|
63
63
|
width
|
64
64
|
end
|
65
65
|
|
@@ -99,17 +99,16 @@ class Wraith::SaveImages
|
|
99
99
|
max_attempts = 5
|
100
100
|
max_attempts.times do |i|
|
101
101
|
run_command capture_page_image
|
102
|
-
|
103
|
-
if wraith.resize
|
104
|
-
return # @TODO - need to check if the image was generated, as per the reload example below
|
105
|
-
end
|
106
|
-
|
107
|
-
return if File.exist? filename
|
108
|
-
|
102
|
+
return true if image_was_created filename
|
109
103
|
logger.warn "Failed to capture image #{filename} on attempt number #{i + 1} of #{max_attempts}"
|
110
104
|
end
|
111
105
|
|
112
|
-
fail "Unable to capture image #{filename} after #{max_attempts} attempt(s)"
|
106
|
+
fail "Unable to capture image #{filename} after #{max_attempts} attempt(s)" unless image_was_created filename
|
107
|
+
end
|
108
|
+
|
109
|
+
def image_was_created(filename)
|
110
|
+
# @TODO - need to check if the image was generated even if in resize mode
|
111
|
+
wraith.resize or File.exist? filename
|
113
112
|
end
|
114
113
|
|
115
114
|
def create_invalid_image(filename, width)
|
data/lib/wraith/spider.rb
CHANGED
@@ -6,19 +6,20 @@ require "uri"
|
|
6
6
|
|
7
7
|
class Wraith::Spidering
|
8
8
|
include Logging
|
9
|
+
attr_reader :wraith
|
9
10
|
|
10
11
|
def initialize(config)
|
11
12
|
@wraith = Wraith::Wraith.new(config)
|
12
13
|
end
|
13
14
|
|
14
15
|
def check_for_paths
|
15
|
-
if
|
16
|
-
unless
|
16
|
+
if wraith.paths.nil?
|
17
|
+
unless wraith.sitemap.nil?
|
17
18
|
logger.info "no paths defined in config, loading paths from sitemap"
|
18
|
-
spider = Wraith::Sitemap.new(
|
19
|
+
spider = Wraith::Sitemap.new(wraith)
|
19
20
|
else
|
20
21
|
logger.info "no paths defined in config, crawling from site root"
|
21
|
-
spider = Wraith::Crawler.new(
|
22
|
+
spider = Wraith::Crawler.new(wraith)
|
22
23
|
end
|
23
24
|
spider.determine_paths
|
24
25
|
end
|
@@ -39,7 +40,7 @@ class Wraith::Spider
|
|
39
40
|
private
|
40
41
|
|
41
42
|
def write_file
|
42
|
-
File.open(
|
43
|
+
File.open(wraith.spider_file, "w+") { |file| file.write(@paths) }
|
43
44
|
end
|
44
45
|
|
45
46
|
def add_path(path)
|
@@ -60,16 +61,15 @@ class Wraith::Crawler < Wraith::Spider
|
|
60
61
|
m3u f4v pdf doc xls ppt pps bin exe rss xml)
|
61
62
|
|
62
63
|
def spider
|
63
|
-
if File.exist?(
|
64
|
+
if File.exist?(wraith.spider_file) && modified_since(wraith.spider_file, wraith.spider_days[0])
|
64
65
|
logger.info "using existing spider file"
|
65
|
-
@paths = eval(File.read(
|
66
|
+
@paths = eval(File.read(wraith.spider_file))
|
66
67
|
else
|
67
68
|
logger.info "creating new spider file"
|
68
|
-
|
69
|
-
Anemone.crawl(@wraith.base_domain) do |anemone|
|
69
|
+
Anemone.crawl(wraith.base_domain) do |anemone|
|
70
70
|
anemone.skip_links_like(/\.(#{EXT.join('|')})$/)
|
71
71
|
# Add user specified skips
|
72
|
-
anemone.skip_links_like(
|
72
|
+
anemone.skip_links_like(wraith.spider_skips)
|
73
73
|
anemone.on_every_page { |page| add_path(page.url.path) }
|
74
74
|
end
|
75
75
|
end
|
@@ -84,21 +84,20 @@ class Wraith::Sitemap < Wraith::Spider
|
|
84
84
|
include Logging
|
85
85
|
|
86
86
|
def spider
|
87
|
-
unless
|
88
|
-
logger.info "reading sitemap.xml from #{
|
89
|
-
if
|
90
|
-
sitemap = Nokogiri::XML(open(
|
87
|
+
unless wraith.sitemap.nil?
|
88
|
+
logger.info "reading sitemap.xml from #{wraith.sitemap}"
|
89
|
+
if wraith.sitemap =~ URI.regexp
|
90
|
+
sitemap = Nokogiri::XML(open(wraith.sitemap))
|
91
91
|
else
|
92
|
-
sitemap = Nokogiri::XML(File.open(
|
92
|
+
sitemap = Nokogiri::XML(File.open(wraith.sitemap))
|
93
93
|
end
|
94
|
-
urls = {}
|
95
94
|
sitemap.css("loc").each do |loc|
|
96
95
|
path = loc.content
|
97
96
|
# Allow use of either domain in the sitemap.xml
|
98
|
-
|
97
|
+
wraith.domains.each do |_k, v|
|
99
98
|
path.sub!(v, "")
|
100
99
|
end
|
101
|
-
if
|
100
|
+
if wraith.spider_skips.nil? || wraith.spider_skips.none? { |regex| regex.match(path) }
|
102
101
|
add_path(path)
|
103
102
|
end
|
104
103
|
end
|
data/lib/wraith/validate.rb
CHANGED
@@ -4,13 +4,14 @@ require "wraith/helpers/utilities"
|
|
4
4
|
|
5
5
|
class Wraith::Validate
|
6
6
|
include Logging
|
7
|
+
attr_reader :wraith
|
7
8
|
|
8
9
|
def initialize(config, yaml_passed = false)
|
9
10
|
@wraith = Wraith::Wraith.new(config, yaml_passed)
|
10
11
|
end
|
11
12
|
|
12
13
|
def validate(mode = false)
|
13
|
-
list_debug_information if
|
14
|
+
list_debug_information if wraith.verbose
|
14
15
|
validate_basic_properties
|
15
16
|
validate_mode_properties(mode) if mode
|
16
17
|
# if we get this far, we've only had warnings at worst, not errors.
|
@@ -18,13 +19,13 @@ class Wraith::Validate
|
|
18
19
|
end
|
19
20
|
|
20
21
|
def validate_basic_properties
|
21
|
-
if
|
22
|
-
|
22
|
+
if wraith.engine.nil?
|
23
|
+
fail MissingRequiredPropertyError, "You must specify a browser engine! #{docs_prompt}"
|
23
24
|
end
|
24
|
-
unless
|
25
|
-
|
25
|
+
unless wraith.domains
|
26
|
+
fail MissingRequiredPropertyError, "You must specify at least one domain for Wraith to do anything! #{docs_prompt}"
|
26
27
|
end
|
27
|
-
|
28
|
+
# @TODO validate fuzz is not nil, etc
|
28
29
|
end
|
29
30
|
|
30
31
|
def validate_mode_properties(mode)
|
@@ -42,25 +43,21 @@ class Wraith::Validate
|
|
42
43
|
end
|
43
44
|
|
44
45
|
def validate_capture_mode
|
45
|
-
if
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
logger.warn "You have specified a `history_dir` in your config, but this is used in `history` mode, NOT `capture` mode. #{docs_prompt}"
|
50
|
-
end
|
46
|
+
fail InvalidDomainsError, "`wraith capture` requires exactly two domains. #{docs_prompt}" if wraith.domains.length != 2
|
47
|
+
|
48
|
+
logger.warn "You have specified a `history_dir` in your config, but this is"\
|
49
|
+
" used in `history` mode, NOT `capture` mode. #{docs_prompt}" if wraith.history_dir
|
51
50
|
end
|
52
51
|
|
53
52
|
def validate_history_mode
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
if
|
58
|
-
raise InvalidDomainsError, "History mode requires exactly one domain. #{docs_prompt}"
|
59
|
-
end
|
53
|
+
fail MissingRequiredPropertyError, "You must specify a `history_dir` to run"\
|
54
|
+
" Wraith in history mode. #{docs_prompt}" unless wraith.history_dir
|
55
|
+
|
56
|
+
fail InvalidDomainsError, "History mode requires exactly one domain. #{docs_prompt}" if wraith.domains.length != 1
|
60
57
|
end
|
61
58
|
|
62
59
|
def validate_base_shots_exist
|
63
|
-
unless File.directory?(
|
60
|
+
unless File.directory?(wraith.history_dir)
|
64
61
|
logger.error "You need to run `wraith history` at least once before you can run `wraith latest`!"
|
65
62
|
end
|
66
63
|
end
|
@@ -71,10 +68,10 @@ class Wraith::Validate
|
|
71
68
|
|
72
69
|
def list_debug_information
|
73
70
|
wraith_version = Wraith::VERSION
|
74
|
-
ruby_version = run_command_safely(
|
75
|
-
phantomjs_version = run_command_safely(
|
76
|
-
casperjs_version = run_command_safely(
|
77
|
-
imagemagick_version = run_command_safely(
|
71
|
+
ruby_version = run_command_safely("ruby -v") || "Ruby not installed"
|
72
|
+
phantomjs_version = run_command_safely("phantomjs --version") || "PhantomJS not installed"
|
73
|
+
casperjs_version = run_command_safely("casperjs --version") || "CasperJS not installed"
|
74
|
+
imagemagick_version = run_command_safely("convert -version") || "ImageMagick not installed"
|
78
75
|
|
79
76
|
logger.debug "#################################################"
|
80
77
|
logger.debug " Wraith version: #{wraith_version}"
|
@@ -90,9 +87,9 @@ class Wraith::Validate
|
|
90
87
|
def run_command_safely(command)
|
91
88
|
begin
|
92
89
|
output = `#{command}`
|
93
|
-
rescue
|
90
|
+
rescue StandardError
|
94
91
|
return false
|
95
92
|
end
|
96
93
|
output.lines.first
|
97
94
|
end
|
98
|
-
end
|
95
|
+
end
|
data/lib/wraith/version.rb
CHANGED
data/lib/wraith/wraith.rb
CHANGED
@@ -7,21 +7,27 @@ class Wraith::Wraith
|
|
7
7
|
attr_accessor :config
|
8
8
|
|
9
9
|
def initialize(config, yaml_passed = false)
|
10
|
-
|
11
|
-
|
12
|
-
logger.level = verbose ? Logger::DEBUG : Logger::INFO
|
13
|
-
rescue
|
14
|
-
logger.error "unable to find config at #{config}"
|
15
|
-
end
|
10
|
+
@config = yaml_passed ? config : open_config_file(config)
|
11
|
+
logger.level = verbose ? Logger::DEBUG : Logger::INFO
|
16
12
|
end
|
17
13
|
|
18
14
|
def open_config_file(config_name)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
possible_filenames = [
|
16
|
+
config_name,
|
17
|
+
"#{config_name}.yml",
|
18
|
+
"#{config_name}.yaml",
|
19
|
+
"configs/#{config_name}.yml",
|
20
|
+
"configs/#{config_name}.yaml"
|
21
|
+
]
|
22
|
+
|
23
|
+
possible_filenames.each do |filepath|
|
24
|
+
if File.exist?(filepath)
|
25
|
+
config = File.open config_name
|
26
|
+
return YAML.load config
|
27
|
+
end
|
23
28
|
end
|
24
|
-
|
29
|
+
rescue
|
30
|
+
logger.error "unable to find config \"#{config}\""
|
25
31
|
end
|
26
32
|
|
27
33
|
def directory
|
@@ -45,7 +51,7 @@ class Wraith::Wraith
|
|
45
51
|
end
|
46
52
|
|
47
53
|
def snap_file_from_engine(engine)
|
48
|
-
path_to_js_templates = File.dirname(__FILE__) +
|
54
|
+
path_to_js_templates = File.dirname(__FILE__) + "/javascript"
|
49
55
|
case engine
|
50
56
|
when "phantomjs"
|
51
57
|
path_to_js_templates + "/phantom.js"
|
@@ -131,7 +137,7 @@ class Wraith::Wraith
|
|
131
137
|
end
|
132
138
|
|
133
139
|
def gallery_template
|
134
|
-
default =
|
140
|
+
default = "basic_template"
|
135
141
|
if @config["gallery"].nil?
|
136
142
|
default
|
137
143
|
else
|
@@ -163,6 +169,6 @@ class Wraith::Wraith
|
|
163
169
|
|
164
170
|
def verbose
|
165
171
|
# @TODO - also add a `--verbose` CLI flag which overrides whatever you have set in the config
|
166
|
-
@config[
|
172
|
+
@config["verbose"] || false
|
167
173
|
end
|
168
|
-
end
|
174
|
+
end
|
data/spec/before_capture_spec.rb
CHANGED
@@ -2,12 +2,12 @@ require "_helpers"
|
|
2
2
|
|
3
3
|
def run_js_then_capture(config)
|
4
4
|
saving = Wraith::SaveImages.new(config_name)
|
5
|
-
generated_image =
|
5
|
+
generated_image = "shots/test/temporary_jsified_image.png"
|
6
6
|
capture_image = saving.construct_command(320, "http://www.bbc.com/afrique", generated_image, selector, config[:global_js], config[:path_js])
|
7
7
|
`#{capture_image}`
|
8
8
|
Wraith::CompareImages.new(config_name).compare_task(generated_image, config[:output_should_look_like], "shots/test/test_diff.png", "shots/test/test.txt")
|
9
|
-
diff = File.open(
|
10
|
-
expect(diff).to eq
|
9
|
+
diff = File.open("shots/test/test.txt", "rb").read
|
10
|
+
expect(diff).to eq "0.0"
|
11
11
|
end
|
12
12
|
|
13
13
|
describe Wraith do
|
@@ -30,7 +30,7 @@ describe Wraith do
|
|
30
30
|
'
|
31
31
|
wraith = Wraith::Wraith.new(config, true)
|
32
32
|
# not sure about having code IN the test, but we want to get this right.
|
33
|
-
expect(wraith.before_capture).to eq
|
33
|
+
expect(wraith.before_capture).to eq(Dir.pwd + "/javascript/do_something.js")
|
34
34
|
end
|
35
35
|
|
36
36
|
it "should allow users to specify the absolute path to the before_capture file" do
|
@@ -39,7 +39,7 @@ describe Wraith do
|
|
39
39
|
before_capture: /Users/some_user/wraith/javascript/do_something.js
|
40
40
|
'
|
41
41
|
wraith = Wraith::Wraith.new(config, true)
|
42
|
-
expect(wraith.before_capture).to eq
|
42
|
+
expect(wraith.before_capture).to eq("/Users/some_user/wraith/javascript/do_something.js")
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -48,33 +48,33 @@ describe Wraith do
|
|
48
48
|
describe "When hooking into beforeCapture (CasperJS)" do
|
49
49
|
it "Executes the global JS before capturing" do
|
50
50
|
run_js_then_capture(
|
51
|
-
global_js
|
52
|
-
path_js
|
53
|
-
output_should_look_like
|
54
|
-
engine
|
51
|
+
:global_js => before_suite_js,
|
52
|
+
:path_js => false,
|
53
|
+
:output_should_look_like => "spec/base/global.png",
|
54
|
+
:engine => "casperjs"
|
55
55
|
)
|
56
56
|
end
|
57
57
|
|
58
58
|
it "Executes the path-level JS before capturing" do
|
59
59
|
run_js_then_capture(
|
60
|
-
global_js
|
61
|
-
path_js
|
62
|
-
output_should_look_like
|
63
|
-
engine
|
60
|
+
:global_js => false,
|
61
|
+
:path_js => before_capture_js,
|
62
|
+
:output_should_look_like => "spec/base/path.png",
|
63
|
+
:engine => "casperjs"
|
64
64
|
)
|
65
65
|
end
|
66
66
|
|
67
67
|
it "Executes the global JS before the path-level JS" do
|
68
68
|
run_js_then_capture(
|
69
|
-
global_js
|
70
|
-
path_js
|
71
|
-
output_should_look_like
|
72
|
-
engine
|
69
|
+
:global_js => before_suite_js,
|
70
|
+
:path_js => before_capture_js,
|
71
|
+
:output_should_look_like => "spec/base/path.png",
|
72
|
+
:engine => "casperjs"
|
73
73
|
)
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
#
|
77
|
+
# @TODO - uncomment and figure out why broken
|
78
78
|
# describe "When hooking into beforeCapture (PhantomJS)" do
|
79
79
|
# let(:config_name) { get_path_relative_to __FILE__, "./configs/test_config--phantom.yaml" }
|
80
80
|
# let(:saving) { Wraith::SaveImages.new(config_name) }
|
@@ -110,4 +110,4 @@ describe Wraith do
|
|
110
110
|
# )
|
111
111
|
# end
|
112
112
|
# end
|
113
|
-
end
|
113
|
+
end
|
data/spec/config_spec.rb
CHANGED
@@ -70,10 +70,10 @@ describe "wraith config" do
|
|
70
70
|
|
71
71
|
describe "different ways of initialising browser engine" do
|
72
72
|
it "should let us directly specify the engine" do
|
73
|
-
config = YAML.load
|
73
|
+
config = YAML.load "browser: phantomjs"
|
74
74
|
wraith = Wraith::Wraith.new(config, true)
|
75
75
|
|
76
|
-
expect(wraith.engine).to eq
|
76
|
+
expect(wraith.engine).to eq "phantomjs"
|
77
77
|
end
|
78
78
|
|
79
79
|
it "should be backwards compatible with the old way" do
|
@@ -82,19 +82,19 @@ describe "wraith config" do
|
|
82
82
|
phantomjs: "casperjs"
|
83
83
|
'
|
84
84
|
wraith = Wraith::Wraith.new(config, true)
|
85
|
-
expect(wraith.engine).to eq
|
85
|
+
expect(wraith.engine).to eq "casperjs"
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
89
|
describe "different ways of determining the snap file" do
|
90
90
|
it "should calculate the snap file from the engine" do
|
91
|
-
config = YAML.load
|
91
|
+
config = YAML.load "browser: phantomjs"
|
92
92
|
wraith = Wraith::Wraith.new(config, true)
|
93
|
-
expect(wraith.snap_file).to include
|
93
|
+
expect(wraith.snap_file).to include "lib/wraith/javascript/phantom.js"
|
94
94
|
|
95
|
-
config = YAML.load
|
95
|
+
config = YAML.load "browser: casperjs"
|
96
96
|
wraith = Wraith::Wraith.new(config, true)
|
97
|
-
expect(wraith.snap_file).to include
|
97
|
+
expect(wraith.snap_file).to include "lib/wraith/javascript/casper.js"
|
98
98
|
end
|
99
99
|
|
100
100
|
it "should calculate the snap file in a backwards-compatible way" do
|
@@ -103,7 +103,7 @@ describe "wraith config" do
|
|
103
103
|
phantomjs: "casperjs"
|
104
104
|
'
|
105
105
|
wraith = Wraith::Wraith.new(config, true)
|
106
|
-
expect(wraith.snap_file).to include
|
106
|
+
expect(wraith.snap_file).to include "lib/wraith/javascript/casper.js"
|
107
107
|
end
|
108
108
|
|
109
109
|
it "should allow users to specify the relative path to their own snap file" do
|
@@ -113,7 +113,7 @@ describe "wraith config" do
|
|
113
113
|
'
|
114
114
|
wraith = Wraith::Wraith.new(config, true)
|
115
115
|
# not sure about having code IN the test, but we want to get this right.
|
116
|
-
expect(wraith.snap_file).to eq
|
116
|
+
expect(wraith.snap_file).to eq(Dir.pwd + "/path/to/snap.js")
|
117
117
|
end
|
118
118
|
|
119
119
|
it "should allow users to specify the absolute path to their own snap file" do
|
@@ -122,7 +122,7 @@ describe "wraith config" do
|
|
122
122
|
snap_file: /Users/my_username/Sites/bbc/wraith/path/to/snap.js
|
123
123
|
'
|
124
124
|
wraith = Wraith::Wraith.new(config, true)
|
125
|
-
expect(wraith.snap_file).to eq
|
125
|
+
expect(wraith.snap_file).to eq("/Users/my_username/Sites/bbc/wraith/path/to/snap.js")
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
@@ -139,4 +139,4 @@ describe "wraith config" do
|
|
139
139
|
expect(wraith.resize).to eq false
|
140
140
|
end
|
141
141
|
end
|
142
|
-
end
|
142
|
+
end
|
@@ -6,10 +6,10 @@ describe "Wraith config to CLI argument mapping" do
|
|
6
6
|
let(:config_name) { get_path_relative_to __FILE__, "./configs/test_config--phantom.yaml" }
|
7
7
|
let(:saving) { Wraith::SaveImages.new(config_name) }
|
8
8
|
let(:width) { 320 }
|
9
|
-
let(:url) {
|
10
|
-
let(:file_name) {
|
11
|
-
let(:selector) {
|
12
|
-
let(:global_bc) {
|
9
|
+
let(:url) { "http://example.com/my-page" }
|
10
|
+
let(:file_name) { "wraith/my-page/320_phantomjs_latest.png" }
|
11
|
+
let(:selector) { ".my_selector" }
|
12
|
+
let(:global_bc) { "javascript/before_capture.js" }
|
13
13
|
let(:path_bc) { false }
|
14
14
|
|
15
15
|
it "should take a load of variables and construct a command" do
|
@@ -40,4 +40,4 @@ describe "Wraith config to CLI argument mapping" do
|
|
40
40
|
expect(actual).to eq expected
|
41
41
|
end
|
42
42
|
end
|
43
|
-
end
|
43
|
+
end
|
data/spec/gallery_spec.rb
CHANGED
@@ -5,33 +5,27 @@ describe Wraith do
|
|
5
5
|
let(:gallery) { Wraith::GalleryGenerator.new(config_name, false) }
|
6
6
|
|
7
7
|
describe "When generating gallery" do
|
8
|
-
|
9
8
|
it "should not break when there is a `-` in the filename" do
|
10
|
-
dirs = gallery.parse_directories
|
9
|
+
dirs = gallery.parse_directories "spec/thumbnails"
|
11
10
|
|
12
11
|
images = [
|
13
12
|
{
|
14
|
-
:filename =>
|
15
|
-
:thumb =>
|
13
|
+
:filename => "home/test_image-afrique.png",
|
14
|
+
:thumb => "thumbnails/home/test_image-afrique.png"
|
16
15
|
},
|
17
16
|
{
|
18
|
-
:filename =>
|
19
|
-
:thumb =>
|
17
|
+
:filename => "home/test_image-russian.png",
|
18
|
+
:thumb => "thumbnails/home/test_image-russian.png"
|
20
19
|
}
|
21
20
|
]
|
22
21
|
|
23
|
-
dirs[
|
22
|
+
dirs["home"][0][:variants].each_with_index do |image, i|
|
24
23
|
expect(image[:filename]).to eq images[i][:filename]
|
25
24
|
expect(image[:thumb]).to eq images[i][:thumb]
|
26
25
|
end
|
27
26
|
|
28
|
-
diff
|
29
|
-
|
30
|
-
:thumb => 'thumbnails/home/test_image-diff.png'
|
31
|
-
}
|
32
|
-
|
33
|
-
expect(dirs['home'][0][:diff][:filename]).to eq 'home/test_image-diff.png'
|
34
|
-
expect(dirs['home'][0][:diff][:thumb]).to eq 'thumbnails/home/test_image-diff.png'
|
27
|
+
expect(dirs["home"][0][:diff][:filename]).to eq "home/test_image-diff.png"
|
28
|
+
expect(dirs["home"][0][:diff][:thumb]).to eq "thumbnails/home/test_image-diff.png"
|
35
29
|
end
|
36
30
|
end
|
37
|
-
end
|
31
|
+
end
|
data/spec/helper_spec.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "_helpers"
|
2
|
+
|
3
|
+
describe "Wraith helpers classes and functions" do
|
4
|
+
|
5
|
+
describe "the convert_to_absolute function" do
|
6
|
+
it "should return false if no filepath provided" do
|
7
|
+
expect(convert_to_absolute(nil)).to eq 'false'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should convert a relative path to absolute" do
|
11
|
+
relative = 'my/filepath'
|
12
|
+
absolute = convert_to_absolute relative
|
13
|
+
expect(absolute[0]).to eq '/'
|
14
|
+
expect(absolute.length).to be > relative.length
|
15
|
+
expect(absolute).to match(/\/(.+)\/(.+)\/my\/filepath/)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should leave an absolute path unchanged" do
|
19
|
+
relative = '/my/filepath'
|
20
|
+
absolute = convert_to_absolute relative
|
21
|
+
expect(absolute).to eq relative
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should leave a Windows-flavoured absolute path unchanged" do
|
25
|
+
relative = 'C:/Code/Wraith/javascript/global.js'
|
26
|
+
absolute = convert_to_absolute relative
|
27
|
+
expect(absolute).to eq relative
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/spec/resize_reload_spec.rb
CHANGED
data/spec/save_images_spec.rb
CHANGED
data/spec/validate_spec.rb
CHANGED
@@ -12,40 +12,40 @@ describe "Wraith config validator" do
|
|
12
12
|
|
13
13
|
describe "universal, basic validation for all modes" do
|
14
14
|
it "should validate a basic config" do
|
15
|
-
|
15
|
+
Wraith::Validate.new(config, true).validate
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should complain if the `domains` property is missing" do
|
19
|
-
config[
|
19
|
+
config["domains"] = nil
|
20
20
|
expect { Wraith::Validate.new(config, true).validate }.to raise_error MissingRequiredPropertyError
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should complain if the `browser` property is missing" do
|
24
|
-
config[
|
24
|
+
config["browser"] = nil
|
25
25
|
expect { Wraith::Validate.new(config, true).validate }.to raise_error MissingRequiredPropertyError
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
describe "validation specific to capture mode" do
|
30
30
|
it "should complain if fewer than two domains are specified" do
|
31
|
-
expect { Wraith::Validate.new(config, true).validate(
|
31
|
+
expect { Wraith::Validate.new(config, true).validate("capture") }.to raise_error InvalidDomainsError
|
32
32
|
end
|
33
33
|
|
34
34
|
it "should complain if more than two domains are specified" do
|
35
|
-
config[
|
35
|
+
config["domains"] = YAML.load('
|
36
36
|
test: http://something.bbc.com
|
37
37
|
stage: http://something-else.bbc.com
|
38
38
|
live: http://www.bbc.com
|
39
39
|
')
|
40
|
-
expect { Wraith::Validate.new(config, true).validate(
|
40
|
+
expect { Wraith::Validate.new(config, true).validate("capture") }.to raise_error InvalidDomainsError
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should be happy if exactly two domains are specified" do
|
44
|
-
config[
|
44
|
+
config["domains"] = YAML.load('
|
45
45
|
test: http://something.bbc.com
|
46
46
|
live: http://www.bbc.com
|
47
47
|
')
|
48
|
-
|
48
|
+
Wraith::Validate.new(config, true).validate("capture")
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -57,20 +57,20 @@ describe "Wraith config validator" do
|
|
57
57
|
end
|
58
58
|
|
59
59
|
it "should complain if more than one domain is specified" do
|
60
|
-
history_conf[
|
60
|
+
history_conf["domains"] = YAML.load('
|
61
61
|
test: http://something.bbc.com
|
62
62
|
live: http://www.bbc.com
|
63
63
|
')
|
64
|
-
expect { Wraith::Validate.new(history_conf, true).validate(
|
64
|
+
expect { Wraith::Validate.new(history_conf, true).validate("history") }.to raise_error InvalidDomainsError
|
65
65
|
end
|
66
66
|
|
67
67
|
it "should complain if no history_dir is specified" do
|
68
|
-
history_conf[
|
69
|
-
expect { Wraith::Validate.new(history_conf, true).validate(
|
68
|
+
history_conf["history_dir"] = nil
|
69
|
+
expect { Wraith::Validate.new(history_conf, true).validate("history") }.to raise_error MissingRequiredPropertyError
|
70
70
|
end
|
71
71
|
|
72
72
|
it "should be happy if a history_dir and one domain is specified" do
|
73
|
-
|
73
|
+
Wraith::Validate.new(history_conf, true).validate("history")
|
74
74
|
end
|
75
75
|
end
|
76
|
-
end
|
76
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wraith
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dave Blooman
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2016-02-28 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: pry
|
@@ -221,6 +221,7 @@ files:
|
|
221
221
|
- spec/configs/test_config--phantom.yaml
|
222
222
|
- spec/construct_command_spec.rb
|
223
223
|
- spec/gallery_spec.rb
|
224
|
+
- spec/helper_spec.rb
|
224
225
|
- spec/js/custom_snap_file.js
|
225
226
|
- spec/js/global.js
|
226
227
|
- spec/js/path.js
|
@@ -263,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
263
264
|
version: '0'
|
264
265
|
requirements: []
|
265
266
|
rubyforge_project:
|
266
|
-
rubygems_version: 2.4.
|
267
|
+
rubygems_version: 2.4.8
|
267
268
|
signing_key:
|
268
269
|
specification_version: 4
|
269
270
|
summary: Wraith is a screenshot comparison tool, created by developers at BBC News.
|
@@ -277,6 +278,7 @@ test_files:
|
|
277
278
|
- spec/configs/test_config--phantom.yaml
|
278
279
|
- spec/construct_command_spec.rb
|
279
280
|
- spec/gallery_spec.rb
|
281
|
+
- spec/helper_spec.rb
|
280
282
|
- spec/js/custom_snap_file.js
|
281
283
|
- spec/js/global.js
|
282
284
|
- spec/js/path.js
|