slack_page_speed 0.0.6 → 0.0.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bd5929ded51785604e7852c132a394a3d0169f46
4
- data.tar.gz: 93c7ec0227679faa615986fc8affa881473fbbd4
3
+ metadata.gz: e471a023a7b3da86129fb1778186644208c0174e
4
+ data.tar.gz: b8b8233436752ed9bb85d1c2ce27f795ea1e4782
5
5
  SHA512:
6
- metadata.gz: df9dbf064dd22ab48eba98b2ab9b14af36f7449af247d0a1161f421ac0646a4810c07194f810f647e1c0f6c64a5d16d7dfebe60e13dae175fd2e1c6898f9189c
7
- data.tar.gz: d3fc00402fffedd65862bb70bd15524a68eac2a6c33865d381479fbef2facf1194920ab7c19d8ed7568e23aaf2fe995b171c16b95a0a2321fa91fd9a9ade2a20
6
+ metadata.gz: ee04bfebdb8aaa77d94e04c7535a2f4003d77094dc5e62c97743705192520cd86b4dc08b8d27d5c16028d1a4b6afdad355f2545a86dfc54281cab273658e9f11
7
+ data.tar.gz: f418d704cb4f9903728705a1b2b3fdfbdf7e6bd89ff3f7855e78c7837c66e0eac4ce8e71835a7eab67644b1d0006b88464ae8c025ee57c5f2dee29b43d614c49
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- raise 'you need to populate configuration.yml first' unless (File.exists?('./configuration.yml'))
4
3
  require 'slack_page_speed'
4
+ ARGV[0] == 'configure' ? SlackPageSpeed.new.configure : SlackPageSpeed.new.main
@@ -2,29 +2,26 @@ require 'httparty'
2
2
  require 'json'
3
3
  require 'yaml'
4
4
 
5
- def configure
6
- puts "hi"
7
- end
8
-
9
-
10
- configuration_info = YAML.load_file('configuration.yml')
11
- @slack_post_url = configuration_info['slack_url']
12
-
13
- HTTParty::Basement.default_options.update(verify: false)
14
- @pagespeed_api_key = configuration_info['pagespeed_api_key']
15
- @webpagetest_api_key = configuration_info['webpagetest_api_key']
16
- @slack_post_url = configuration_info['slack_url']
17
- @history_file = './pagespeed_history.txt'
18
- @slack_channel = configuration_info['slack_channel']
19
- @slack_username = configuration_info['slack_username']
20
- @slack_bot_emoji = configuration_info['slack_bot_emoji']
21
- @improvement_emoji = configuration_info['improvement_emoji']
22
- @minimal_change_emoji = configuration_info['minimal_change_emoji']
23
- @regression_emoji = configuration_info['regression_emoji']
24
- @domain = configuration_info['domain']
25
- @message = configuration_info['include_timestamp'] ? "Page performance scores for #{Date.today.strftime('%d/%m/%Y')}. \n" : ''
26
- @threshold = configuration_info['threshold'].to_i
27
- @results = {}
5
+ class SlackPageSpeed
6
+ def main
7
+ configuration_info = YAML.load_file('configuration.yml')
8
+ @slack_post_url = configuration_info['slack_url']
9
+
10
+ HTTParty::Basement.default_options.update(verify: false)
11
+ @pagespeed_api_key = configuration_info['pagespeed_api_key']
12
+ @webpagetest_api_key = configuration_info['webpagetest_api_key']
13
+ @slack_post_url = configuration_info['slack_url']
14
+ @history_file = './pagespeed_history.txt'
15
+ @slack_channel = configuration_info['slack_channel']
16
+ @slack_username = configuration_info['slack_username']
17
+ @slack_bot_emoji = configuration_info['slack_bot_emoji']
18
+ @improvement_emoji = configuration_info['improvement_emoji']
19
+ @minimal_change_emoji = configuration_info['minimal_change_emoji']
20
+ @regression_emoji = configuration_info['regression_emoji']
21
+ @domain = configuration_info['domain']
22
+ @message = configuration_info['include_timestamp'] ? "Page performance scores for #{Date.today.strftime('%d/%m/%Y')}. \n" : ''
23
+ @threshold = configuration_info['threshold'].to_i
24
+ @results = {}
28
25
  # @page_list = %w(
