likadan 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/likadan_runner.rb +20 -4
- data/lib/likadan_uploader.rb +23 -7
- data/lib/public/likadan-runner.js +73 -7
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bd6cec6d554529beb5c4492107883d5e80054d0
|
4
|
+
data.tar.gz: 11f2cea49136b6850c34a071f749ec66ea65228c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed89a22c58e98b897439ea9e473a37ffc61bf6c477e8ff715633d546c2f6279624797c2070f8f73061abd3430cde6098078483149d989cde37f7571b812ab778
|
7
|
+
data.tar.gz: 546df3614ba330b8675f5034b34634557546c528cce79ff19b529888e2b2de1104504aa0b0163db3030877ffa80a083f971613048ff137f9955bd15891728dd4
|
data/lib/likadan_runner.rb
CHANGED
@@ -17,8 +17,18 @@ def resolve_viewports(example)
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
driver = Selenium::WebDriver.for LikadanUtils.config['driver'].to_sym
|
21
20
|
begin
|
21
|
+
driver = Selenium::WebDriver.for LikadanUtils.config['driver'].to_sym
|
22
|
+
rescue Selenium::WebDriver::Error::WebDriverError
|
23
|
+
# "unable to obtain stable firefox connection in 60 seconds"
|
24
|
+
#
|
25
|
+
# This seems to happen sporadically for some versions of Firefox, so we want
|
26
|
+
# to retry it in case it will work the second time around.
|
27
|
+
driver = Selenium::WebDriver.for LikadanUtils.config['driver'].to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
begin
|
31
|
+
driver.manage.timeouts.script_timeout = 3 # move to config?
|
22
32
|
driver.navigate.to LikadanUtils.construct_url('/')
|
23
33
|
|
24
34
|
# Check for errors during startup
|
@@ -33,7 +43,13 @@ begin
|
|
33
43
|
driver.manage.window.resize_to(viewport['width'], viewport['height'])
|
34
44
|
|
35
45
|
# Render the example
|
36
|
-
|
46
|
+
|
47
|
+
script = <<-EOS
|
48
|
+
var doneFunc = arguments[arguments.length - 1];
|
49
|
+
window.likadan.renderCurrent(doneFunc);
|
50
|
+
EOS
|
51
|
+
rendered = driver.execute_async_script(script)
|
52
|
+
|
37
53
|
if error = rendered['error']
|
38
54
|
puts <<-EOS
|
39
55
|
Error while rendering "#{current['name']}" @#{viewport['name']}:
|
@@ -56,8 +72,8 @@ begin
|
|
56
72
|
cropped = ChunkyPNG::Image.from_file(output_file)
|
57
73
|
cropped.crop!(rendered['left'],
|
58
74
|
rendered['top'],
|
59
|
-
rendered['width'],
|
60
|
-
rendered['height'])
|
75
|
+
[rendered['width'], 1].max,
|
76
|
+
[rendered['height'], 1].max)
|
61
77
|
cropped.save(output_file)
|
62
78
|
|
63
79
|
print "Checking \"#{current['name']}\" at [#{viewport['name']}]... "
|
data/lib/likadan_uploader.rb
CHANGED
@@ -3,22 +3,23 @@ require 's3'
|
|
3
3
|
require 'securerandom'
|
4
4
|
|
5
5
|
class LikadanUploader
|
6
|
-
|
6
|
+
BUCKET_NAME = 'likadan-diffs'
|
7
|
+
|
8
|
+
def initialize
|
7
9
|
@s3_access_key_id = LikadanUtils.config['s3_access_key_id']
|
8
10
|
@s3_secret_access_key = LikadanUtils.config['s3_secret_access_key']
|
9
11
|
end
|
10
12
|
|
11
13
|
def upload_diffs
|
12
|
-
service = S3::Service.new(access_key_id: @s3_access_key_id,
|
13
|
-
secret_access_key: @s3_secret_access_key)
|
14
14
|
current_snapshots = LikadanUtils.current_snapshots
|
15
15
|
return [] if current_snapshots[:diffs].empty?
|
16
16
|
|
17
|
-
bucket =
|
18
|
-
|
17
|
+
bucket = find_or_build_bucket
|
18
|
+
|
19
|
+
dir = SecureRandom.uuid
|
19
20
|
|
20
21
|
diff_images = current_snapshots[:diffs].map do |diff|
|
21
|
-
image = bucket.objects.build("#{diff[:name]}_#{diff[:viewport]}.png")
|
22
|
+
image = bucket.objects.build("#{dir}/#{diff[:name]}_#{diff[:viewport]}.png")
|
22
23
|
image.content = open(diff[:file])
|
23
24
|
image.content_type = 'image/png'
|
24
25
|
image.save
|
@@ -26,7 +27,7 @@ class LikadanUploader
|
|
26
27
|
diff
|
27
28
|
end
|
28
29
|
|
29
|
-
html = bucket.objects.build(
|
30
|
+
html = bucket.objects.build("#{dir}/index.html")
|
30
31
|
html.content =
|
31
32
|
ERB.new(
|
32
33
|
File.read(File.expand_path(
|
@@ -36,4 +37,19 @@ class LikadanUploader
|
|
36
37
|
html.save
|
37
38
|
html.url
|
38
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def find_or_build_bucket
|
44
|
+
service = S3::Service.new(access_key_id: @s3_access_key_id,
|
45
|
+
secret_access_key: @s3_secret_access_key)
|
46
|
+
bucket = service.buckets.find(BUCKET_NAME)
|
47
|
+
|
48
|
+
if bucket.nil?
|
49
|
+
bucket = service.buckets.build(BUCKET_NAME)
|
50
|
+
bucket.save(location: :us)
|
51
|
+
end
|
52
|
+
|
53
|
+
bucket
|
54
|
+
end
|
39
55
|
end
|
@@ -56,10 +56,80 @@ window.likadan = {
|
|
56
56
|
});
|
57
57
|
},
|
58
58
|
|
59
|
-
|
59
|
+
handleError: function(error) {
|
60
|
+
console.error(error);
|
61
|
+
return {
|
62
|
+
name: this.currentExample.name,
|
63
|
+
error: error.message
|
64
|
+
};
|
65
|
+
},
|
66
|
+
|
67
|
+
/**
|
68
|
+
* @param {Function} func The likadan.describe function from the current
|
69
|
+
* example being rendered. This function takes a callback as an argument
|
70
|
+
* that is called when it is done.
|
71
|
+
* @return {Promise}
|
72
|
+
*/
|
73
|
+
tryAsync: function(func) {
|
74
|
+
return new Promise(function(resolve, reject) {
|
75
|
+
// Saftey valve: if the function does not finish after 3s, then something
|
76
|
+
// went haywire and we need to move on.
|
77
|
+
var timeout = setTimeout(function() {
|
78
|
+
reject(new Error('Async callback was not invoked within timeout.'));
|
79
|
+
}, 3000);
|
80
|
+
|
81
|
+
// This function is called by the example when it is done executing.
|
82
|
+
var doneCallback = function(elem) {
|
83
|
+
clearTimeout(timeout);
|
84
|
+
|
85
|
+
if (!arguments.length) {
|
86
|
+
return reject(new Error(
|
87
|
+
'The async done callback expects the rendered element as an ' +
|
88
|
+
'argument, but there were no arguments.'
|
89
|
+
));
|
90
|
+
}
|
91
|
+
|
92
|
+
resolve(elem);
|
93
|
+
};
|
94
|
+
|
95
|
+
func(doneCallback);
|
96
|
+
});
|
97
|
+
},
|
98
|
+
|
99
|
+
/**
|
100
|
+
* @param {Function} doneFunc injected by driver.execute_async_script in
|
101
|
+
* likadan_runner.rb
|
102
|
+
*/
|
103
|
+
renderCurrent: function(doneFunc) {
|
60
104
|
try {
|
61
105
|
this.clearVisibleElements();
|
62
|
-
|
106
|
+
|
107
|
+
var func = this.currentExample.func;
|
108
|
+
if (func.length) {
|
109
|
+
// The function takes an argument, which is a callback that is called
|
110
|
+
// once it is done executing. This can be used to write functions that
|
111
|
+
// have asynchronous code in them.
|
112
|
+
this.tryAsync(func).then(function(elem) {
|
113
|
+
doneFunc(this.processElem(elem));
|
114
|
+
}.bind(this)).catch(function(error) {
|
115
|
+
doneFunc(this.handleError(error));
|
116
|
+
}.bind(this));
|
117
|
+
} else {
|
118
|
+
// The function does not take an argument, so we can run it
|
119
|
+
// synchronously.
|
120
|
+
var elem = func();
|
121
|
+
doneFunc(this.processElem(elem));
|
122
|
+
}
|
123
|
+
} catch (error) {
|
124
|
+
doneFunc(this.handleError(error));
|
125
|
+
}
|
126
|
+
},
|
127
|
+
|
128
|
+
processElem: function(elem) {
|
129
|
+
try {
|
130
|
+
// TODO: elem.getDOMNode is deprecated in React, so we need to convert
|
131
|
+
// this to React.findDOMNode(elem) at some point, or push this requirement
|
132
|
+
// into the examples.
|
63
133
|
if (elem.getDOMNode) {
|
64
134
|
// Soft-dependency to React here. If the thing returned has a
|
65
135
|
// `getDOMNode` method, call it to get the real DOM node.
|
@@ -87,11 +157,7 @@ window.likadan = {
|
|
87
157
|
left: left
|
88
158
|
};
|
89
159
|
} catch (error) {
|
90
|
-
|
91
|
-
return {
|
92
|
-
name: this.currentExample.name,
|
93
|
-
error: error.message
|
94
|
-
};
|
160
|
+
return this.handleError(error);
|
95
161
|
}
|
96
162
|
}
|
97
163
|
};
|