cucumber-performance-generator 0.0.1
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/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: []
|