29
26
  # credit-cards/
30
27
  # life-insurance/
@@ -34,167 +31,196 @@ HTTParty::Basement.default_options.update(verify: false)
34
31
  # car-insurance/
35
32
  # Homepage
36
33
  # )
37
- @page_list = configuration_info['page_list']
34
+ @page_list = configuration_info['page_list']
38
35
 
39
36
  # @run_results = [{}, {}, {}]
40
- @run_results = [{}]
41
- @page_list.each do |page|
42
- search_string = page.gsub('-', '+').gsub('/', '')
43
- search_string = search_string + '+switch' if page == 'energy/'
44
- search_string = 'compare+the+market' if page == 'Homepage'
45
- @results[page] = { search_string: search_string }
46
- @run_results.each do |run_result|
47
- run_result[page] = { search_string: search_string }
48
- end
49
- end
37
+ @run_results = [{}]
38
+ @page_list.each do |page|
39
+ search_string = page.gsub('-', '+').gsub('/', '')
40
+ search_string = search_string + '+switch' if page == 'energy/'
41
+ search_string = 'compare+the+market' if page == 'Homepage'
42
+ @results[page] = { search_string: search_string }
43
+ @run_results.each do |run_result|
44
+ run_result[page] = { search_string: search_string }
45
+ end
46
+ end
50
47
 
51
48
  # Gets google page rank
52
- def get_gpr(page, search_string, iteration)
53
- puts page
54
- response = JSON.parse(HTTParty.get("https://www.googleapis.com/customsearch/v1element?key=#{@pagespeed_api_key}&rsz=filtered_cse&num=10&hl=en&prettyPrint=false&source=gcsc&gss=.com&q=#{search_string}&sort=&googlehost=www.google.co.uk&oq=#{search_string}&gs_l=partner.12...31030.31885.0.34635.7.7.0.0.0.0.73.428.7.7.0.gsnos%2Cn%3D13...0.864j151518j7..1ac.1.25.partner..7.0.0.-WiGDitO8Y8&callback=google.search.Search.apiary19818&nocache=1502961217931").body.chomp[49..-3])
55
- begin
56
- @run_results[iteration][page][:rank] = response['results'].index { |result_property| result_property['url'].include? 'comparethemarket.com' } + 1
57
- rescue NoMethodError => e
58
- puts "Not on the front page of Google results for '#{page}'.\nResults were: \n"
59
- response['results'].each { |result| puts result['url'] }
60
- raise e
61
- end
62
- end
49
+ def get_gpr(page, search_string, iteration)
50
+ puts page
51
+ response = JSON.parse(HTTParty.get("https://www.googleapis.com/customsearch/v1element?key=#{@pagespeed_api_key}&rsz=filtered_cse&num=10&hl=en&prettyPrint=false&source=gcsc&gss=.com&q=#{search_string}&sort=&googlehost=www.google.co.uk&oq=#{search_string}&gs_l=partner.12...31030.31885.0.34635.7.7.0.0.0.0.73.428.7.7.0.gsnos%2Cn%3D13...0.864j151518j7..1ac.1.25.partner..7.0.0.-WiGDitO8Y8&callback=google.search.Search.apiary19818&nocache=1502961217931").body.chomp[49..-3])
52
+ begin
53
+ @run_results[iteration][page][:rank] = response['results'].index { |result_property| result_property['url'].include? 'comparethemarket.com' } + 1
54
+ rescue NoMethodError => e
55
+ puts "Not on the front page of Google results for '#{page}'.\nResults were: \n"
56
+ response['results'].each { |result| puts result['url'] }
57
+ raise e
58
+ end
59
+ end
63
60
 
