slack_page_speed 0.0.5

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
+ SHA1:
3
+ metadata.gz: 94e85d62a708e5d1a2dc56b831040a6a58a4fe77
4
+ data.tar.gz: facf5265499c049eb238336317073efa5e6889d6
5
+ SHA512:
6
+ metadata.gz: 02e17d415d308a16aaaba034a7e00ecf22974111b1a0c2da47da46ae11d1a9642abaea92d489882b2ac5ade87fb7c49a49dcd9007f0b3fb16588acf43a7a33fa
7
+ data.tar.gz: 512af41b78d4d238b0591fae8c9a0e6330bb7ef07845231aac22a185db3b22d1d3ca37e45f34a8ac0140734e47a101e99bc9070308eb55cbe059a47794baa6c5
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ raise 'you need to populate configuration.yml first' unless (File.exists?('./configuration.yml'))
4
+ require 'slack_page_speed'
@@ -0,0 +1,200 @@
1
+ require 'httparty'
2
+ require 'json'
3
+ require 'yaml'
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 = {}
28
+ # @page_list = %w(
29
+ # credit-cards/
30
+ # life-insurance/
31
+ # energy/
32
+ # home-insurance/
33
+ # travel-insurance/
34
+ # car-insurance/
35
+ # Homepage
36
+ # )
37
+ @page_list = configuration_info['page_list']
38
+
39
+ # @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
50
+
51
+ # 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
63
+
64
+ # 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
74
+
75
+ # 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
81
+
82
+ # 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
92
+
93
+ # 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}"
122
+ end
123
+ end
124
+ comparison_message
125
+ end
126
+
127
+ def write_new_scores
128
+ file = File.open(@history_file, 'w+')
129
+
130
+ # Clear the file
131
+ file.truncate(0)
132
+ file.write(@results.to_json)
133
+ file.close
134
+ end
135
+
136
+ # ==========
137
+ # RUN SCRIPT
138
+ # ==========
139
+
140
+ # 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
147
+
148
+ # 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
154
+
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)
159
+ end
160
+
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])
173
+ 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
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slack_page_speed
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ platform: ruby
6
+ authors:
7
+ - Abi Travers, Andy Barnett, Dan Clissold, Tom Dane
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-04-25 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Discover a website's page speed scores with Google Pagespeed and WebPageTest
14
+ and notify slack with the results.
15
+ email: andrew.barnett@bglgroup.co.uk
16
+ executables:
17
+ - slack_page_speed
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/slack_page_speed
22
+ - lib/slack_page_speed.rb
23
+ homepage: http://rubygems.org/gems/slack_page_speed
24
+ licenses:
25
+ - GPL-3.0
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.5.1
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Let's get notifying!
47
+ test_files: []