taft 0.2.0 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b1a851c3a3d0bf8e0933b9b4580f38d218346b8a0231dc1b661f47e2e967be9
4
- data.tar.gz: 4cb413f6f6f2659736fff5fe1f97aaaeff4ab92e1671bb316ce4fba5d0b9e1e4
3
+ metadata.gz: 8bb8aab3c606d366ebac88a23d9dacad106707fa91b5a83275c51eb2d526a5d2
4
+ data.tar.gz: 14efc06fed065914cceb78028bac5200b4b281fa5232d3c781adc1c8812b5aa6
5
5
  SHA512:
6
- metadata.gz: c2d4b1f2d0af7d33943781130923bd45b4a118845b019740b9448368ccb0b69ff7f9bf75ddaa3433d91b30a884b4fbe418d3e6f702646b33d434a52462b0facb
7
- data.tar.gz: c1be8aa35bc5013a0d747a62842197da04eaf42f4cb39f2d704e4dd7c0bc774685df58eab2b3133b4c147ca4cadef06af30ca948da7dd0817e1af9e6b0c4214e
6
+ metadata.gz: c59f2588cc15ada34b51b517ec16efb5d8a317c34b8c0c67fece5070c028cd32c5fac92662254c7e42e282e8cf908232b8af521dfb3b9d9e2fffebdb57959202
7
+ data.tar.gz: 10220e583b36dcc8aaaec35bc6a53aec3e3a08f3792c0cf178ee9e12358a3079118b06b6ddf2d1a4318aa040cc47c4602c727669250afee2eb871089c33ac1d1
@@ -8,5 +8,4 @@ require "red_sky/api_helpers/rest"
8
8
  require "red_sky/ui_helpers/ui_general"
9
9
 
10
10
  require "red_sky/watir/pages/rs_pages"
11
- require "red_sky/watir/flows/rs_flows"
12
11
  require "red_sky/watir/custom/all"
data/lib/taft.rb CHANGED
@@ -199,6 +199,8 @@ class Taft
199
199
  entries = Dir.entries(dest_base_folder)
200
200
  entries.delete(".")
201
201
  entries.delete("..")
202
+ entries.delete(".git")
203
+ entries.delete(".gitignore")
202
204
  entries.each do |f|
203
205
  f = File.expand_path(f)
204
206
  pd "Now looking at #{f}; is dir? #{Dir.exists?(f)}"
@@ -8,5 +8,4 @@ require "zznamezz/api_helpers/rest"
8
8
  require "zznamezz/ui_helpers/ui_general"
9
9
 
10
10
  require "zznamezz/watir/pages/xxabbrevxx_pages"
11
- require "zznamezz/watir/flows/xxabbrevxx_flows"
12
11
  require "zznamezz/watir/custom/all"
@@ -28,7 +28,7 @@ class XXabbrevupperxxHelper
28
28
 
29
29
  # Reads in a file of CSV test data, e.g for use in data-driven tests
30
30
  def read_csv_test_data(filename)
31
- path = File.join(File.dirname(File.expand_path(__FILE__)) + "/../../../../tests/data", filename)
31
+ path = File.join(File.dirname(File.expand_path(__FILE__)) + "/../../../tests/data", filename)
32
32
  read_csv_data_from_file(path)
33
33
  end
34
34
 
@@ -43,7 +43,7 @@ class XXabbrevupperxxHelper
43
43
 
44
44
  # Reads in a JSON schema
45
45
  def read_json_schema(schema_filename)
46
- path = File.join(File.dirname(File.expand_path(__FILE__)) + "/../../../../tests/data", schema_filename)
46
+ path = File.join(File.dirname(File.expand_path(__FILE__)) + "/../../../tests/data", schema_filename)
47
47
  data = []
48
48
  File.open(path, "r") do |f|
49
49
  data = f.readlines
@@ -54,7 +54,7 @@ module ZZnamezzTestCase
54
54
  when /^browser$/
55
55
  browser
56
56
  when /^xxabbrevxx/i
57
- RSPages.find(name.to_s) # return the page so that the test can use it
57
+ XXabbrevupperxxPages.find(name.to_s) # return the page so that the test can use it
58
58
  else
59
59
  super
60
60
  end
@@ -73,9 +73,9 @@ module ZZnamezzTestCase
73
73
  end
74
74
 
75
75
  def load_pages(browser)
76
+ @browser_has_been_opened = true
76
77
  xxabbrevupperxxPages.make_pages(browser) # cannot have pages without a browser object
77
78
  $browsers << browser
78
- @browser_has_been_opened = true
79
79
  end
80
80
 
81
81
  # Close the current browser
@@ -1,4 +1,4 @@
1
- $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../../lib")
1
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../../lib"))
2
2
 
3
3
  require "zznamezz_test_case"
4
4
 
data/taft.gemspec CHANGED
@@ -1,13 +1,13 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'taft'
3
- s.version = '0.2.0'
3
+ s.version = '0.2.5'
4
4
  s.licenses = ['MIT']
5
5
  s.summary = "Test Automation Framework Template (TAFT)"
6
6
  s.description = "TAFT will deploy/install a skeleton code framework for the automated testing of applications with APIs and/or web-UIs"
7
7
  s.authors = ["Richard Morrisby"]
8
8
  s.email = 'rmorrisby@gmail.com'
9
9
  s.files = ["lib/taft.rb"]
10
- s.homepage = 'https://rubygems.org/gems/taft'
10
+ s.homepage = 'https://github.com/RMorrisby/taft'
11
11
  s.required_ruby_version = '>=2.6'
12
12
  s.files = Dir['**/**']