64
61
  # Gets google pagespeed score for a 'page'
65
- def get_gps_score(page, strategy, iteration)
66
- response = HTTParty.get("https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url=#{@domain + page.gsub('Homepage', '') + '?src=TSTT'}&strategy=#{strategy}&key=#{@pagespeed_api_key}")
67
- unless response.response.code == '200' && JSON.parse(response.body)['responseCode'] != '400'
68
- puts response
69
- raise "Couldn't get Google PageSpeed score for #{page}"
70
- end
71
- score = JSON.parse(response.body)['ruleGroups']['SPEED']['score']
72
- @run_results[iteration][page][strategy.to_sym] = score
73
- end
62
+ def get_gps_score(page, strategy, iteration)
63
+ response = HTTParty.get("https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url=#{@domain + page.gsub('Homepage', '') + '?src=TSTT'}&strategy=#{strategy}&key=#{@pagespeed_api_key}")
64
+ unless response.response.code == '200' && JSON.parse(response.body)['responseCode'] != '400'
65
+ puts response
66
+ raise "Couldn't get Google PageSpeed score for #{page}"
67
+ end
68
+ score = JSON.parse(response.body)['ruleGroups']['SPEED']['score']
69
+ @run_results[iteration][page][strategy.to_sym] = score
70
+ end
74
71
 
75
72
  # runs a new WebPageTest test based on the url supplied
76
- def start_wpt_test(page, iteration)
77
- response = HTTParty.get("http://www.webpagetest.org/runtest.php?url=#{@domain + page.gsub('Homepage', '') + '?src=TSTT'}&location=Dulles.3G&f=json&fvonly=1&k=#{@webpagetest_api_key}")
78
- raise "Couldn't get WebPageTest score for #{page}" unless response.response.code == '200'
79
- @run_results[iteration][page][:results_url] = JSON.parse(response.body)['data']['jsonUrl']
80
- end
73
+ def start_wpt_test(page, iteration)
74
+ response = HTTParty.get("http://www.webpagetest.org/runtest.php?url=#{@domain + page.gsub('Homepage', '') + '?src=TSTT'}&location=Dulles.3G&f=json&fvonly=1&k=#{@webpagetest_api_key}")
75
+ raise "Couldn't get WebPageTest score for #{page}" unless response.response.code == '200'
76
+ @run_results[iteration][page][:results_url] = JSON.parse(response.body)['data']['jsonUrl']
77
+ end
81
78
 
82
79
  # waits until the status of the run at 'results_url' is 200 (test finished)
83
- def wait_for_wpt_results(page, result_url, iteration)
84
- 361.times do
85
- @response = HTTParty.get(result_url)
86
- puts "#{JSON.parse(@response.body)['statusText']} for #{page}"
87
- break if JSON.parse(@response.body)['statusCode'] == 200
88
- sleep 10
89
- end
90
- @run_results[iteration][page][:speed_index] = (JSON.parse(@response.body)['data']['runs']['1']['firstView']['SpeedIndex'].to_f / 1000).round(2)
91
- end
80
+ def wait_for_wpt_results(page, result_url, iteration)
81
+ 361.times do
82
+ @response = HTTParty.get(result_url)
83
+ puts "#{JSON.parse(@response.body)['statusText']} for #{page}"
84
+ break if JSON.parse(@response.body)['statusCode'] == 200
85
+ sleep 10
86
+ end
87
+ @run_results[iteration][page][:speed_index] = (JSON.parse(@response.body)['data']['runs']['1']['firstView']['SpeedIndex'].to_f / 1000).round(2)
88
+ end
92
89
 
93
90
  # Send a slack message with all the scores
