cucumber-performance-generator 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +2 -0
- data/lib/cucumber-performance-generator.rb +15 -0
- data/lib/cucumber-performance-generator/functions.rb +515 -0
- data/lib/cucumber-performance-generator/hooks.rb +21 -0
- data/lib/cucumber-performance-generator/poltergeist_override.rb +74 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4a5cbf2a3db077452e39b7d32beb402324871701
|
4
|
+
data.tar.gz: bdf7e5a2cb8cb52ad4c634d2ed9d76d16322b6ae
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 70facdf1f9afda07bc0a9893fb666509f5983813982767a6874bc9f956a3636bd51eec268f6662abbd5930575b18f478bbb51b58b4385e79bdabd002e146fb48
|
7
|
+
data.tar.gz: 9eeffee9b3edc9a1aeaa7b7e753b5d8112dac1b1f2211e4cc2fc0eaf6e0782b3d47f869d51a24e960ae6ed819fd9988fa8db39581b27c6296de14f3eebf1a95c
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Andrew Moore
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'cliver'
|
2
|
+
require 'capybara/poltergeist'
|
3
|
+
|
4
|
+
require_relative 'cucumber-performance-generator/hooks.rb'
|
5
|
+
require_relative 'cucumber-performance-generator/functions.rb'
|
6
|
+
require_relative 'cucumber-performance-generator/poltergeist_override.rb'
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
options = {}
|
12
|
+
|
13
|
+
PHANTOMJS_VERSION = ['1.9.7']
|
14
|
+
PHANTOMJS_NAME = 'phantomjs'
|
15
|
+
puts Cliver::detect!((options[:path] || PHANTOMJS_NAME), *PHANTOMJS_VERSION)
|
@@ -0,0 +1,515 @@
|
|
1
|
+
#####
|
2
|
+
## Function: recursive_list_variable
|
3
|
+
## Inputs: variable (any Hash/Array/nil) prev (string of current path)
|
4
|
+
## Outputs: Flat hash (key = path, value = value)
|
5
|
+
## Description: This function creates a flat hash of the object so it can be
|
6
|
+
## easily used to paramterise the performance script.
|
7
|
+
## This is a recursive function.
|
8
|
+
#####
|
9
|
+
def recursive_list_variable(variable, prev = '')
|
10
|
+
|
11
|
+
# create the hash
|
12
|
+
data = {}
|
13
|
+
|
14
|
+
## If the variable is an array we need to use .each_with_index.
|
15
|
+
if (variable.kind_of?(Array)) then
|
16
|
+
|
17
|
+
# Loop through the items of the array
|
18
|
+
variable.each_with_index do |value, key|
|
19
|
+
# build the variable path, this is the structure of the object
|
20
|
+
variable_key = prev + '[' + key.to_s + ']'
|
21
|
+
|
22
|
+
# If the child is either an Array or Hash then it needs to be put
|
23
|
+
# back into this function.
|
24
|
+
if ((variable[key].kind_of?(Array)) || (variable[key].kind_of?(Hash))) then
|
25
|
+
data_ret = recursive_list_variable(variable[key], variable_key)
|
26
|
+
data = data_ret.merge(data)
|
27
|
+
else
|
28
|
+
# Otherwise we're at the top for this part, so assign the value to the data hash
|
29
|
+
data[variable_key] = value
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# The same code as above, but instead needs to use .each
|
34
|
+
elsif (variable.kind_of?(Hash)) then
|
35
|
+
|
36
|
+
# Loop through the items of the array
|
37
|
+
variable.each do |key, value|
|
38
|
+
|
39
|
+
# build the variable path, this is the structure of the object
|
40
|
+
variable_key = prev + '["' + key.to_s + '"]'
|
41
|
+
|
42
|
+
# If the child is either an Array or Hash then it needs to be put
|
43
|
+
# back into this function.
|
44
|
+
if ((variable[key].kind_of?(Array)) || (variable[key].kind_of?(Hash))) then
|
45
|
+
data_ret = recursive_list_variable(variable[key], variable_key)
|
46
|
+
data = data_ret.merge(data)
|
47
|
+
else
|
48
|
+
# Otherwise we're at the top for this part, so assign the value to the data hash
|
49
|
+
data[variable_key] = value
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
# If it is nil, then we need to return a hash still, this will be reworked in the future
|
54
|
+
elsif (variable.nil?)
|
55
|
+
data['nil'] = ''
|
56
|
+
end
|
57
|
+
|
58
|
+
# Return data hash
|
59
|
+
return data
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
#####
|
64
|
+
## Function: generate_performance_test_script
|
65
|
+
## Inputs: scenario object (this contains data about the scenario. i.e. name)
|
66
|
+
## Outputs: None
|
67
|
+
## Description: This will generate the load test for a step.
|
68
|
+
## => This will use phantomjs to work out which http requests were made
|
69
|
+
## => It will work out the variables being used and paramatise them in the script
|
70
|
+
## => It will create the file if it doesn't exist
|
71
|
+
#####
|
72
|
+
def generate_performance_test_script(scenario)
|
73
|
+
|
74
|
+
## the scenario object doesn't know what the current step it, this will
|
75
|
+
## work it out and structure it how we want to use it
|
76
|
+
step_name = scenario.steps.to_a[$step].name.gsub('(','').gsub(')', '').gsub(/ /, '_').capitalize
|
77
|
+
|
78
|
+
## Use a global variable to keep track of the step. As this fucntion is just
|
79
|
+
## called once per a step, so we can increase this by 1
|
80
|
+
$step = $step + 1
|
81
|
+
|
82
|
+
# get the scenario name, ( and ) can confuse regex and spaces we want as underscores
|
83
|
+
scenario_name = scenario.name.gsub('(','').gsub(')', '').gsub(/ /, '_').capitalize
|
84
|
+
|
85
|
+
# We only want to do something if there was any http traffic
|
86
|
+
if (page.driver.network_traffic.to_a.count > 0) then
|
87
|
+
|
88
|
+
perf_file_name = 'performanceTests/' + scenario_name.downcase + '.rb'
|
89
|
+
|
90
|
+
|
91
|
+
# We want to recreate the script each time it runs. This variable keeps track of it
|
92
|
+
#if (!File.file?(perf_file_name))
|
93
|
+
if ($file_not_created == true) then
|
94
|
+
# Set this to another value so we don't keep recreating the performance script
|
95
|
+
$file_not_created = false
|
96
|
+
|
97
|
+
if (!File.directory?(File.expand_path('performanceTests/').to_s)) then
|
98
|
+
Dir.mkdir(File.expand_path('performanceTests/').to_s)
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
# Lets create the basic structure of the file
|
103
|
+
file_structure = %{
|
104
|
+
|
105
|
+
# Scenario Name: #{scenario.name}
|
106
|
+
|
107
|
+
class #{scenario_name}
|
108
|
+
|
109
|
+
def initialize()
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
def v_init()
|
114
|
+
|
115
|
+
|
116
|
+
#v_init end
|
117
|
+
end
|
118
|
+
|
119
|
+
def v_action()
|
120
|
+
@curl = Curl::Easy.new
|
121
|
+
@curl.follow_location = true
|
122
|
+
@curl.enable_cookies = true
|
123
|
+
|
124
|
+
#v_action end
|
125
|
+
end
|
126
|
+
|
127
|
+
def v_end()
|
128
|
+
|
129
|
+
#v_end end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
}
|
135
|
+
|
136
|
+
# Lets write that to a file
|
137
|
+
File.open(perf_file_name, 'w') { |file| file.write(file_structure) }
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
# This bit gets complex. We record which functions were being called.
|
142
|
+
# If this is above 0 then we want to understand this fucntions as this is
|
143
|
+
# key to being able to paramertise the script
|
144
|
+
if ($function_call_name.count > 0) then
|
145
|
+
|
146
|
+
# Loop through the function calls as we only want to use the new ones
|
147
|
+
for i in $function_call_start..$function_call_name.count - 1
|
148
|
+
|
149
|
+
function_argouments = ''
|
150
|
+
#puts $function_call_arguments[i]
|
151
|
+
|
152
|
+
if (!$function_call_arguments[i].nil?)
|
153
|
+
$function_call_arguments[i].each do |key, value|
|
154
|
+
|
155
|
+
# We need to build, up the functions arguments, seperated by a string
|
156
|
+
if (function_argouments != '') then
|
157
|
+
function_argouments = function_argouments + ', '
|
158
|
+
end
|
159
|
+
if (value.class.to_s == 'String') then
|
160
|
+
|
161
|
+
# assigned the value to a temp variable.
|
162
|
+
func_value = value.to_s
|
163
|
+
# we can only parameterise the second and following functions.
|
164
|
+
if (i > 0) then
|
165
|
+
# Loop through the previous functions to the one that is current.
|
166
|
+
# This means we don't accidently assign the current function a value
|
167
|
+
# that its self returns
|
168
|
+
for i2 in 0..i - 1
|
169
|
+
# the variable $function_call_data contains the data that is returned
|
170
|
+
# from each function. However this data is nested in a hash.
|
171
|
+
# We need to get a flat structure.
|
172
|
+
value_list = recursive_list_variable($function_call_data[i2])
|
173
|
+
# Loop through the flat structure results to do a replace
|
174
|
+
# on the value with a variable
|
175
|
+
value_list.each do |data_key, data_value|
|
176
|
+
# We only want to replace values that are greater than 0 length
|
177
|
+
if (data_value.to_s.length > 0) then
|
178
|
+
# replace the actual value with the variable
|
179
|
+
func_value = func_value.gsub(/#{data_value.to_s}/i, '#{' + "genData#{i2}" + data_key + '}')
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
# concat the function_argouments, the list of arguments for the function
|
185
|
+
function_argouments = function_argouments + '"' + func_value + '"'
|
186
|
+
|
187
|
+
|
188
|
+
else
|
189
|
+
|
190
|
+
# assigned the value to a temp variable.
|
191
|
+
func_value = value.to_s
|
192
|
+
# we can only parameterise the second and following functions.
|
193
|
+
if (i > 0) then
|
194
|
+
# Loop through the previous functions to the one that is current.
|
195
|
+
# This means we don't accidently assign the current function a value
|
196
|
+
# that its self returns
|
197
|
+
for i2 in 0..i - 1
|
198
|
+
# the variable $function_call_data contains the data that is returned
|
199
|
+
# from each function. However this data is nested in a hash.
|
200
|
+
# We need to get a flat structure.
|
201
|
+
value_list = recursive_list_variable($function_call_data[i2])
|
202
|
+
# Loop through the flat structure results to do a replace
|
203
|
+
# on the value with a variable
|
204
|
+
value_list.each do |data_key, data_value|
|
205
|
+
# We only want to replace values that are greater than 0 length
|
206
|
+
if (data_value.to_s.length > 0) then
|
207
|
+
# replace the actual value with the variable
|
208
|
+
func_value = func_value.gsub(/"#{data_value.to_s}"/is, '"#{' + "genData#{i2}" + data_key + '}"')
|
209
|
+
|
210
|
+
func_value = func_value.gsub(/ "#{data_value.to_s.gsub('(', '\(').gsub(')', '\)')}"/is, ' "#{' + "genData#{i2}" + data_key + '}"')
|
211
|
+
func_value = func_value.gsub(/"#{data_value.to_s.gsub('(', '\(').gsub(')', '\)')}",/is, '"#{' + "genData#{i2}" + data_key + '}",')
|
212
|
+
func_value = func_value.gsub(/\=\>"#{data_value.to_s.gsub('(', '\(').gsub(')', '\)')}\}"/is, '=>"#{' + "genData#{i2}" + data_key + '}"}')
|
213
|
+
func_value = func_value.gsub(/\["#{data_value.to_s.gsub('(', '\(').gsub(')', '\)')}"\]/is, '["#{' + "genData#{i2}" + data_key + '}"]')
|
214
|
+
|
215
|
+
|
216
|
+
func_value = func_value.gsub(/ #{data_value.to_s.gsub('(', '\(').gsub(')', '\)')}/is, " genData#{i2}" + data_key)
|
217
|
+
func_value = func_value.gsub(/#{data_value.to_s.gsub('(', '\(').gsub(')', '\)')},/is, "genData#{i2}" + data_key + ',')
|
218
|
+
func_value = func_value.gsub(/\=\>#{data_value.to_s.gsub('(', '\(').gsub(')', '\)')}\}/is, '=>' + "genData#{i2}" + data_key + '}')
|
219
|
+
func_value = func_value.gsub(/\[#{data_value.to_s.gsub('(', '\(').gsub(')', '\)')}\]/is, '[' + "genData#{i2}" + data_key + ']')
|
220
|
+
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# concat the function_argouments, the list of arguments for the function
|
227
|
+
function_argouments = function_argouments + func_value
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
# build up the action step with the code
|
235
|
+
v_action_text = %{
|
236
|
+
|
237
|
+
genData#{i} = #{$function_call_name[i]}(#{function_argouments})
|
238
|
+
}
|
239
|
+
|
240
|
+
# write the code to the performance test script file.
|
241
|
+
write_line_to_performance_test_file(perf_file_name, v_action_text, true)
|
242
|
+
|
243
|
+
end
|
244
|
+
|
245
|
+
# Update which function we are up to.
|
246
|
+
$function_call_start = $function_call_name.count
|
247
|
+
|
248
|
+
end
|
249
|
+
|
250
|
+
|
251
|
+
# We are going to put transactions in based on the step being executed
|
252
|
+
v_action_text = %{
|
253
|
+
|
254
|
+
trans_time = start_traction("#{step_name}")
|
255
|
+
}
|
256
|
+
|
257
|
+
write_line_to_performance_test_file(perf_file_name, v_action_text, true)
|
258
|
+
|
259
|
+
prevredirect = '';
|
260
|
+
|
261
|
+
page.driver.network_traffic.each do |request|
|
262
|
+
|
263
|
+
# We only want valid http calls, not data calls (These are just managed in the front end)
|
264
|
+
if (!request.url.include? 'data:application') then
|
265
|
+
|
266
|
+
# A http request may forward onto multiple urls. We don't want each of these
|
267
|
+
# and only want the final one, as these steps wont be reproduced in the script
|
268
|
+
# as we will automatically forward
|
269
|
+
if (prevredirect == '') then
|
270
|
+
|
271
|
+
# Build up the action step for submit data
|
272
|
+
v_action_text = %{
|
273
|
+
data = {}
|
274
|
+
data["header"] = {}
|
275
|
+
}
|
276
|
+
# write this to the performance test script file
|
277
|
+
write_line_to_performance_test_file(perf_file_name, v_action_text)
|
278
|
+
|
279
|
+
# Have we got any headers for this http request?
|
280
|
+
if (request.headers.count > 0) then
|
281
|
+
|
282
|
+
# If so, let's loop through them and add them to the script
|
283
|
+
request.headers.each do |value|
|
284
|
+
# We don't want the Content-Length one, as this will differ
|
285
|
+
if (value['name'] != 'Content-Length') then
|
286
|
+
# Record the headers
|
287
|
+
v_action_text = %{
|
288
|
+
data["header"]["#{value['name']}"] = "#{value['value']}"
|
289
|
+
}
|
290
|
+
# write each header to file
|
291
|
+
write_line_to_performance_test_file(perf_file_name, v_action_text)
|
292
|
+
|
293
|
+
end
|
294
|
+
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
298
|
+
|
299
|
+
# assign the request url to a variable (notice the . and _)
|
300
|
+
request_url = request.url
|
301
|
+
|
302
|
+
# The url could contain a parameter (i.e. a title number) so we need to
|
303
|
+
# check for that and paramterise it
|
304
|
+
# So lets loop through all the function data we know
|
305
|
+
for i in 0..$function_call_data.count - 1
|
306
|
+
|
307
|
+
# Get a flat list of the hash values
|
308
|
+
value_list = recursive_list_variable($function_call_data[i])
|
309
|
+
|
310
|
+
# Loop through each of the hash values
|
311
|
+
value_list.each do |data_key, data_value|
|
312
|
+
|
313
|
+
# We don't want to include anything too small. An example is the letter M (for male)
|
314
|
+
if (data_value.to_s.length > 1) then
|
315
|
+
|
316
|
+
# We want to sure the value matches and is case sensitive
|
317
|
+
if (request_url.include? "#{CGI::escape(data_value.to_s)}")
|
318
|
+
|
319
|
+
# Replace the value in the url, but it needs to be escaped
|
320
|
+
# so is in the url format
|
321
|
+
request_url = request_url.gsub(/#{CGI::escape(data_value.to_s)}/i, '#{' + "genData#{i}" + data_key + '}')
|
322
|
+
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|
327
|
+
|
328
|
+
end
|
329
|
+
|
330
|
+
# The request can either be a GET or POST, so we need to check which type it is
|
331
|
+
if (request.method == 'POST')
|
332
|
+
|
333
|
+
# Phantomjs returns the data in a Base64 encode, let's decode it
|
334
|
+
begin
|
335
|
+
data_str = Base64.decode64(request.data)
|
336
|
+
rescue Exception=>e
|
337
|
+
raise "Are you sure you're running the custom version of phantomjs from https://github.com/mooreandrew/phantomjs ?"
|
338
|
+
end
|
339
|
+
|
340
|
+
# lets define a post_data value in the script
|
341
|
+
v_action_text = %{
|
342
|
+
data["post_data"] = {}
|
343
|
+
}
|
344
|
+
|
345
|
+
# lets write that
|
346
|
+
write_line_to_performance_test_file(perf_file_name, v_action_text)
|
347
|
+
|
348
|
+
# we have a long string of data, lets split is by &
|
349
|
+
data_str_and = data_str.split('&')
|
350
|
+
|
351
|
+
# lets loop through each of the items
|
352
|
+
data_str_and.each do |elements|
|
353
|
+
# each item contains the key and value seperated by an equal.
|
354
|
+
data_str_keyvalue = elements.split('=')
|
355
|
+
|
356
|
+
# lets unescaspe the value
|
357
|
+
post_key = CGI::unescape(data_str_keyvalue[0])
|
358
|
+
|
359
|
+
# if the value is nil, lets make it an empty string
|
360
|
+
if (data_str_keyvalue[1].nil?) then
|
361
|
+
data_str_keyvalue[1] = ''
|
362
|
+
end
|
363
|
+
|
364
|
+
# all http headers are strings, so lets make them strings in our data hash
|
365
|
+
post_value = '"' + CGI::unescape(data_str_keyvalue[1]).gsub('"', '\"') + '"'
|
366
|
+
|
367
|
+
# Lets loop through the function call data and replace any post data with parameters
|
368
|
+
for i in 0..$function_call_data.count - 1
|
369
|
+
|
370
|
+
# Get a flat list of the hash values
|
371
|
+
value_list = recursive_list_variable($function_call_data[i])
|
372
|
+
|
373
|
+
# Loop through each of the hash values
|
374
|
+
value_list.each do |data_key, data_value|
|
375
|
+
# If value from the post data identically matches the a functionc call, lets use that instead
|
376
|
+
if (CGI::unescape(data_str_keyvalue[1]).to_s == data_value.to_s) then
|
377
|
+
post_value = "genData#{i}#{data_key.to_s}"
|
378
|
+
# puts data_key.to_s + ' - ' + data_value.to_s
|
379
|
+
else
|
380
|
+
if (data_value.to_s.length > 1) then
|
381
|
+
post_value = post_value.gsub(data_value.to_s, '#{' + "genData#{i}#{data_key.to_s}" + '}')
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
end
|
387
|
+
|
388
|
+
# write the post data keys to the performance script
|
389
|
+
v_action_text = %{
|
390
|
+
data["post_data"]["#{post_key}"] = #{post_value}
|
391
|
+
}
|
392
|
+
|
393
|
+
write_line_to_performance_test_file(perf_file_name, v_action_text)
|
394
|
+
|
395
|
+
end
|
396
|
+
|
397
|
+
# write the post data to the performance script
|
398
|
+
v_action_text = %{
|
399
|
+
response = http_post(@curl, data, "#{request_url}")
|
400
|
+
}
|
401
|
+
|
402
|
+
else
|
403
|
+
# If it isn't a post, it must be a get
|
404
|
+
|
405
|
+
|
406
|
+
v_action_text = %{
|
407
|
+
response = http_get(@curl, data, "#{request_url}")
|
408
|
+
}
|
409
|
+
|
410
|
+
end
|
411
|
+
|
412
|
+
# write the http (get or post) call
|
413
|
+
write_line_to_performance_test_file(perf_file_name, v_action_text)
|
414
|
+
|
415
|
+
end
|
416
|
+
|
417
|
+
# The scripts will run with auto redirect, so we only want to check the final step, not all of them.
|
418
|
+
if (request.response_parts[request.response_parts.count - 1].redirect_url.to_s == '') then
|
419
|
+
|
420
|
+
# Lets assert to see if the response from the http call matches that we should expect
|
421
|
+
v_action_text = %{
|
422
|
+
assert_http_status(response, #{request.response_parts[request.response_parts.count -1].status})
|
423
|
+
}
|
424
|
+
|
425
|
+
write_line_to_performance_test_file(perf_file_name, v_action_text, true)
|
426
|
+
|
427
|
+
end
|
428
|
+
|
429
|
+
end
|
430
|
+
|
431
|
+
# Assign the prevredirect variable with the current redirect url.
|
432
|
+
prevredirect = request.response_parts[request.response_parts.count - 1].redirect_url.to_s
|
433
|
+
|
434
|
+
|
435
|
+
end
|
436
|
+
|
437
|
+
# End the transaction
|
438
|
+
v_action_text = %{
|
439
|
+
end_traction("#{step_name}", trans_time)
|
440
|
+
}
|
441
|
+
|
442
|
+
write_line_to_performance_test_file(perf_file_name, v_action_text, true)
|
443
|
+
|
444
|
+
end
|
445
|
+
|
446
|
+
# Clear out the network traffic log so we don't end up with duplicates
|
447
|
+
page.driver.clear_network_traffic
|
448
|
+
|
449
|
+
end
|
450
|
+
|
451
|
+
|
452
|
+
#####
|
453
|
+
## Function: decode_value
|
454
|
+
## Inputs: object (any object type)
|
455
|
+
## Outputs: object (transformed object)
|
456
|
+
## Description: This function should be called within other functions to transform
|
457
|
+
## the object into something that can be converted to a string.
|
458
|
+
## => an example is Cucumber::Ast::Table is a text table, but it needs to be
|
459
|
+
## => the raw version.
|
460
|
+
#####
|
461
|
+
def decode_value(variable_item)
|
462
|
+
# If the item is a nil, then change it to a nil
|
463
|
+
if variable_item.nil? then
|
464
|
+
item = nil
|
465
|
+
# Arrays are ok to pass through as they are
|
466
|
+
elsif (variable_item.class.to_s == 'Array') then
|
467
|
+
item = variable_item
|
468
|
+
elsif (variable_item.class.to_s == 'String') then
|
469
|
+
item = variable_item
|
470
|
+
# A Cucumber Docstring needs to be checked if it is empty or not
|
471
|
+
elsif (variable_item.class.to_s == 'Cucumber::Ast::DocString') then
|
472
|
+
if variable_item.to_s.empty? then
|
473
|
+
item = nil
|
474
|
+
else
|
475
|
+
item = variable_item
|
476
|
+
end
|
477
|
+
# A Cucumber Table needs to be the raw format
|
478
|
+
elsif (variable_item.class.to_s == 'Cucumber::Ast::Table') then
|
479
|
+
if variable_item.to_s.empty? then
|
480
|
+
item = nil
|
481
|
+
else
|
482
|
+
item = variable_item.raw
|
483
|
+
end
|
484
|
+
else
|
485
|
+
# else keep it as it is
|
486
|
+
item = variable_item
|
487
|
+
end
|
488
|
+
|
489
|
+
return item
|
490
|
+
|
491
|
+
end
|
492
|
+
|
493
|
+
|
494
|
+
#####
|
495
|
+
## Function: write_line_to_performance_test_file
|
496
|
+
## Inputs: perf_file_name (String) v_action_text (String)
|
497
|
+
## Outputs: None
|
498
|
+
## Description: This will write the action text to the performance test script
|
499
|
+
#####
|
500
|
+
def write_line_to_performance_test_file(perf_file_name, v_action_text, doublespace = false)
|
501
|
+
|
502
|
+
# Open the file to read
|
503
|
+
file_text = File.read(File.expand_path(perf_file_name).to_s)
|
504
|
+
# get the text of the file and add the new code to the end of #v_action end
|
505
|
+
if doublespace == true then
|
506
|
+
file_text_mod = file_text.gsub('#v_action end', ' ' + v_action_text.strip + "\n\n" + '#v_action temp end')
|
507
|
+
else
|
508
|
+
file_text_mod = file_text.gsub('#v_action end', ' ' + v_action_text.strip + "\n" + '#v_action temp end')
|
509
|
+
end
|
510
|
+
# Add the v#_action_end text back it. Doing this with the temp stops a recursive command
|
511
|
+
file_text_mod = file_text_mod.gsub('#v_action temp end', '#v_action end')
|
512
|
+
# Write it back to the file
|
513
|
+
open(perf_file_name, 'w') { |file| file.puts(File.expand_path(file_text_mod).to_s) }
|
514
|
+
|
515
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
Before do | scenario |
|
3
|
+
|
4
|
+
$step = 0
|
5
|
+
|
6
|
+
$function_call_name = []
|
7
|
+
$function_call_data = []
|
8
|
+
$function_call_arguments = []
|
9
|
+
$function_call_start = 0
|
10
|
+
|
11
|
+
$file_not_created = true
|
12
|
+
|
13
|
+
page.driver.clear_network_traffic
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
AfterStep do | scenario |
|
18
|
+
if (!ENV['GENERATE_PERFORMANCE_SCRIPT'].nil?) then
|
19
|
+
generate_performance_test_script(scenario)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Capybara::Poltergeist::NetworkTraffic
|
2
|
+
class Request
|
3
|
+
attr_reader :response_parts
|
4
|
+
|
5
|
+
def initialize(data, response_parts = [])
|
6
|
+
@data = data
|
7
|
+
@response_parts = response_parts
|
8
|
+
end
|
9
|
+
|
10
|
+
def response_parts
|
11
|
+
@response_parts
|
12
|
+
end
|
13
|
+
|
14
|
+
def url
|
15
|
+
@data['url']
|
16
|
+
end
|
17
|
+
|
18
|
+
def method
|
19
|
+
@data['method']
|
20
|
+
end
|
21
|
+
|
22
|
+
def data
|
23
|
+
@data['data']
|
24
|
+
end
|
25
|
+
|
26
|
+
def headers
|
27
|
+
@data['headers']
|
28
|
+
end
|
29
|
+
|
30
|
+
def time
|
31
|
+
@data['time'] && Time.parse(@data['time'])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module Capybara::Poltergeist::NetworkTraffic
|
37
|
+
class Response
|
38
|
+
def initialize(data)
|
39
|
+
@data = data
|
40
|
+
end
|
41
|
+
|
42
|
+
def url
|
43
|
+
@data['url']
|
44
|
+
end
|
45
|
+
|
46
|
+
def status
|
47
|
+
@data['status']
|
48
|
+
end
|
49
|
+
|
50
|
+
def status_text
|
51
|
+
@data['statusText']
|
52
|
+
end
|
53
|
+
|
54
|
+
def headers
|
55
|
+
@data['headers']
|
56
|
+
end
|
57
|
+
|
58
|
+
def redirect_url
|
59
|
+
@data['redirectURL']
|
60
|
+
end
|
61
|
+
|
62
|
+
def body_size
|
63
|
+
@data['bodySize']
|
64
|
+
end
|
65
|
+
|
66
|
+
def content_type
|
67
|
+
@data['contentType']
|
68
|
+
end
|
69
|
+
|
70
|
+
def time
|
71
|
+
@data['time'] && Time.parse(@data['time'])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cucumber-performance-generator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Moore
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: poltergeist
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.5.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.5.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: cliver
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.3.1
|
41
|
+
description: This gem adds to convert a capybara/poltergeist script into a load script
|
42
|
+
usable by the cucumber-performance gem.
|
43
|
+
email: mooreandrew@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- lib/cucumber-performance-generator/functions.rb
|
49
|
+
- lib/cucumber-performance-generator/hooks.rb
|
50
|
+
- lib/cucumber-performance-generator/poltergeist_override.rb
|
51
|
+
- lib/cucumber-performance-generator.rb
|
52
|
+
- LICENSE
|
53
|
+
- README.md
|
54
|
+
homepage: https://github.com/mooreandrew/cucumber-performance-generator
|
55
|
+
licenses:
|
56
|
+
- MIT
|
57
|
+
metadata: {}
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 2.0.14
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: ''
|
78
|
+
test_files: []
|