13
13
  s.test_files = Dir["test/test*.rb"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taft
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Morrisby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-05 00:00:00.000000000 Z
11
+ date: 2021-02-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: TAFT will deploy/install a skeleton code framework for the automated
14
14
  testing of applications with APIs and/or web-UIs
@@ -26,9 +26,6 @@ files:
26
26
  - examples/ruby/rs/framework/red_sky/ui_helpers/ui_general.rb
27
27
  - examples/ruby/rs/framework/red_sky/watir/custom/all.rb
28
28
  - examples/ruby/rs/framework/red_sky/watir/custom/rs_custom.rb
29
- - examples/ruby/rs/framework/red_sky/watir/flows/flow_objects.rb
30
- - examples/ruby/rs/framework/red_sky/watir/flows/rs_flow_names.rb
31
- - examples/ruby/rs/framework/red_sky/watir/flows/rs_flows.rb
32
29
  - examples/ruby/rs/framework/red_sky/watir/pages/page_objects.rb
33
30
  - examples/ruby/rs/framework/red_sky/watir/pages/rs_pages.rb
34
31
  - examples/ruby/rs/lib/config/red_sky_config.rb
@@ -43,9 +40,6 @@ files:
43
40
  - lib/taft_files/framework/zznamezz/ui_helpers/ui_general.rb
44
41
  - lib/taft_files/framework/zznamezz/watir/custom/all.rb
45
42
  - lib/taft_files/framework/zznamezz/watir/custom/xxabbrevxx_custom.rb
46
- - lib/taft_files/framework/zznamezz/watir/flows/flow_objects.rb
47
- - lib/taft_files/framework/zznamezz/watir/flows/xxabbrevxx_flow_names.rb
48
- - lib/taft_files/framework/zznamezz/watir/flows/xxabbrevxx_flows.rb
49
43
  - lib/taft_files/framework/zznamezz/watir/pages/page_objects.rb
50
44
  - lib/taft_files/framework/zznamezz/watir/pages/xxabbrevxx_pages.rb
51
45
  - lib/taft_files/lib/config/runtime_constants.rb
@@ -54,7 +48,7 @@ files:
54
48
  - lib/taft_files/tests/v1/tc_r001_01_an_example_test.rb
55
49
  - taft.gemspec
56
50
  - test/test_example.rb
57
- homepage: https://rubygems.org/gems/taft
51
+ homepage: https://github.com/RMorrisby/taft
58
52
  licenses:
59
53
  - MIT
60
54
  metadata: {}
@@ -1,466 +0,0 @@
1
- # A class defining the series of Flow classes & helpers
2
-
3
- # TODO define some base class/classes. Must be scope here for consolidation through inheritance?
4
-
5
- #require 'minitest/unit' # needed? # TODO use test-unit, or convert everything else to minitest
6
-
7
- #class FlowObjects
8
- # attr_accessor :flows
9
- #
10
- # def initialize
11
- # @flows = [] # an array of Flow objects
12
- # end
13
- #
14
- # def add_flow(flow)
15
- # @flows << flow
16
- # end
17
- #
18
- # # TODO needed?
19
- # def ==(o)
20
- # end
21
- #
22
- # # TODO needed?
23
- # def to_s
24
- # end
25
- #
26
- #end
27
-
28
- # A class defining a flow. This contains the fields to be interacted with, in their proper sequence, with valid or
29
- # invalid values
30
- class Flow
31
-
32
- attr_accessor :name
33
- attr_accessor :flow_map # some collection of Flow, FlowField & other Flow-type objects # TODO
34
-
35
- def initialize(name)
36
- @name = name
37
- @flow_map = []
38
- end
39
-
40
- def add(flow_item)
41
- @flow_map << flow_item
42
- end
43
-
44
- # TODO needed?
45
- def ==(o)
46
- end
47
-
48
- def to_s
49
- s = ""
50
- s += "Flow name : #{@name}. Flow map size : #{@flow_map.size}. Flow items :"
51
- @flow_map.each {|f| s += "\n\t#{f.to_s}" }
52
- s
53
- end
54
-
55
- # Executes the flow
56
- # Takes symbols which act as flags :
57
- # success_sym - set to :success for a valid set of inputs, set to :fail for one or more of the inputs to be invalid and
58
- # the flow to fail
59
- # mandatory_fields_sym - set to :mandatory to only involve the mandatory fields, set to :all_fields to use all defined
60
- # fields in the flow
61
- # custom_values_hash - hash of values some/all of the fields must take (e.g. creating a new record with a specific foreign key)
62
- # keys are field names (as defined in CeresFlows) in either symbol or string form, values are the values the fields should take
63
- # TODO : don't want to have to pass in browser each time
64
- def execute(browser, custom_values_hash = {}, success_sym = :success, mandatory_fields_sym = :mandatory)
65
- report = nil # if report is still nil at the end of the method, generate a dummy one
66
- return_value = nil # default value that will be fed into the report # TODO needs to be an array? Or hold multiple
67
- # values?
68
- # pass = true
69
- # all = true
70
- case success_sym
71
- when :success
72
- pass = true
73
- when :fail
74
- pass = false
75
- else
76
- raise "Did not understand value '#{success_sym.inspect}' for success_sym"
77
- end
78
-
79
- case mandatory_fields_sym
80
- when :mandatory
81
- all = false
82
- when :all_fields
83
- all = true
84
- else
85
- raise "Did not understand value '#{mandatory_fields_sym.inspect}' for mandatory_fields_sym"
86
- end
87
-
88
- @flow_map.each do |flow_item|
89
- case flow_item
90
- when Flow # flows can contain sub-flows
91
- flow_item.execute(browser, custom_values_hash, success_sym, mandatory_fields_sym) # call recursively
92
- when FlowPrecondition
93
- # TODO : find flow from name & execute it
94
- flow_item.execute_precondition_flow(custom_values_hash)
95
- when FlowLink
96
- # debugging
97
- # puts "Executing #{flow_item.name}"
98
- # puts browser.url
99
-
100
- browser.link(:id => flow_item.name).click
101
-
102
- sleep 1 # TODO determine expected page, call page.wait_until_displayed
103
- when FlowField
104
- puts "Now executing field #{flow_item.to_s}"
105
- next if all == false && flow_item.mandatory == false # skip optional fields if instructed
106
-
107
- field = nil
108
-
109
- # TODO : look up field identification parameters (e.g. :id => something) from field definition in rs_pages
110
- # The linkage should be that the NAME of the rs_page field (e.g. page.add_field("role", :list, :id, "user_role") )
111
- # matches the NAME of the flow_item. We therefore use flow_item.name to track down the field identification parameters
112
- # stored in the field definition in rs_pages (in this example, :id, "user_role" )
113
- # Until this is done, flow_item.name needs to match the rs_pages field ident param.
114
-
115
- case flow_item.type
116
- # TODO only have this case statement determine field type, then pass it into one eval line instead of one
117
- # line per type
118
- # Type field completion may differ by more than just their field type...
119
-
120
- when :string
121
- field = browser.text_field(:id => flow_item.name)
122
- when :p
123
- field = browser.p(:id => flow_item.name)
124
- when :div
125
- field = browser.div(:id => flow_item.name)
126
- when :checkbox
127
- field = browser.input(:id => flow_item.name)
128
- when :list
129
- # field = browser.select_list(:id => flow_item.name)
130
- field = browser.select(:id => flow_item.name)
131
- when :button
132
- # buttons only have one function - to be pressed, not to be read or written to
133
- browser.button(:id => flow_item.name).click
134
- else
135
- raise "Cannot execute #{flow_item.class} of type #{flow_item.type}"
136
- end
137
- case flow_item.operation
138
- when :read
139
- case flow_item.type
140
- when :string, :checkbox, :list, :p, :div
141
- # puts "value : #{field.value}"
142
- # puts "text : #{field.text}"
143
- return_value = field.value
144
- return_value = field.text if return_value == "" # p needs .text
145
- # puts "return_value : #{return_value}"
146
- end
147
- when :write
148
- # get valid value from hash, if it has been specified
149
- value = custom_values_hash[flow_item.name.to_sym].to_s # flow_item.name is defined in rs_flows to be a string; it is nicer if the custom hash keys are symbols, but we then need to convert them
150
- value = flow_item.random_valid_value if value == nil
151
- # value = flow_item.random_invalid_value if invalid # TODO enable
152
- case flow_item.type
153
- when :string, :checkbox
154
- field.set(value)
155
- when :list
156
- field.select(value)
157
- end
158
- end
159
- when FlowVerify
160
- name = "verify"
161
- verify_flow = Flow.new(name)
162
- verify_flow.add(flow_item.flow_field)
163
- # call recursively, have it generate a Report, perform validation against the Report
164
- report = verify_flow.execute(browser)
165
- #puts "report : #{report}"
166
- value = report.value
167
- flow_item.verify(value)
168
- return_value = "FlowVerify passed : #{flow_item}"
169
- when FlowReport # not yet in use - no FlowReports have been defined in rs_flows
170
- report = flow_item.generate_report
171
- else
172
- raise "Cannot execute flow item of class #{flow_item.class}"
173
- end # end case
174
- end # end .each
175
- if report == nil # if report is still nil at the end of the method, generate a dummy one
176
- # return_value =
177
- report = FlowReport.new(return_value)
178
- end
179
- report
180
- end # end execute
181
-
182
- end # end class
183
-
184
- # A class defining a flow that must be executed as a precondition to the flow this object belongs to
185
- class FlowPrecondition
186
-
187
- attr_accessor :precondition_flow # precondition_flow is the name of the precondition flow that must be executed
188
-
189
- def initialize(precondition_flow)
190
- @precondition_flow = precondition_flow
191
- end
192
-
193
- def to_s
194
- s = ""
195
- s += "Precondition Flow : #{@precondition_flow}"
196
- s
197
- end
198
-
199
- # TODO : need success & madatory field flags here?
200
- def execute_precondition_flow(custom_values_hash = {})
201
- # find flow from name
202
- # TODO : flows all stored in @flow (CeresFlow.new()). Gaining access to this feels wrong...
203
-
204
- # execute flow
205
-
206
- end
207
-
208
- end
209
-
210
- # A class defining a navigation step that is needed as part of a flow. These assume that their navigation is done via
211
- # links, not buttons/divs/etc.
212
- class FlowLink
213
-
214
- attr_accessor :name, :parent_page, :destination, :verification # parent_page is the page within which the desired link
215
- # can be found
216
- # destination is the name of the page that the browser will arrive at after performing this navigation.
217
- # verification is a FlowVerify object that is defined such that it can only pass if it matches the defined field on the
218
- # destination page
219
- # TODO enable mechanism such that one can simply state flow.goto(destination) and all flows will be scanned for the
220
- # flow that will take us there, then that flow will be executed.
221
-
222
- def initialize(destination, name, parent_page)
223
- @destination = destination
224
- @name = name
225
- @parent_page = parent_page
226
- end
227
-
228
- def to_s
229
- s = ""
230
- s += "Flow destination : #{@destination}. Link ID : #{@name}. Parent page : #{@parent_page}"
231
- s
232
- end
233
-
234
- end
235
-
236
- # A class defining a field that is interacted with in some way as part of a flow.
237
- # Valid types: :string (a text field); :button (a button); :link (a link); :list (a select list); :checkbox (a checkbox)
238
- # TODO still want link to be valid here? What about FlowLink?
239
- class FlowField
240
-
241
- attr_accessor :name, :type, :operation, :mandatory, :size, :custom_valid_value_definition, :custom_invalid_value_definition
242
-
243
- def initialize(name, type = :string, operation = :write, mandatory = true, size = nil, custom_valid_value_definition = nil, custom_invalid_value_definition = nil)
244
- raise "FlowField name must be a string" unless name.class == String
245
- @name = name
246
- @type = type
247
- @operation = operation
248
- raise "Cannot define FlowField #{@name} with operation of #{@operation.inspect}" unless @operation == :read || @operation == :write
249
- @mandatory = mandatory
250
- if size == nil
251
- @size = get_default_size
252
- else
253
- @size = size
254
- end
255
-
256
- custom_valid_value_definition = nil
257
- custom_invalid_value_definition = nil
258
-
259
- check_valid_type
260
-
261
- # TODO custom_valid_value_definition, etc
262
- case custom_valid_value_definition
263
- when NilClass
264
- # take default valid field def based on @type
265
- when Symbol
266
- #run sub-case based on symbol
267
- when Regexp # ?
268
- # define method
269
- when Array
270
- @custom_valid_value_definition = custom_valid_value_definition
271
- when block # ?
272
- # define method
273
- else
274
- raise "Could not process custom_valid_value_definition specified for FlowField of name '#{@name}'"
275
- end
276
-
277
- case custom_invalid_value_definition
278
- when NilClass
279
- # take default valid field def based on @type
280
- when Symbol
281
- #run sub-case based on symbol
282
- when Regexp # ?
283
- # define method
284
- when Block # ?
285
- # define method
286
- else
287
- raise "Could not process custom_invalid_value_definition specified for FlowField of name '#{@name}'"
288
- end
289
- end
290
-
291
- # Retrieves default sizes for fields
292
- # Assumes @type is set
293
- def get_default_size
294
- size = 0
295
- case @type
296
- when :button, :link, :list, :checkbox
297
- # do nothing
298
- when :string
299
- size = 32
300
- when :p, :div # these will be read-only so this doesn't really matter
301
- size = 4000
302
- else
303
- raise "#{@type} is not a valid type for FlowField"
304
- end
305
- size
306
- end
307
-
308
- # Valid types:
309
- # :string (a text field);
310
- # :button (a button);
311
- # :link (a link);
312
- # :list (a select list);
313
- # :checkbox (a checkbox)
314
- def check_valid_type
315
- case @type
316
- when :button, :link, :list, :checkbox
317
- check_valid_size(0)
318
- when :string, :p, :div
319
- check_valid_size(@size) # TODO a pointless call - @size will compared against itself!
320
- else
321
- raise "#{@type} is not a valid type for FlowField"
322
- end
323
- end
324
-
325
- # Raises unless the supplied size is greater or equal to @size
326
- def check_valid_size(valid_size_for_type)
327
- valid = false
328
- case @size
329
- when NilClass
330
- valid = true if @size == nil
331
- when TrueClass # possible?
332
- valid = @size if something # TODO
333
- when FalseClass # possible?
334
- valid = @size if something # TODO
335
- when Fixnum, String
336
- valid = true if @size <= valid_size_for_type
337
- end
338
-
339
- raise "Defined size #{@size.inspect} for FlowField '#{@name}' is not valid for field of type '#{type}'" unless valid
340
- end
341
-
342
- # TODO needed?
343
- def ==(o)
344
- end
345
-
346
- # TODO needed?
347
- def to_s
348
- s = ""
349
- s += "Flow field : #{@name}. Type : #{@type}. Mandatory : #{@mandatory}. Size : #{@size}"
350
- s
351
- end
352
-
353
- # Generate a random value based on its type
354
- def random_valid_value
355
- value = nil
356
- case @type
357
- when :string
358
- value = rand_string(@size) # TODO : vary size of random string?
359
- when :checkbox
360
- # value = (rand(2) == 1) # TODO : need to have the object itself have defined what is a valid and invalid
361
- # value
362
- value = true # most checkboxes will want to be ticked, but it is plausable that the valid value for some of them
363
- # is to be unticked
364
- when :list
365
- # TODO difficult - need to pick a random item from the list. How do we know its contents?
366
- # Maybe pick a random number, not greater than the size of the list, then set by index/position?
367
- if @custom_valid_value_definition != nil # if not nil, custom_valid_value_definition should be an array of the valid options
368
- value = @custom_valid_value_definition.random
369
- end
370
- when :button
371
- # do nothing
372
- else
373
- raise "Do not know how to generate a random valid value for FlowField of type #{@type}"
374
- end
375
- value
376
- end
377
-
378
- end
379
-
380
- # A class defining a verification step
381
- class FlowVerify
382
-
383
- include Test::Unit::Assertions
384
-
385
- attr_accessor :expected, :value_or_regex, :flow_field
386
- # expected is a boolean for whether or not the verification is expected to succeed or fail
387
- # value_or_regex is a string, number, boolean or regex
388
- # flow_field is a FlowField object pointing to a field whose value value_or_regex must be used against
389
-
390
- def initialize(expected, value_or_regex, flow_field)
391
- @expected = expected
392
- @value_or_regex = value_or_regex
393
-
394
- @flow_field = flow_field
395
- raise ":flow_field must be of class FlowField" unless @flow_field.class == FlowField
396
- end
397
-
398
- def to_s
399
- s = ""
400
- s += "Flow verifier : expected : #{@expected}. Value/regex : #{@value_or_regex.inspect}. Field : #{@flow_field}"
401
- s
402
- end
403
-
404
- def verify(actual)
405
- puts "now in verify for FlowVerify for field #{@flow_field} against value #{@value_or_regex}"
406
-
407
- case @value_or_regex # case is better, leaves room for other options depending on class
408
- when Regexp
409
- match = !!(actual =~ @value_or_regex) # double-invert to convert to true-or-false
410
- else
411
- match = (actual == @value_or_regex)
412
- end
413
- if @expected
414
- message = "FlowVerify failed. Expected the value to match #{@value_or_regex.inspect} but was actually #{actual.inspect}"
415
- else
416
- message = "FlowVerify failed. Expected the value #{@value_or_regex.inspect} to be different to the actual value of #{actual.inspect}"
417
- end
418
- puts "about to assert; #{actual.inspect} == #{@value_or_regex.inspect} => #{@expected == match}"
419
- assert_equal(@expected, match, message)
420
- puts "assertion passed"
421
- end
422
-
423
- end
424
-
425
- # A class defining feedback to be returned after invoking the flow.
426
- # TODO : rework this so that it knows how to gather the required information (?)
427
- class FlowReport
428
-
429
- # attr_accessor :success, :message, :value_hash_array
430
- # # success is a boolean
431
- # # message is a string
432
- # # value_hash_array is an array of hashes, one per object/event/thing. Its keys are the object's fields, and the
433
- # values
434
- ## are their values
435
- #
436
- # def initialize(success, message, value_hash_array)
437
- # @success = success
438
- # @message = message
439
- # @value_hash_array = value_hash_array
440
- # end
441
- #
442
- # def to_s
443
- # s = ""
444
- # s += "Flow report : success? #{@success}. Message : #{@message}. Values : #{@value_hash_array}"
445
- # s
446
- # end
447
-
448
- attr_accessor :value
449
-
450
- def initialize(value = nil)
451
- # do nothing?
452
- @value = value
453
- end
454
-
455
- def to_s
456
- s = ""
457
- s += "Flow report : value : #{@value}"
458
- s
459
- end
460
-
461
- def generate_report
462
- #TODO
463
- ""
464
- end
465
-
466
- end
@@ -1,15 +0,0 @@
1
- # List of constants that store names of flows
2
- # Names are stored as symbols
3
-
4
- class RSFN
5
-
6
- # Homepage
7
- GOTO_HOMEPAGE = :goto_homepage
8
-
9
- # Users
10
- VIEW_ALL_USERS = :view_all_users
11
- VIEW_USER = :view_user
12
- CREATE_USER = :create_user
13
- DELETE_USER = :delete_user
14
-
15
- end
@@ -1,117 +0,0 @@
1
- # A class defining the UI flows within RedSky, such that simple usecase-esq methods arise from them and can
2
- # perform a series of UI actions (making a record, viewing & deleting, etc.)
3
-
4
- # The intended use is that the test (or supporting framework) call @flow.flow_name, e.g. @flow.create_project, which will
5
- # perform all of the actions of that flow. Parameters can be supplied to the call, which will change its behaviour
6
-
7
- require_relative 'flow_objects'
8
- require_relative 'rs_flow_names'
9
-
10
- class RSFlows
11
-
12
- attr_accessor :flows # array of Flow objects
13
- attr_accessor :flow_names # array of names of known Flow objects
14
-
15
-
16
- # Assembles all of the flows and stores them, ready for use
17
- def initialize
18
- @flows = [] # an array of Flow objects
19
- @flow_names = []
20
-
21
- # Simple nav flow to get to the homepage
22
- flow = Flow.new(RSFN::GOTO_HOMEPAGE)
23
- flow.add(FlowLink.new("goto_homepage", "rs_home_header_link", nil)) # no parent page, is valid from any page
24
- add_flow(flow)
25
-
26
- # View all users
27
- flow = new_base_flow(RSFN::VIEW_ALL_USERS)
28
- flow.add(FlowLink.new("all_users", "users_header_link", nil))
29
- add_flow(flow)
30
-
31
- # Create user
32
- flow = new_base_flow(RSFN::CREATE_USER)
33
- add_existing_flow_to_flow(flow, RSFN::VIEW_ALL_USERS)
34
-
35
- flow.add(FlowLink.new("all_users", "users_header_link", nil))
36
- flow.add(FlowLink.new("create_user", "new_user_link", "all_users"))
37
- field_flow = Flow.new("create_user_fields")
38
-
39
- field_flow.add(FlowField.new("user_name"))
40
- field_flow.add(FlowField.new("user_role", :list, :write, true, nil, RedSkyConfig::ALL_USER_ROLES))
41
-
42
- flow.add(field_flow)
43
- flow.add(FlowField.new("save", :button))
44
-
45
- message = FlowField.new("notice", :p, :read)
46
- flow.add(FlowVerify.new(true, "User was successfully created.", message))
47
-
48
- add_flow(flow)
49
- end
50
-
51
-
52
- ##############################################################################
53
-
54
-
55
- def method_missing(name, *args, &block)
56
- puts "RSFlows method_missing called; name = #{name.inspect}; #{name.class}"
57
-
58
- if flow_known(name)
59
- puts "Flow #{name} is known"
60
- # TODO define a whole bunch of methods and then perform them
61
- # If args and/or block have been provided, process them. E.g. one arg could be a trigger to perform the flow with
62
- # invalid values # TODO : is that the best way of doing that?
63
- else
64
- super
65
- end
66
- end
67
-
68
- def add_flow(flow)
69
- @flows << flow
70
- @flow_names << flow.name
71
- end
72
-
73
- # TODO needed?
74
- def ==(o)
75
- end
76
-
77
- # TODO needed?
78
- def to_s
79
- s = ""
80
- s += "#{@flows.size} flows defined. Names :"
81
- @flow_names.each {|f| s += "\n#{f}" }
82
- s
83
- end
84
-
85
- # Will convert name to a string
86
- def flow_known?(name)
87
- @flow_names.include?(name)
88
- end
89
-
90
- # Retrieves the specific flow; raises if it cannot be found
91
- # Will convert name to a string
92
- def find(name)
93
- raise "Could not locate flow '#{name}'" unless flow_known?(name)
94
- @flows[@flow_names.index(name)]
95
- end
96
-
97
- # Finds & executes a flow
98
- def find_and_execute(browser, name, custom_values_hash = {}, success_sym = :success, mandatory_fields_sym = :mandatory)
99
- f = find(name)
100
- f.execute(browser, custom_values_hash, success_sym, mandatory_fields_sym)
101
- end
102
-
103
- # Adds an already-existing flow to the supplied flow
104
- def add_existing_flow_to_flow(new_flow, existing_flow_name)
105
- # TODO : need deduplication mechanism so that a flow doesn't gain two/more duplicate flow items in a row (e.g. two calls to GOTO_HOMEPAGE in a row)
106
- new_flow.add(find(existing_flow_name))
107
- end
108
-
109
- # Shortcut to define a new flow with standard prerequisite flows already added
110
- # Cannot be called until the flows that are to be added have been defined
111
- def new_base_flow(name)
112
- flow = Flow.new(name)
113
- add_existing_flow_to_flow(flow, RSFN::GOTO_HOMEPAGE)
114
- flow
115
- end
116
-
117
- end
@@ -1,466 +0,0 @@
1
- # A class defining the series of Flow classes & helpers
2
-
3
- # TODO define some base class/classes. Must be scope here for consolidation through inheritance?
4
-
5
- #require 'minitest/unit' # needed? # TODO use test-unit, or convert everything else to minitest
6
-
7
- #class FlowObjects
8
- # attr_accessor :flows
9
- #
10
- # def initialize
11
- # @flows = [] # an array of Flow objects
12
- # end
13
- #
14
- # def add_flow(flow)
15
- # @flows << flow
16
- # end
17
- #
18
- # # TODO needed?
19
- # def ==(o)
20
- # end
21
- #
22
- # # TODO needed?
23
- # def to_s
24
- # end
25
- #
26
- #end
27
-
28
- # A class defining a flow. This contains the fields to be interacted with, in their proper sequence, with valid or
29
- # invalid values
30
- class Flow
31
-
32
- attr_accessor :name
33
- attr_accessor :flow_map # some collection of Flow, FlowField & other Flow-type objects # TODO
34
-
35
- def initialize(name)
36
- @name = name
37
- @flow_map = []
38
- end
39
-
40
- def add(flow_item)
41
- @flow_map << flow_item
42
- end
43
-
44
- # TODO needed?
45
- def ==(o)
46
- end
47
-
48
- def to_s
49
- s = ""
50
- s += "Flow name : #{@name}. Flow map size : #{@flow_map.size}. Flow items :"
51
- @flow_map.each {|f| s += "\n\t#{f.to_s}" }
52
- s
53
- end
54
-
55
- # Executes the flow
56
- # Takes symbols which act as flags :
57
- # success_sym - set to :success for a valid set of inputs, set to :fail for one or more of the inputs to be invalid and
58
- # the flow to fail
59
- # mandatory_fields_sym - set to :mandatory to only involve the mandatory fields, set to :all_fields to use all defined
60
- # fields in the flow
61
- # custom_values_hash - hash of values some/all of the fields must take (e.g. creating a new record with a specific foreign key)
62
- # keys are field names (as defined in CeresFlows) in either symbol or string form, values are the values the fields should take
63
- # TODO : don't want to have to pass in browser each time
64
- def execute(browser, custom_values_hash = {}, success_sym = :success, mandatory_fields_sym = :mandatory)
65
- report = nil # if report is still nil at the end of the method, generate a dummy one
66
- return_value = nil # default value that will be fed into the report # TODO needs to be an array? Or hold multiple
67
- # values?
68
- # pass = true
69
- # all = true
70
- case success_sym
71
- when :success
72
- pass = true
73
- when :fail
74
- pass = false
75
- else
76
- raise "Did not understand value '#{success_sym.inspect}' for success_sym"
77
- end
78
-
79
- case mandatory_fields_sym
80
- when :mandatory
81
- all = false
82
- when :all_fields
83
- all = true
84
- else
85
- raise "Did not understand value '#{mandatory_fields_sym.inspect}' for mandatory_fields_sym"
86
- end
87
-
88
- @flow_map.each do |flow_item|
89
- case flow_item
90
- when Flow # flows can contain sub-flows
91
- flow_item.execute(browser, custom_values_hash, success_sym, mandatory_fields_sym) # call recursively
92
- when FlowPrecondition
93
- # TODO : find flow from name & execute it
94
- flow_item.execute_precondition_flow(custom_values_hash)
95
- when FlowLink
96
- # debugging
97
- # puts "Executing #{flow_item.name}"
98
- # puts browser.url
99
-
100
- browser.link(:id => flow_item.name).click
101
-
102
- sleep 1 # TODO determine expected page, call page.wait_until_displayed
103
- when FlowField
104
- puts "Now executing field #{flow_item.to_s}"
105
- next if all == false && flow_item.mandatory == false # skip optional fields if instructed
106
-
107
- field = nil
108
-
109
- # TODO : look up field identification parameters (e.g. :id => something) from field definition in xxabbrevxx_pages
110
- # The linkage should be that the NAME of the xxabbrevxx_page field (e.g. page.add_field("role", :list, :id, "user_role") )
111
- # matches the NAME of the flow_item. We therefore use flow_item.name to track down the field identification parameters
112
- # stored in the field definition in xxabbrevxx_pages (in this example, :id, "user_role" )
113
- # Until this is done, flow_item.name needs to match the xxabbrevxx_pages field ident param.
114
-
115
- case flow_item.type
116
- # TODO only have this case statement determine field type, then pass it into one eval line instead of one
117
- # line per type
118
- # Type field completion may differ by more than just their field type...
119
-
120
- when :string
121
- field = browser.text_field(:id => flow_item.name)
122
- when :p
123
- field = browser.p(:id => flow_item.name)
124
- when :div
125
- field = browser.div(:id => flow_item.name)
126
- when :checkbox
127
- field = browser.input(:id => flow_item.name)
128
- when :list
129
- # field = browser.select_list(:id => flow_item.name)
130
- field = browser.select(:id => flow_item.name)
131
- when :button
132
- # buttons only have one function - to be pressed, not to be read or written to
133
- browser.button(:id => flow_item.name).click
134
- else
135
- raise "Cannot execute #{flow_item.class} of type #{flow_item.type}"
136
- end
137
- case flow_item.operation
138
- when :read
139
- case flow_item.type
140
- when :string, :checkbox, :list, :p, :div
141
- # puts "value : #{field.value}"
142
- # puts "text : #{field.text}"
143
- return_value = field.value
144
- return_value = field.text if return_value == "" # p needs .text
145
- # puts "return_value : #{return_value}"
146
- end
147
- when :write
148
- # get valid value from hash, if it has been specified
149
- value = custom_values_hash[flow_item.name.to_sym].to_s # flow_item.name is defined in xxabbrevxx_flows to be a string; it is nicer if the custom hash keys are symbols, but we then need to convert them
150
- value = flow_item.random_valid_value if value == nil
151
- # value = flow_item.random_invalid_value if invalid # TODO enable
152
- case flow_item.type
153
- when :string, :checkbox
154
- field.set(value)
155
- when :list
156
- field.select(value)
157
- end
158
- end
159
- when FlowVerify
160
- name = "verify"
161
- verify_flow = Flow.new(name)
162
- verify_flow.add(flow_item.flow_field)
163
- # call recursively, have it generate a Report, perform validation against the Report
164
- report = verify_flow.execute(browser)
165
- #puts "report : #{report}"
166
- value = report.value
167
- flow_item.verify(value)
168
- return_value = "FlowVerify passed : #{flow_item}"
169
- when FlowReport # not yet in use - no FlowReports have been defined in xxabbrevxx_flows
170
- report = flow_item.generate_report
171
- else
172
- raise "Cannot execute flow item of class #{flow_item.class}"
173
- end # end case
174
- end # end .each
175
- if report == nil # if report is still nil at the end of the method, generate a dummy one
176
- # return_value =
177
- report = FlowReport.new(return_value)
178
- end
179
- report
180
- end # end execute
181
-
182
- end # end class
183
-
184
- # A class defining a flow that must be executed as a precondition to the flow this object belongs to
185
- class FlowPrecondition
186
-
187
- attr_accessor :precondition_flow # precondition_flow is the name of the precondition flow that must be executed
188
-
189
- def initialize(precondition_flow)
190
- @precondition_flow = precondition_flow
191
- end
192
-
193
- def to_s
194
- s = ""
195
- s += "Precondition Flow : #{@precondition_flow}"
196
- s
197
- end
198
-
199
- # TODO : need success & madatory field flags here?
200
- def execute_precondition_flow(custom_values_hash = {})
201
- # find flow from name
202
- # TODO : flows all stored in @flow (CeresFlow.new()). Gaining access to this feels wrong...
203
-
204
- # execute flow
205
-
206
- end
207
-
208
- end
209
-
210
- # A class defining a navigation step that is needed as part of a flow. These assume that their navigation is done via
211
- # links, not buttons/divs/etc.
212
- class FlowLink
213
-
214
- attr_accessor :name, :parent_page, :destination, :verification # parent_page is the page within which the desired link
215
- # can be found
216
- # destination is the name of the page that the browser will arrive at after performing this navigation.
217
- # verification is a FlowVerify object that is defined such that it can only pass if it matches the defined field on the
218
- # destination page
219
- # TODO enable mechanism such that one can simply state flow.goto(destination) and all flows will be scanned for the
220
- # flow that will take us there, then that flow will be executed.
221
-
222
- def initialize(destination, name, parent_page)
223
- @destination = destination
224
- @name = name
225
- @parent_page = parent_page
226
- end
227
-
228
- def to_s
229
- s = ""
230
- s += "Flow destination : #{@destination}. Link ID : #{@name}. Parent page : #{@parent_page}"
231
- s
232
- end
233
-
234
- end
235
-
236
- # A class defining a field that is interacted with in some way as part of a flow.
237
- # Valid types: :string (a text field); :button (a button); :link (a link); :list (a select list); :checkbox (a checkbox)
238
- # TODO still want link to be valid here? What about FlowLink?
239
- class FlowField
240
-
241
- attr_accessor :name, :type, :operation, :mandatory, :size, :custom_valid_value_definition, :custom_invalid_value_definition
242
-
243
- def initialize(name, type = :string, operation = :write, mandatory = true, size = nil, custom_valid_value_definition = nil, custom_invalid_value_definition = nil)
244
- raise "FlowField name must be a string" unless name.class == String
245
- @name = name
246
- @type = type
247
- @operation = operation
248
- raise "Cannot define FlowField #{@name} with operation of #{@operation.inspect}" unless @operation == :read || @operation == :write
249
- @mandatory = mandatory
250
- if size == nil
251
- @size = get_default_size
252
- else
253
- @size = size
254
- end
255
-
256
- custom_valid_value_definition = nil
257
- custom_invalid_value_definition = nil
258
-
259
- check_valid_type
260
-
261
- # TODO custom_valid_value_definition, etc
262
- case custom_valid_value_definition
263
- when NilClass
264
- # take default valid field def based on @type
265
- when Symbol
266
- #run sub-case based on symbol
267
- when Regexp # ?
268
- # define method
269
- when Array
270
- @custom_valid_value_definition = custom_valid_value_definition
271
- when block # ?
272
- # define method
273
- else
274
- raise "Could not process custom_valid_value_definition specified for FlowField of name '#{@name}'"
275
- end
276
-
277
- case custom_invalid_value_definition
278
- when NilClass
279
- # take default valid field def based on @type
280
- when Symbol
281
- #run sub-case based on symbol
282
- when Regexp # ?
283
- # define method
284
- when Block # ?
285
- # define method
286
- else
287
- raise "Could not process custom_invalid_value_definition specified for FlowField of name '#{@name}'"
288
- end
289
- end
290
-
291
- # Retrieves default sizes for fields
292
- # Assumes @type is set
293
- def get_default_size
294
- size = 0
295
- case @type
296
- when :button, :link, :list, :checkbox
297
- # do nothing
298
- when :string
299
- size = 32
300
- when :p, :div # these will be read-only so this doesn't really matter
301
- size = 4000
302
- else
303
- raise "#{@type} is not a valid type for FlowField"
304
- end
305
- size
306
- end
307
-
308
- # Valid types:
309
- # :string (a text field);
310
- # :button (a button);
311
- # :link (a link);
312
- # :list (a select list);
313
- # :checkbox (a checkbox)
314
- def check_valid_type
315
- case @type
316
- when :button, :link, :list, :checkbox
317
- check_valid_size(0)
318
- when :string, :p, :div
319
- check_valid_size(@size) # TODO a pointless call - @size will compared against itself!
320
- else
321
- raise "#{@type} is not a valid type for FlowField"
322
- end
323
- end
324
-
325
- # Raises unless the supplied size is greater or equal to @size
326
- def check_valid_size(valid_size_for_type)
327
- valid = false
328
- case @size
329
- when NilClass
330
- valid = true if @size == nil
331
- when TrueClass # possible?
332
- valid = @size if something # TODO
333
- when FalseClass # possible?
334
- valid = @size if something # TODO
335
- when Fixnum, String
336
- valid = true if @size <= valid_size_for_type
337
- end
338
-
339
- raise "Defined size #{@size.inspect} for FlowField '#{@name}' is not valid for field of type '#{type}'" unless valid
340
- end
341
-
342
- # TODO needed?
343
- def ==(o)
344
- end
345
-
346
- # TODO needed?
347
- def to_s
348
- s = ""
349
- s += "Flow field : #{@name}. Type : #{@type}. Mandatory : #{@mandatory}. Size : #{@size}"
350
- s
351
- end
352
-
353
- # Generate a random value based on its type
354
- def random_valid_value
355
- value = nil
356
- case @type
357
- when :string
358
- value = rand_string(@size) # TODO : vary size of random string?
359
- when :checkbox
360
- # value = (rand(2) == 1) # TODO : need to have the object itself have defined what is a valid and invalid
361
- # value
362
- value = true # most checkboxes will want to be ticked, but it is plausable that the valid value for some of them
363
- # is to be unticked
364
- when :list
365
- # TODO difficult - need to pick a random item from the list. How do we know its contents?
366
- # Maybe pick a random number, not greater than the size of the list, then set by index/position?
367
- if @custom_valid_value_definition != nil # if not nil, custom_valid_value_definition should be an array of the valid options
368
- value = @custom_valid_value_definition.random
369
- end
370
- when :button
371
- # do nothing
372
- else
373
- raise "Do not know how to generate a random valid value for FlowField of type #{@type}"
374
- end
375
- value
376
- end
377
-
378
- end
379
-
380
- # A class defining a verification step
381
- class FlowVerify
382
-
383
- include Test::Unit::Assertions
384
-
385
- attr_accessor :expected, :value_or_regex, :flow_field
386
- # expected is a boolean for whether or not the verification is expected to succeed or fail
387
- # value_or_regex is a string, number, boolean or regex
388
- # flow_field is a FlowField object pointing to a field whose value value_or_regex must be used against
389
-
390
- def initialize(expected, value_or_regex, flow_field)
391
- @expected = expected
392
- @value_or_regex = value_or_regex
393
-
394
- @flow_field = flow_field
395
- raise ":flow_field must be of class FlowField" unless @flow_field.class == FlowField
396
- end
397
-
398
- def to_s
399
- s = ""
400
- s += "Flow verifier : expected : #{@expected}. Value/regex : #{@value_or_regex.inspect}. Field : #{@flow_field}"
401
- s
402
- end
403
-
404
- def verify(actual)
405
- puts "now in verify for FlowVerify for field #{@flow_field} against value #{@value_or_regex}"
406
-
407
- case @value_or_regex # case is better, leaves room for other options depending on class
408
- when Regexp
409
- match = !!(actual =~ @value_or_regex) # double-invert to convert to true-or-false
410
- else
411
- match = (actual == @value_or_regex)
412
- end
413
- if @expected
414
- message = "FlowVerify failed. Expected the value to match #{@value_or_regex.inspect} but was actually #{actual.inspect}"
415
- else
416
- message = "FlowVerify failed. Expected the value #{@value_or_regex.inspect} to be different to the actual value of #{actual.inspect}"
417
- end
418
- puts "about to assert; #{actual.inspect} == #{@value_or_regex.inspect} => #{@expected == match}"
419
- assert_equal(@expected, match, message)
420
- puts "assertion passed"
421
- end
422
-
423
- end
424
-
425
- # A class defining feedback to be returned after invoking the flow.
426
- # TODO : rework this so that it knows how to gather the required information (?)
427
- class FlowReport
428
-
429
- # attr_accessor :success, :message, :value_hash_array
430
- # # success is a boolean
431
- # # message is a string
432
- # # value_hash_array is an array of hashes, one per object/event/thing. Its keys are the object's fields, and the
433
- # values
434
- ## are their values
435
- #
436
- # def initialize(success, message, value_hash_array)
437
- # @success = success
438
- # @message = message
439
- # @value_hash_array = value_hash_array
440
- # end
441
- #
442
- # def to_s
443
- # s = ""
444
- # s += "Flow report : success? #{@success}. Message : #{@message}. Values : #{@value_hash_array}"
445
- # s
446
- # end
447
-
448
- attr_accessor :value
449
-
450
- def initialize(value = nil)
451
- # do nothing?
452
- @value = value
453
- end
454
-
455
- def to_s
456
- s = ""
457
- s += "Flow report : value : #{@value}"
458
- s
459
- end
460
-
461
- def generate_report
462
- #TODO
463
- ""
464
- end
465
-
466
- end
@@ -1,15 +0,0 @@
1
- # List of constants that store names of flows
2
- # Names are stored as symbols
3
-
4
- class XXabbrevupperxxFN
5
-
6
- # Homepage
7
- GOTO_HOMEPAGE = :goto_homepage
8
-
9
- # Users
10
- VIEW_ALL_USERS = :view_all_users
11
- VIEW_USER = :view_user
12
- CREATE_USER = :create_user
13
- DELETE_USER = :delete_user
14
-
15
- end
@@ -1,117 +0,0 @@
1
- # A class defining the UI flows within ZZnamezz, such that simple usecase-esq methods arise from them and can
2
- # perform a series of UI actions (making a record, viewing & deleting, etc.)
3
-
4
- # The intended use is that the test (or supporting framework) call @flow.flow_name, e.g. @flow.create_project, which will
5
- # perform all of the actions of that flow. Parameters can be supplied to the call, which will change its behaviour
6
-
7
- require_relative 'flow_objects'
8
- require_relative 'xxabbrevxx_flow_names'
9
-
10
- class XXabbrevupperxxFlows
11
-
12
- attr_accessor :flows # array of Flow objects
13
- attr_accessor :flow_names # array of names of known Flow objects
14
-
15
-
16
- # Assembles all of the flows and stores them, ready for use
17
- def initialize
18
- @flows = [] # an array of Flow objects
19
- @flow_names = []
20
-
21
- # Simple nav flow to get to the homepage
22
- flow = Flow.new(XXabbrevupperxxFN::GOTO_HOMEPAGE)
23
- flow.add(FlowLink.new("goto_homepage", "xxabbrevxx_home_header_link", nil)) # no parent page, is valid from any page
24
- add_flow(flow)
25
-
26
- # View all users
27
- flow = new_base_flow(XXabbrevupperxxFN::VIEW_ALL_USERS)
28
- flow.add(FlowLink.new("all_users", "users_header_link", nil))
29
- add_flow(flow)
30
-
31
- # Create user
32
- flow = new_base_flow(XXabbrevupperxxFN::CREATE_USER)
33
- add_existing_flow_to_flow(flow, XXabbrevupperxxFN::VIEW_ALL_USERS)
34
-
35
- flow.add(FlowLink.new("all_users", "users_header_link", nil))
36
- flow.add(FlowLink.new("create_user", "new_user_link", "all_users"))
37
- field_flow = Flow.new("create_user_fields")
38
-
39
- field_flow.add(FlowField.new("user_name"))
40
- field_flow.add(FlowField.new("user_role", :list, :write, true, nil, ZZnamezzConfig::ALL_USER_ROLES))
41
-
42
- flow.add(field_flow)
43
- flow.add(FlowField.new("save", :button))
44
-
45
- message = FlowField.new("notice", :p, :read)
46
- flow.add(FlowVerify.new(true, "User was successfully created.", message))
47
-
48
- add_flow(flow)
49
- end
50
-
51
-
52
- ##############################################################################
53
-
54
-
55
- def method_missing(name, *args, &block)
56
- puts "XXabbrevupperxxFlows method_missing called; name = #{name.inspect}; #{name.class}"
57
-
58
- if flow_known(name)
59
- puts "Flow #{name} is known"
60
- # TODO define a whole bunch of methods and then perform them
61
- # If args and/or block have been provided, process them. E.g. one arg could be a trigger to perform the flow with
62
- # invalid values # TODO : is that the best way of doing that?
63
- else
64
- super
65
- end
66
- end
67
-
68
- def add_flow(flow)
69
- @flows << flow
70
- @flow_names << flow.name
71
- end
72
-
73
- # TODO needed?
74
- def ==(o)
75
- end
76
-
77
- # TODO needed?
78
- def to_s
79
- s = ""
80
- s += "#{@flows.size} flows defined. Names :"
81
- @flow_names.each {|f| s += "\n#{f}" }
82
- s
83
- end
84
-
85
- # Will convert name to a string
86
- def flow_known?(name)
87
- @flow_names.include?(name)
88
- end
89
-
90
- # Retrieves the specific flow; raises if it cannot be found
91
- # Will convert name to a string
92
- def find(name)
93
- raise "Could not locate flow '#{name}'" unless flow_known?(name)
94
- @flows[@flow_names.index(name)]
95
- end
96
-
97
- # Finds & executes a flow
98
- def find_and_execute(browser, name, custom_values_hash = {}, success_sym = :success, mandatory_fields_sym = :mandatory)
99
- f = find(name)
100
- f.execute(browser, custom_values_hash, success_sym, mandatory_fields_sym)
101
- end
102
-
103
- # Adds an already-existing flow to the supplied flow
104
- def add_existing_flow_to_flow(new_flow, existing_flow_name)
105
- # TODO : need deduplication mechanism so that a flow doesn't gain two/more duplicate flow items in a row (e.g. two calls to GOTO_HOMEPAGE in a row)
106
- new_flow.add(find(existing_flow_name))
107
- end
108
-
109
- # Shortcut to define a new flow with standard prerequisite flows already added
110
- # Cannot be called until the flows that are to be added have been defined
111
- def new_base_flow(name)
112
- flow = Flow.new(name)
113
- add_existing_flow_to_flow(flow, XXabbrevupperxxFN::GOTO_HOMEPAGE)
114
- flow
115
- end
116
-
117
- end