94
- def slack_notify(message)
95
- HTTParty.post(@slack_post_url,
96
- body: { 'channel': "##{@slack_channel}", 'icon_emoji': @slack_bot_emoji, 'username': @slack_username, 'text': message }.to_json,
97
- headers: { 'Content-Type': 'application/json',
98
- 'Accept': 'application/json' })
99
- end
100
-
101
- def get_old_score(latest_score, page, score_key)
102
- threshold = score_key == :rank ? 0 : @threshold
103
- comparison_message = ''
104
- if File.exist?(@history_file) && JSON.parse(File.read(@history_file)).keys.include?(page)
105
- # We want the pagespeed score to be greater than before,
106
- # but we want the speed index to be less than.
107
- compare_operator = (score_key == :speed_index || score_key == :rank) ? :> : :<
108
- # Open file that stores the history of the latest scores
109
- file = File.open(@history_file, 'r')
110
- # Find the value of the score of the page we want
111
- old_score = JSON.parse(file.read)[page][score_key.to_s]
112
- # Check if it's within the acceptable threshold, otherwise,
113
- # check if it's greater than or less than (depending on what type of score it is)
114
- # and add the relevant emoji
115
- comparison_message = " (was #{old_score})"
116
- if latest_score.to_f.between?(old_score.to_f - threshold, old_score.to_f + threshold)
117
- comparison_message += " #{@minimal_change_emoji}"
118
- elsif latest_score.to_f.send(compare_operator, old_score.to_f)
119
- comparison_message += " #{@regression_emoji}"
120
- else
121
- comparison_message += " #{@improvement_emoji}"
91
+ def slack_notify(message)
92
+ HTTParty.post(@slack_post_url,
93
+ body: { 'channel': "##{@slack_channel}", 'icon_emoji': @slack_bot_emoji, 'username': @slack_username, 'text': message }.to_json,
94
+ headers: { 'Content-Type': 'application/json',
95
+ 'Accept': 'application/json' })
122
96
  end
123
- end
124
- comparison_message
125
- end
126
97
 
127
- def write_new_scores
128
- file = File.open(@history_file, 'w+')
98
+ def get_old_score(latest_score, page, score_key)
99
+ threshold = score_key == :rank ? 0 : @threshold
100
+ comparison_message = ''
101
+ if File.exist?(@history_file) && JSON.parse(File.read(@history_file)).keys.include?(page)
102
+ # We want the pagespeed score to be greater than before,
103
+ # but we want the speed index to be less than.
104
+ compare_operator = (score_key == :speed_index || score_key == :rank) ? :> : :<
105
+ # Open file that stores the history of the latest scores
106
+ file = File.open(@history_file, 'r')
107
+ # Find the value of the score of the page we want
108
+ old_score = JSON.parse(file.read)[page][score_key.to_s]
109
+ # Check if it's within the acceptable threshold, otherwise,
110
+ # check if it's greater than or less than (depending on what type of score it is)
111
+ # and add the relevant emoji
112
+ comparison_message = " (was #{old_score})"
113
+ if latest_score.to_f.between?(old_score.to_f - threshold, old_score.to_f + threshold)
114
+ comparison_message += " #{@minimal_change_emoji}"
115
+ elsif latest_score.to_f.send(compare_operator, old_score.to_f)
116
+ comparison_message += " #{@regression_emoji}"
117
+ else
118
+ comparison_message += " #{@improvement_emoji}"
119
+ end
120
+ end
121
+ comparison_message
122
+ end
129
123
 
130
- # Clear the file
131
- file.truncate(0)
132
- file.write(@results.to_json)
133
- file.close
134
- end
124
+ def write_new_scores
125
+ file = File.open(@history_file, 'w+')
126
+
127
+ # Clear the file
128
+ file.truncate(0)
129
+ file.write(@results.to_json)
130
+ file.close
131
+ end
135
132
 
136
133
  # ==========
137
134
  # RUN SCRIPT
138
135
  # ==========
139
136
 
