dom_glancy 0.1.0
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 +7 -0
- data/.gitignore +21 -0
- data/.ruby-version +1 -0
- data/.travis.yml +15 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +22 -0
- data/README.md +35 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/application.js +1 -0
- data/app/assets/stylesheets/1236_grid.css +21 -0
- data/app/assets/stylesheets/720_grid.css +33 -0
- data/app/assets/stylesheets/986_grid.css +24 -0
- data/app/assets/stylesheets/dom_glancy.css +134 -0
- data/app/assets/stylesheets/normalize.css +425 -0
- data/app/controllers/dom_glancy_application_controller.rb +8 -0
- data/app/controllers/dom_glancy_controller.rb +114 -0
- data/app/views/dom_glancy/about.html.erb +3 -0
- data/app/views/dom_glancy/artifacts.html.erb +16 -0
- data/app/views/dom_glancy/index.html.erb +12 -0
- data/app/views/dom_glancy/new.html.erb +15 -0
- data/app/views/dom_glancy/path_config.html.erb +8 -0
- data/app/views/dom_glancy/show.html.erb +42 -0
- data/app/views/layouts/dom_glancy.html.erb +32 -0
- data/app/views/shared/_dom_glancy_nav.html.erb +8 -0
- data/app/views/shared/_dom_set.html.erb +35 -0
- data/config/routes.rb +17 -0
- data/dom_glancy.gemspec +26 -0
- data/lib/dom_glancy/analysis.rb +141 -0
- data/lib/dom_glancy/dom_glancy.rb +121 -0
- data/lib/dom_glancy/element.rb +92 -0
- data/lib/dom_glancy/locations.rb +49 -0
- data/lib/dom_glancy/rails/engine.rb +7 -0
- data/lib/dom_glancy/svg.rb +71 -0
- data/lib/dom_glancy/version.rb +3 -0
- data/lib/dom_glancy.rb +7 -0
- data/test/page_objects/dom_glancy/about_page.rb +7 -0
- data/test/page_objects/dom_glancy/artifacts_page.rb +7 -0
- data/test/page_objects/dom_glancy/config_page.rb +19 -0
- data/test/page_objects/dom_glancy/index_page.rb +9 -0
- data/test/page_objects/dom_glancy/local_index_page.rb +7 -0
- data/test/page_objects/dom_glancy/new_page.rb +7 -0
- data/test/page_objects/dom_glancy/show_page.rb +15 -0
- data/test/page_objects/dom_glancy/viewer_page.rb +15 -0
- data/test/page_objects/navigation.rb +34 -0
- data/test/page_objects.rb +13 -0
- data/test/selenium/mapping_test.rb +118 -0
- data/test/selenium/viewer_test.rb +26 -0
- data/test/selenium_test_helper.rb +147 -0
- data/test/test_app/Gemfile +10 -0
- data/test/test_app/app/assets/stylesheets/local_app.css +25 -0
- data/test/test_app/app/controllers/application_controller.rb +2 -0
- data/test/test_app/app/controllers/local_controller.rb +8 -0
- data/test/test_app/app/views/layouts/local.html.erb +14 -0
- data/test/test_app/app/views/local/index.html.erb +45 -0
- data/test/test_app/config/database.yml +13 -0
- data/test/test_app/config/initializers/dom_glancy_initializer.rb +5 -0
- data/test/test_app/config/routes.rb +4 -0
- data/test/test_app/config.ru +31 -0
- data/test/test_app/test_app.rb +30 -0
- data/test/test_helper.rb +43 -0
- data/test/test_helpers/kracker_class_for_stubbing.rb +3 -0
- data/test/test_helpers/location_helpers.rb +28 -0
- data/test/test_objects/test_objects.rb +2031 -0
- data/test/unit/analysis_test.rb +111 -0
- data/test/unit/element_test.rb +47 -0
- data/test/unit/kracker_test.rb +79 -0
- data/test/unit/location_test.rb +23 -0
- data/watchr_script.rb +3 -0
- metadata +199 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
<div id="<%= finder_id %>">
|
2
|
+
<% if elements.length > 0 %>
|
3
|
+
<table class='kr--dom'>
|
4
|
+
<thead>
|
5
|
+
<tr>
|
6
|
+
<th>tag</th>
|
7
|
+
<th>id</th>
|
8
|
+
<th>class(s)</th>
|
9
|
+
<th>top</th>
|
10
|
+
<th>left</th>
|
11
|
+
<th>width</th>
|
12
|
+
<th>height</th>
|
13
|
+
<th>visible</th>
|
14
|
+
</tr>
|
15
|
+
</thead>
|
16
|
+
<tbody>
|
17
|
+
<% reset_cycle %>
|
18
|
+
<% elements.each do |element| %>
|
19
|
+
<tr onclick="highlightElement(<%= element[:js_id] %>);" class="<%= cycle("kr-dom_row_odd", "kr-dom_row_even") %>">
|
20
|
+
<td><%= element['tag'] %></td>
|
21
|
+
<td><%= element['id'] %></td>
|
22
|
+
<td><%= element['class'] %></td>
|
23
|
+
<td><%= element['top'] %></td>
|
24
|
+
<td><%= element['left'] %></td>
|
25
|
+
<td><%= element['width'] %></td>
|
26
|
+
<td><%= element['height'] %></td>
|
27
|
+
<td><%= element['visible'] %></td>
|
28
|
+
</tr>
|
29
|
+
<% end %>
|
30
|
+
</tbody>
|
31
|
+
</table>
|
32
|
+
<% else %>
|
33
|
+
<p>no elements found.</p>
|
34
|
+
<% end %>
|
35
|
+
</div>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
get 'dom_glancy' => "dom_glancy#index"
|
3
|
+
get 'dom_glancy/config' => "dom_glancy#path_config"
|
4
|
+
get 'dom_glancy/about' => "dom_glancy#about"
|
5
|
+
get 'dom_glancy/show/:diff_file' => "dom_glancy#show"
|
6
|
+
get 'dom_glancy/clear' => "dom_glancy#clear"
|
7
|
+
post 'dom_glancy/bless' => "dom_glancy#bless"#, :via => [:get, :post]
|
8
|
+
|
9
|
+
get 'dom_glancy/artifacts' => "dom_glancy#artifacts"
|
10
|
+
get 'dom_glancy/artifacts_delete/:file' => "dom_glancy#artifacts_delete"
|
11
|
+
get 'dom_glancy/artifacts_expand/:file' => "dom_glancy#artifacts_expand"
|
12
|
+
|
13
|
+
get 'dom_glancy/make_master/:file' => "dom_glancy#make_master"
|
14
|
+
get 'dom_glancy/delete_current/:file' => "dom_glancy#delete_current"
|
15
|
+
|
16
|
+
resources :dom_glancy
|
17
|
+
end
|
data/dom_glancy.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dom_glancy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dom_glancy"
|
8
|
+
spec.version = DomGlancy::VERSION
|
9
|
+
spec.authors = ["geordie"]
|
10
|
+
spec.email = ["george.speake@gmail.com"]
|
11
|
+
spec.description = %q{DOM Mapping}
|
12
|
+
spec.summary = %q{Map the page DOM and get some stats on it compared to a known default map.}
|
13
|
+
spec.homepage = "https://github.com/QuantumGeordie/dom_glancy"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
|
24
|
+
spec.add_dependency(%q<kramdown>, ["~> 1.1.0"])
|
25
|
+
spec.add_dependency 'capybara'
|
26
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module DomGlancy
|
2
|
+
|
3
|
+
def analyze(master_data, current_data, test_root = nil)
|
4
|
+
output_hash = {}
|
5
|
+
|
6
|
+
master_set = master_data.to_set
|
7
|
+
current_set = current_data.to_set
|
8
|
+
|
9
|
+
set_current_not_master = current_set - master_set
|
10
|
+
set_master_not_current = master_set - current_set
|
11
|
+
set_changed_master = Set.new
|
12
|
+
|
13
|
+
changed_element_pairs = []
|
14
|
+
if set_master_not_current.count > 0 || set_current_not_master.count > 0
|
15
|
+
|
16
|
+
ok_pairs = pairs_that_are_close_enough(set_current_not_master, set_master_not_current)
|
17
|
+
|
18
|
+
ok_pairs.each do |item1, item2|
|
19
|
+
set_current_not_master.delete(item1)
|
20
|
+
set_master_not_current.delete(item2)
|
21
|
+
end
|
22
|
+
|
23
|
+
changed_element_pairs = get_set_of_same_but_different(set_current_not_master, set_master_not_current)
|
24
|
+
|
25
|
+
changed_element_pairs.each do |item1, item2|
|
26
|
+
set_current_not_master.delete(item1)
|
27
|
+
set_current_not_master.delete(item2)
|
28
|
+
|
29
|
+
set_master_not_current.delete(item1)
|
30
|
+
set_master_not_current.delete(item2)
|
31
|
+
end
|
32
|
+
|
33
|
+
changed_element_pairs.select!{ |pair| !DOMElement.new(pair[0]).close_enough?(DOMElement.new(pair[1])) }
|
34
|
+
changed_element_pairs.each do |pair|
|
35
|
+
set_changed_master.add(pair.first)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
all_same = set_current_not_master.count == 0 && set_master_not_current.count == 0 && changed_element_pairs.count == 0
|
40
|
+
|
41
|
+
create_diff_file(set_current_not_master, set_master_not_current, set_changed_master, test_root) if test_root && !all_same
|
42
|
+
|
43
|
+
output_hash[:not_in_master] = set_current_not_master
|
44
|
+
output_hash[:not_in_current] = set_master_not_current
|
45
|
+
output_hash[:changed_element_pairs] = changed_element_pairs
|
46
|
+
output_hash[:same] = all_same
|
47
|
+
output_hash[:test_root] = test_root
|
48
|
+
output_hash
|
49
|
+
end
|
50
|
+
|
51
|
+
def make_svg(set_master_not_current, set_current_not_master, set_changed_master)
|
52
|
+
js_id = 0
|
53
|
+
set_master_not_current.each do |item|
|
54
|
+
item[:js_id] = js_id
|
55
|
+
js_id += 1
|
56
|
+
end
|
57
|
+
set_current_not_master.each do |item|
|
58
|
+
item[:js_id] = js_id
|
59
|
+
js_id += 1
|
60
|
+
end
|
61
|
+
set_changed_master.each do |item|
|
62
|
+
item[:js_id] = js_id
|
63
|
+
js_id += 1
|
64
|
+
end
|
65
|
+
|
66
|
+
rectangles = set_current_not_master.map { |item| item.merge(format__not_in_master) }
|
67
|
+
rectangles << set_master_not_current.map { |item| item.merge(format__not_in_current) }
|
68
|
+
rectangles << set_changed_master.map { |item| item.merge(format__same_but_different) }
|
69
|
+
rectangles.flatten!
|
70
|
+
|
71
|
+
generate_svg(rectangles)
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_diff_file(set_current_not_master, set_master_not_current, set_changed_master, test_root)
|
75
|
+
filename = DomGlancy.diff_filename(test_root)
|
76
|
+
svg = make_svg(set_current_not_master, set_master_not_current, set_changed_master)
|
77
|
+
File.open(filename, 'w') { |file| file.write(svg) }
|
78
|
+
save_set_info(test_root, 'current_not_master', set_current_not_master)
|
79
|
+
save_set_info(test_root, 'master_not_current', set_master_not_current)
|
80
|
+
save_set_info(test_root, 'changed_master', set_changed_master)
|
81
|
+
end
|
82
|
+
|
83
|
+
def save_set_info(test_root, suffix, data_set)
|
84
|
+
filename = File.join(DomGlancy.diff_file_location, "#{test_root}__#{suffix}__diff.yaml")
|
85
|
+
|
86
|
+
data_array = data_set.to_a
|
87
|
+
|
88
|
+
File.open(filename, 'w') { |file| file.write(data_array.to_yaml) }
|
89
|
+
end
|
90
|
+
|
91
|
+
def get_set_of_same_but_different(set1, set2)
|
92
|
+
same_but_different_pairs = []
|
93
|
+
set1.each do |item1|
|
94
|
+
element1 = DOMElement.new(item1)
|
95
|
+
set2.each do |item2|
|
96
|
+
element2 = DOMElement.new(item2)
|
97
|
+
if element1.same_element?(element2)
|
98
|
+
same_but_different_pairs << [item1, item2] #unless element1.close_enough?(element2)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
same_but_different_pairs
|
103
|
+
end
|
104
|
+
|
105
|
+
def pairs_that_are_close_enough(set1, set2)
|
106
|
+
ok_pairs = []
|
107
|
+
set1.each do |item1|
|
108
|
+
element1 = DOMElement.new(item1)
|
109
|
+
set2.each do |item2|
|
110
|
+
element2 = DOMElement.new(item2)
|
111
|
+
if element1.same_element?(element2) && element1.close_enough?(element2)
|
112
|
+
ok_pairs << [item1, item2]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
ok_pairs
|
117
|
+
end
|
118
|
+
|
119
|
+
def make_analysis_failure_report(analysis_data)
|
120
|
+
return '' if analysis_data[:same]
|
121
|
+
|
122
|
+
msg = ["\n------- DOM Comparison Failure ------"]
|
123
|
+
msg << "Elements not in master: #{analysis_data[:not_in_master].count}"
|
124
|
+
msg << "Elements not in current: #{analysis_data[:not_in_current].count}"
|
125
|
+
msg << "Changed elements: #{analysis_data[:changed_element_pairs].count}"
|
126
|
+
msg << "Files:"
|
127
|
+
msg << "\tcurrent: #{DomGlancy.current_filename(analysis_data[:test_root])}"
|
128
|
+
msg << "\tmaster: #{DomGlancy.master_filename(analysis_data[:test_root])}"
|
129
|
+
msg << "\tdifference: #{DomGlancy.diff_filename(analysis_data[:test_root])}"
|
130
|
+
msg << "Bless this current data set:"
|
131
|
+
msg << "\t#{blessing_copy_string(analysis_data[:test_root])}"
|
132
|
+
msg<< "-------------------------------------"
|
133
|
+
|
134
|
+
msg.join("\n")
|
135
|
+
end
|
136
|
+
|
137
|
+
def blessing_copy_string(test_root)
|
138
|
+
"cp #{DomGlancy.current_filename(test_root)} #{DomGlancy.master_filename(test_root)}"
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module DomGlancy
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
def page_map_same?(test_root)
|
5
|
+
purge_old_files_before_test(test_root)
|
6
|
+
|
7
|
+
result, msg = map_current_file(test_root)
|
8
|
+
return [result, msg] unless result
|
9
|
+
|
10
|
+
result, msg = master_file_exists?(test_root)
|
11
|
+
return [result, msg] unless result
|
12
|
+
|
13
|
+
result, msg, current_data = read_map_file(DomGlancy.current_filename(test_root))
|
14
|
+
return [result, msg] unless result
|
15
|
+
|
16
|
+
result, msg, master_data = read_map_file(DomGlancy.master_filename(test_root))
|
17
|
+
return [result, msg] unless result
|
18
|
+
|
19
|
+
analysis_data = analyze(master_data, current_data, test_root)
|
20
|
+
|
21
|
+
msg = make_analysis_failure_report(analysis_data)
|
22
|
+
result = analysis_data[:same]
|
23
|
+
|
24
|
+
File.delete DomGlancy.current_filename(test_root) if result
|
25
|
+
|
26
|
+
[result, msg]
|
27
|
+
end
|
28
|
+
|
29
|
+
def read_map_file(filename)
|
30
|
+
results = [true, '', nil]
|
31
|
+
begin
|
32
|
+
results[2] = YAML::load( File.open( filename ) )
|
33
|
+
rescue Exception => e
|
34
|
+
results = [false, "Error reading data from file: #{filename}", nil]
|
35
|
+
end
|
36
|
+
|
37
|
+
results
|
38
|
+
end
|
39
|
+
|
40
|
+
def map_current_file(test_root)
|
41
|
+
filename = DomGlancy.current_filename(test_root)
|
42
|
+
|
43
|
+
result = [true, '']
|
44
|
+
begin
|
45
|
+
data = perform_mapping_operation.to_yaml
|
46
|
+
File.open(filename, 'w') { |file| file.write(data) }
|
47
|
+
rescue Exception => e
|
48
|
+
result = [false, "map current file error: #{e.message}"]
|
49
|
+
end
|
50
|
+
|
51
|
+
result
|
52
|
+
end
|
53
|
+
|
54
|
+
def perform_mapping_operation
|
55
|
+
|
56
|
+
js = <<-JS
|
57
|
+
var dom_glancy = {
|
58
|
+
|
59
|
+
treeUp: function() {
|
60
|
+
var treeWalker = document.createTreeWalker(
|
61
|
+
document.body,
|
62
|
+
NodeFilter.SHOW_ELEMENT,
|
63
|
+
{ acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; } },
|
64
|
+
false
|
65
|
+
);
|
66
|
+
|
67
|
+
var nodeList = [];
|
68
|
+
|
69
|
+
while(treeWalker.nextNode()){
|
70
|
+
var cn = treeWalker.currentNode;
|
71
|
+
var node_details = {
|
72
|
+
"height" : cn.clientHeight,
|
73
|
+
"width" : cn.clientWidth,
|
74
|
+
"id" : cn.id,
|
75
|
+
"tag" : cn.tagName,
|
76
|
+
"class" : cn.className,
|
77
|
+
//"html" : cn.innerHTML,
|
78
|
+
"top" : cn.offsetTop,
|
79
|
+
"left" : cn.offsetLeft,
|
80
|
+
"visible" : dom_glancy.isVisible(cn)
|
81
|
+
}
|
82
|
+
nodeList.push(node_details);
|
83
|
+
}
|
84
|
+
|
85
|
+
return(nodeList);
|
86
|
+
},
|
87
|
+
|
88
|
+
isVisible: function(elem) {
|
89
|
+
return elem.offsetWidth > 0 || elem.offsetHeight > 0;
|
90
|
+
}
|
91
|
+
};
|
92
|
+
return dom_glancy.treeUp();
|
93
|
+
JS
|
94
|
+
|
95
|
+
page.driver.browser.execute_script(js)
|
96
|
+
end
|
97
|
+
|
98
|
+
def master_file_exists?(test_root)
|
99
|
+
filename = DomGlancy.master_filename(test_root)
|
100
|
+
result = File.exist?(filename)
|
101
|
+
msg = result ? '' : make_missing_master_failure_report(test_root)
|
102
|
+
[result, msg]
|
103
|
+
end
|
104
|
+
|
105
|
+
def make_missing_master_failure_report(test_root)
|
106
|
+
msg = ["\n------- DOM Comparison Failure ------"]
|
107
|
+
msg << "Master file does not exist. To make a new master from"
|
108
|
+
msg << "the current page, use this command:"
|
109
|
+
msg << "\t#{blessing_copy_string(test_root)}"
|
110
|
+
msg<< "-------------------------------------"
|
111
|
+
|
112
|
+
msg.join("\n")
|
113
|
+
end
|
114
|
+
|
115
|
+
def purge_old_files_before_test(test_root)
|
116
|
+
File.delete DomGlancy.current_filename(test_root) if File.exist?(DomGlancy.current_filename(test_root))
|
117
|
+
|
118
|
+
filename_pattern = File.join(DomGlancy.diff_file_location, "#{test_root}__*__diff.yaml")
|
119
|
+
Dir[filename_pattern].each { |file| file.delete(file) if File.exist?(file) }
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module DomGlancy
|
2
|
+
|
3
|
+
class DOMElement
|
4
|
+
## element looks like this in archive.
|
5
|
+
# {"id"=>"", "height"=>238, "visible"=>true, "tag"=>"DIV", "width"=>720, "class"=>"grid", "left"=>43, "top"=>14}
|
6
|
+
|
7
|
+
attr_accessor :id
|
8
|
+
attr_accessor :tag
|
9
|
+
attr_accessor :left
|
10
|
+
attr_accessor :top
|
11
|
+
attr_accessor :height
|
12
|
+
attr_accessor :width
|
13
|
+
attr_accessor :klass
|
14
|
+
attr_accessor :visible
|
15
|
+
attr_accessor :style
|
16
|
+
attr_accessor :similarity
|
17
|
+
|
18
|
+
def initialize(h = {})
|
19
|
+
@tag = h[:tag] || h['tag']
|
20
|
+
@left = h[:left] || h['left']
|
21
|
+
@top = h[:top] || h['top']
|
22
|
+
@height = h[:height] || h['height']
|
23
|
+
@width = h[:width] || h['width']
|
24
|
+
@klass = h[:class] || h['class']
|
25
|
+
@id = h[:id] || h['id']
|
26
|
+
@style = h[:style] || h['style']
|
27
|
+
@visible = h[:visible] || h['visible']
|
28
|
+
@similarity = h[:similarity] || h['similarity'] || 15
|
29
|
+
end
|
30
|
+
|
31
|
+
def same_element?(anOther)
|
32
|
+
same = same_tag?(anOther) &&
|
33
|
+
same_id?(anOther) &&
|
34
|
+
same_class?(anOther)
|
35
|
+
end
|
36
|
+
|
37
|
+
def all_same?(anOther)
|
38
|
+
same = same_element?(anOther) &&
|
39
|
+
similar_size?(anOther, 0) &&
|
40
|
+
similar_location?(anOther, 0) &&
|
41
|
+
same_size?(anOther) &&
|
42
|
+
same_visibility?(anOther)
|
43
|
+
end
|
44
|
+
|
45
|
+
def close_enough?(anOther)
|
46
|
+
r = same_element?(anOther) &&
|
47
|
+
similar_location?(anOther, @similarity) &&
|
48
|
+
similar_size?(anOther, @similarity) &&
|
49
|
+
same_style?(anOther) &&
|
50
|
+
same_visibility?(anOther)
|
51
|
+
end
|
52
|
+
|
53
|
+
def similar_size?(anOther, similarity = 0)
|
54
|
+
similar = (@height - anOther.height).abs <= similarity
|
55
|
+
similar && (@width - anOther.width).abs <= similarity
|
56
|
+
end
|
57
|
+
|
58
|
+
def similar_location?(anOther, similarity = 0)
|
59
|
+
similar = (@top - anOther.top).abs <= similarity
|
60
|
+
similar && (@left - anOther.left).abs <= similarity
|
61
|
+
end
|
62
|
+
|
63
|
+
def same_tag?(anOther)
|
64
|
+
@tag == anOther.tag
|
65
|
+
end
|
66
|
+
|
67
|
+
def same_location?(anOther)
|
68
|
+
(@left == anOther.left) && (@top == anOther.top)
|
69
|
+
end
|
70
|
+
|
71
|
+
def same_size?(anOther)
|
72
|
+
(@height == anOther.height) && (@width == anOther.width)
|
73
|
+
end
|
74
|
+
|
75
|
+
def same_class?(anOther)
|
76
|
+
@klass == anOther.klass
|
77
|
+
end
|
78
|
+
|
79
|
+
def same_id?(anOther)
|
80
|
+
@id == anOther.id
|
81
|
+
end
|
82
|
+
|
83
|
+
def same_visibility?(anOther)
|
84
|
+
@visible == anOther.visible
|
85
|
+
end
|
86
|
+
|
87
|
+
def same_style?(anOther)
|
88
|
+
@style == anOther.style
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module DomGlancy
|
2
|
+
|
3
|
+
@master_file_location = nil
|
4
|
+
@diff_file_location = nil
|
5
|
+
@current_file_location = nil
|
6
|
+
|
7
|
+
def self.master_file_location=(location)
|
8
|
+
@master_file_location = location
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.master_file_location
|
12
|
+
@master_file_location
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.diff_file_location=(location)
|
16
|
+
@diff_file_location = location
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.diff_file_location
|
20
|
+
@diff_file_location
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.current_file_location=(location)
|
24
|
+
@current_file_location = location
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.current_file_location
|
28
|
+
@current_file_location
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.create_comparison_directories
|
32
|
+
::FileUtils.mkdir_p(@master_file_location)
|
33
|
+
::FileUtils.mkdir_p(@diff_file_location)
|
34
|
+
::FileUtils.mkdir_p(@current_file_location)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.master_filename(test_root)
|
38
|
+
File.join(self.master_file_location, "#{test_root}_master.yaml")
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.current_filename(test_root)
|
42
|
+
File.join(self.current_file_location, "#{test_root}.yaml")
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.diff_filename(test_root)
|
46
|
+
File.join(self.diff_file_location, "#{test_root}_diff.html")
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module DomGlancy
|
2
|
+
|
3
|
+
def generate_svg(rectangles)
|
4
|
+
width, height = get_window_size_from_rectangles(rectangles)
|
5
|
+
s = svg_start(width, height)
|
6
|
+
|
7
|
+
rectangles.each do |rectangle|
|
8
|
+
rectangle_string = " <rect id='#{rectangle[:js_id]}' x = '#{rectangle['left']}' y = '#{rectangle['top']}' width = '#{rectangle['width']}' height = '#{rectangle['height']}' fill = '#{rectangle[:fill]}' stroke = '#{rectangle[:stroke]}' stroke-width = '#{rectangle[:stroke_width]}' fill-opacity = '#{rectangle[:opacity]}' />\n"
|
9
|
+
s += rectangle_string
|
10
|
+
end
|
11
|
+
|
12
|
+
s += svg_end
|
13
|
+
s += "\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_window_size_from_rectangles(rectangles)
|
17
|
+
width = 0
|
18
|
+
height = 0
|
19
|
+
|
20
|
+
rectangles.each do |rectangle|
|
21
|
+
rectangle_right = rectangle['left'].to_i + rectangle['width'].to_i
|
22
|
+
rectangle_bottom = rectangle['top'].to_i + rectangle['height'].to_i
|
23
|
+
width = rectangle_right if rectangle_right > width
|
24
|
+
height = rectangle_bottom if rectangle_bottom > height
|
25
|
+
end
|
26
|
+
|
27
|
+
[width, height]
|
28
|
+
end
|
29
|
+
|
30
|
+
def svg_start(width, height)
|
31
|
+
s = ["<?xml version='1.0' standalone='no'?>"]
|
32
|
+
s << " <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>"
|
33
|
+
s << " <svg version = '1.1' width='#{width}px' height='#{height}px' border='2px' style='background-color:#FFFFFF;border:1px solid black;'>"
|
34
|
+
s << ''
|
35
|
+
|
36
|
+
s.join("\n")
|
37
|
+
end
|
38
|
+
|
39
|
+
def svg_end
|
40
|
+
s = [' </svg>']
|
41
|
+
s << ''
|
42
|
+
|
43
|
+
s.join("\n")
|
44
|
+
end
|
45
|
+
|
46
|
+
def format__not_in_master
|
47
|
+
{
|
48
|
+
:stroke => 'blue',
|
49
|
+
:fill => 'white',
|
50
|
+
:stroke_width => '1',
|
51
|
+
:opacity => '0.5'
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def format__not_in_current
|
56
|
+
{
|
57
|
+
:stroke => 'red',
|
58
|
+
:fill => 'white',
|
59
|
+
:stroke_width => '1',
|
60
|
+
:opacity => '0.5'
|
61
|
+
}
|
62
|
+
end
|
63
|
+
def format__same_but_different
|
64
|
+
{
|
65
|
+
:stroke => 'orange',
|
66
|
+
:fill => 'white',
|
67
|
+
:stroke_width => '1',
|
68
|
+
:opacity => '0.5'
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
data/lib/dom_glancy.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module PageObjects
|
2
|
+
module DomGlancy
|
3
|
+
class ConfigPage < ViewerPage
|
4
|
+
path '/dom_glancy/config'
|
5
|
+
|
6
|
+
def master
|
7
|
+
node.find("#js-config_master").text
|
8
|
+
end
|
9
|
+
|
10
|
+
def current
|
11
|
+
node.find("#js-config_current").text
|
12
|
+
end
|
13
|
+
|
14
|
+
def diffs
|
15
|
+
node.find("#js-config_diffs").text
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module PageObjects
|
2
|
+
module DomGlancy
|
3
|
+
class ShowPage < ViewerPage
|
4
|
+
|
5
|
+
collection :not_master, :locator => "#js--not_master", :item_locator => 'table tbody tr'
|
6
|
+
collection :not_current, :locator => "#js--not_current", :item_locator => 'table tbody tr'
|
7
|
+
collection :changed, :locator => "#js--changed", :item_locator => 'table tbody tr'
|
8
|
+
|
9
|
+
def bless!
|
10
|
+
node.click_button 'Bless these differences'
|
11
|
+
IndexPage.new
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|