140
137
  # This kicks off a WebPageTest test for every page in the '@page_list' array
141
- @page_list.each do |page|
142
- @run_results.length.times do |iteration|
143
- start_wpt_test(page, iteration)
144
- # get_gpr(page, @results[page][:search_string], iteration)
145
- end
146
- end
138
+ @page_list.each do |page|
139
+ @run_results.length.times do |iteration|
140
+ start_wpt_test(page, iteration)
141
+ # get_gpr(page, @results[page][:search_string], iteration)
142
+ end
143
+ end
147
144
 
148
145
  # Waiting for WebPageTest results and storing them
149
- @page_list.reverse_each do |page|
150
- # This collates the results after all tests have finished
151
- @run_results.length.times do |iteration|
152
- wait_for_wpt_results(page, @run_results[iteration][page][:results_url], iteration)
153
- end
146
+ @page_list.reverse_each do |page|
147
+ # This collates the results after all tests have finished
148
+ @run_results.length.times do |iteration|
149
+ wait_for_wpt_results(page, @run_results[iteration][page][:results_url], iteration)
150
+ end
151
+
152
+ # Average all the GPS scores
153
+ @run_results.length.times do |iteration|
154
+ get_gps_score(page, 'desktop', iteration)
155
+ get_gps_score(page, 'mobile', iteration)
156
+ end
157
+
158
+ # Reset the temporary results array
159
+ # @results[page][:rank] = []
160
+ @results[page][:speed_index] = []
161
+ @results[page][:desktop] = []
162
+ @results[page][:mobile] = []
163
+
164
+ # Add all results to an array of results for each numerical result type
165
+ @run_results.each do |result|
166
+ # @results[page][:rank].push(result[page][:rank])
167
+ @results[page][:speed_index].push(result[page][:speed_index])
168
+ @results[page][:desktop].push(result[page][:desktop])
169
+ @results[page][:mobile].push(result[page][:mobile])
170
+ end
171
+
172
+ # Calculate the mean speed, desktop and mobile scores, and the mode search ranking
173
+ # @results[page][:rank] = @results[page][:rank].max_by { |i| @results[page][:rank].count(i) }
174
+ @results[page][:desktop] = @results[page][:desktop].max_by { |i| @results[page][:desktop].count(i) }
175
+ @results[page][:mobile] = @results[page][:mobile].max_by { |i| @results[page][:mobile].count(i) }
176
+ @results[page][:speed_index] = (@results[page][:speed_index].inject(:+)/@run_results.length).round(2)
177
+
178
+ # Build the slack message
179
+ puts @results if ENV['logging'] == 'true'
180
+ @message += "\n*" + page + ':*'
181
+ @message += "\n desktop score: " + @results[page][:desktop].to_s
182
+ @message += get_old_score(@results[page][:desktop], page, :desktop)
183
+ @message += "\n mobile score: " + @results[page][:mobile].to_s
184
+ @message += get_old_score(@results[page][:mobile], page, :mobile)
185
+ @message += "\n SpeedIndex: " + @results[page][:speed_index].to_s
186
+ @message += get_old_score(@results[page][:speed_index].to_f, page, :speed_index) + "\n"
187
+ # @message += "\n Google Search Rank: " + @results[page][:rank].to_s
188
+ # @message += get_old_score(@results[page][:rank].to_f, page, :rank) + "\n"
189
+ end
154
190
 
155
- # Average all the GPS scores
156
- @run_results.length.times do |iteration|
157
- get_gps_score(page, 'desktop', iteration)
158
- get_gps_score(page, 'mobile', iteration)
191
+ # Add an '@here' to the slack notification if any score has regressed
192
+ @message += ' <!here> Something is worse than last time!' if @message.include?(@regression_emoji)
193
+ puts @message
194
+ slack_notify(@message)
195
+ # Create the scores history file if this is the first run
196
+ File.new(@history_file, 'w') unless File.exist?(@history_file)
197
+ write_new_scores
159
198
  end
160
199
 
161
- # Reset the temporary results array
162
- # @results[page][:rank] = []
163
- @results[page][:speed_index] = []
164
- @results[page][:desktop] = []
165
- @results[page][:mobile] = []
166
-
167
- # Add all results to an array of results for each numerical result type
168
- @run_results.each do |result|
169
- # @results[page][:rank].push(result[page][:rank])
170
- @results[page][:speed_index].push(result[page][:speed_index])
171
- @results[page][:desktop].push(result[page][:desktop])
172
- @results[page][:mobile].push(result[page][:mobile])
200
+ def configure
201
+ config_file = File.open('configuration.yml', 'w+')
202
+ config_file.write("""---
203
+ ##############
204
+ ## Required ##
205
+ ##############
206
+ slack_url: 'https://hooks.slack.com/services/foo/bar/baz' # Set up an incoming webhook for your Slack account here https://get.slack.help/hc/en-us/articles/115005265063-Incoming-WebHooks-for-Slack#set-up-incoming-webhooks
207
+ pagespeed_api_key: 'Get an Google Search API key from https://developers.google.com/webmaster-tools/search-console-api/v1/configure'
208
+ webpagetest_api_key: 'Get a WebPageTest API key from https://www.webpagetest.org/getkey.php'
209
+ slack_channel: 'Select existing Slack channel to post to'
210
+ domain: 'https://www.google.com/' # Change this to the domain you want to test
211
+ page_list: # Change these to the pages you want to test on your domain
212
+ - 'drive/'
213
+ - 'calendar/'
214
+
215
+ #############
216
+ ## Default ##
217
+ #############
218
+ slack_username: 'PageSpeed BOT' # Change this to any name you like
219
+ slack_bot_emoji: ':zap:'
220
+ improvement_emoji: ':racehorse:'
221
+ minimal_change_emoji: ':no_mouth:'
222
+ regression_emoji: ':no-entry:'
223
+ include_timestamp: true
224
+ threshold: '2'""")
173
225
  end
174
-
175
- # Calculate the mean speed, desktop and mobile scores, and the mode search ranking
176
- # @results[page][:rank] = @results[page][:rank].max_by { |i| @results[page][:rank].count(i) }
177
- @results[page][:desktop] = @results[page][:desktop].max_by { |i| @results[page][:desktop].count(i) }
178
- @results[page][:mobile] = @results[page][:mobile].max_by { |i| @results[page][:mobile].count(i) }
179
- @results[page][:speed_index] = (@results[page][:speed_index].inject(:+)/@run_results.length).round(2)
180
-
181
- # Build the slack message
182
- puts @results if ENV['logging'] == 'true'
183
- @message += "\n*" + page + ':*'
184
- @message += "\n desktop score: " + @results[page][:desktop].to_s
185
- @message += get_old_score(@results[page][:desktop], page, :desktop)
186
- @message += "\n mobile score: " + @results[page][:mobile].to_s
187
- @message += get_old_score(@results[page][:mobile], page, :mobile)
188
- @message += "\n SpeedIndex: " + @results[page][:speed_index].to_s
189
- @message += get_old_score(@results[page][:speed_index].to_f, page, :speed_index) + "\n"
190
- # @message += "\n Google Search Rank: " + @results[page][:rank].to_s
191
- # @message += get_old_score(@results[page][:rank].to_f, page, :rank) + "\n"
192
- end
193
-
194
- # Add an '@here' to the slack notification if any score has regressed
195
- @message += ' <!here> Something is worse than last time!' if @message.include?(@regression_emoji)
196
- puts @message
197
- slack_notify(@message)
198
- # Create the scores history file if this is the first run
199
- File.new(@history_file, 'w') unless File.exist?(@history_file)
200
- write_new_scores
226
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slack_page_speed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abi Travers, Andy Barnett, Dan Clissold, Tom Dane