watirmark 5.14.16
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.
- data/app_generators/create_project/create_project_generator.rb +115 -0
- data/app_generators/create_project/templates/features/env.rb.erb +8 -0
- data/app_generators/create_project/templates/features/model_steps.rb.erb +9 -0
- data/app_generators/create_project/templates/features/post_error_steps.rb.erb +15 -0
- data/app_generators/create_project/templates/features/sample.feature.erb +5 -0
- data/app_generators/create_project/templates/features/site_steps.rb.erb +7 -0
- data/app_generators/create_project/templates/generators/controller.rb.erb +9 -0
- data/app_generators/create_project/templates/generators/generate.rb.erb +9 -0
- data/app_generators/create_project/templates/generators/model.rb.erb +7 -0
- data/app_generators/create_project/templates/generators/mvc_generator.rb.erb +100 -0
- data/app_generators/create_project/templates/generators/rbeautify.rb.erb +212 -0
- data/app_generators/create_project/templates/generators/view.rb.erb +16 -0
- data/app_generators/create_project/templates/generators/workflow_loader.rb.erb +1 -0
- data/app_generators/create_project/templates/library/base_controller.rb.erb +9 -0
- data/app_generators/create_project/templates/library/base_view.rb.erb +6 -0
- data/app_generators/create_project/templates/library/configuration.rb.erb +6 -0
- data/app_generators/create_project/templates/library/core_libraries.rb.erb +9 -0
- data/app_generators/create_project/templates/library/loader.rb.erb +23 -0
- data/app_generators/create_project/templates/library/page_load_checker.rb.erb +11 -0
- data/app_generators/create_project/templates/library/post_errors_checker.rb.erb +23 -0
- data/app_generators/create_project/templates/library/project_require_file.rb.erb +8 -0
- data/app_generators/create_project/templates/library/search_controller.rb.erb +12 -0
- data/app_generators/create_project/templates/library/workflows.rb.erb +0 -0
- data/app_generators/create_project/templates/project/config.yml.erb +3 -0
- data/app_generators/create_project/templates/project/gemfile.rb.erb +11 -0
- data/app_generators/create_project/templates/project/rakefile.rb.erb +21 -0
- data/bin/etapestry/Gemfile +11 -0
- data/bin/etapestry/config.yml +3 -0
- data/bin/etapestry/features/etapestry_home.feature +5 -0
- data/bin/etapestry/features/step_definitions/model_steps.rb +9 -0
- data/bin/etapestry/features/step_definitions/post_error_steps.rb +15 -0
- data/bin/etapestry/features/step_definitions/site_steps.rb +7 -0
- data/bin/etapestry/features/support/env.rb +8 -0
- data/bin/etapestry/generators/mvc/mvc_generator.rb +100 -0
- data/bin/etapestry/generators/mvc/rbeautify.rb +212 -0
- data/bin/etapestry/generators/mvc/templates/controller.rb.erb +9 -0
- data/bin/etapestry/generators/mvc/templates/model.rb.erb +7 -0
- data/bin/etapestry/generators/mvc/templates/view.rb.erb +16 -0
- data/bin/etapestry/generators/mvc/templates/workflow_loader.rb.erb +1 -0
- data/bin/etapestry/lib/etapestry.rb +8 -0
- data/bin/etapestry/lib/etapestry/checkers/page_load_checker.rb +11 -0
- data/bin/etapestry/lib/etapestry/checkers/post_errors_checker.rb +23 -0
- data/bin/etapestry/lib/etapestry/configuration.rb +6 -0
- data/bin/etapestry/lib/etapestry/core_libraries.rb +9 -0
- data/bin/etapestry/lib/etapestry/loader.rb +23 -0
- data/bin/etapestry/lib/etapestry/site/base_controller.rb +9 -0
- data/bin/etapestry/lib/etapestry/site/base_view.rb +6 -0
- data/bin/etapestry/lib/etapestry/site/search_controller.rb +12 -0
- data/bin/etapestry/lib/etapestry/workflows.rb +0 -0
- data/bin/etapestry/rakefile.rb +21 -0
- data/bin/etapestry/script/generate.rb +9 -0
- data/bin/twitter/features/hashtag_search.feature +93 -0
- data/bin/twitter/features/step_definitions/hashtag_steps.rb +9 -0
- data/bin/twitter/lib/twitter/workflows/search/result_controller.rb +13 -0
- data/bin/twitter/lib/twitter/workflows/search/result_model.rb +5 -0
- data/bin/twitter/lib/twitter/workflows/search/result_view.rb +19 -0
- data/bin/watirmark +10 -0
- data/lib/watirmark.rb +26 -0
- data/lib/watirmark/at_exit.rb +13 -0
- data/lib/watirmark/configuration.rb +201 -0
- data/lib/watirmark/controller/actions.rb +172 -0
- data/lib/watirmark/controller/assertions.rb +116 -0
- data/lib/watirmark/controller/controller.rb +191 -0
- data/lib/watirmark/controller/dialogs.rb +33 -0
- data/lib/watirmark/controller/matcher.rb +19 -0
- data/lib/watirmark/cucumber/cuke_helper.rb +150 -0
- data/lib/watirmark/cucumber/email_helper.rb +103 -0
- data/lib/watirmark/cucumber/env.rb +9 -0
- data/lib/watirmark/cucumber/hooks.rb +16 -0
- data/lib/watirmark/cucumber/model_helper.rb +34 -0
- data/lib/watirmark/cucumber/transforms.rb +55 -0
- data/lib/watirmark/exceptions.rb +15 -0
- data/lib/watirmark/extensions/ruby_extensions.rb +129 -0
- data/lib/watirmark/extensions/webdriver_extensions.rb +150 -0
- data/lib/watirmark/formatters/snapshot_formatter.rb +23 -0
- data/lib/watirmark/loader.rb +87 -0
- data/lib/watirmark/model.rb +3 -0
- data/lib/watirmark/models/cucumber_helper.rb +49 -0
- data/lib/watirmark/models/debug_methods.rb +21 -0
- data/lib/watirmark/models/default_values.rb +21 -0
- data/lib/watirmark/models/factory.rb +168 -0
- data/lib/watirmark/models/factory_method_generators.rb +84 -0
- data/lib/watirmark/models/factory_methods.rb +72 -0
- data/lib/watirmark/models/trait.rb +35 -0
- data/lib/watirmark/models/upload_csv.rb +24 -0
- data/lib/watirmark/page/keyed_element.rb +63 -0
- data/lib/watirmark/page/page.rb +50 -0
- data/lib/watirmark/page/page_definition.rb +187 -0
- data/lib/watirmark/page/process_page.rb +112 -0
- data/lib/watirmark/page/radio_maps.rb +53 -0
- data/lib/watirmark/profile.rb +22 -0
- data/lib/watirmark/rake/smoketest.rb +17 -0
- data/lib/watirmark/screenshot.rb +127 -0
- data/lib/watirmark/session.rb +115 -0
- data/lib/watirmark/version.rb +5 -0
- data/spec/assertions_spec.rb +95 -0
- data/spec/config_spec.rb +82 -0
- data/spec/controller_actions_spec.rb +91 -0
- data/spec/controller_spec.rb +426 -0
- data/spec/controllers_and_models_spec.rb +52 -0
- data/spec/model_factory_spec.rb +568 -0
- data/spec/model_traits_spec.rb +141 -0
- data/spec/page_spec.rb +127 -0
- data/spec/process_page_spec.rb +163 -0
- data/spec/spec_helper.rb +17 -0
- metadata +238 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Watirmark
|
|
2
|
+
module Dialogs
|
|
3
|
+
def modal_exists?
|
|
4
|
+
!!(Page.browser.windows.size > 1)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def with_modal_dialog(&block)
|
|
8
|
+
wait_for_modal_dialog
|
|
9
|
+
parent_window = (Page.browser.windows.size) - 2
|
|
10
|
+
begin
|
|
11
|
+
Page.browser.windows.last.use
|
|
12
|
+
Page.browser.wait
|
|
13
|
+
block.call
|
|
14
|
+
ensure
|
|
15
|
+
Page.browser.windows[parent_window].use
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def wait_for_modal_dialog
|
|
20
|
+
begin
|
|
21
|
+
Timeout::timeout(30) {
|
|
22
|
+
until modal_exists?
|
|
23
|
+
sleep 0.002
|
|
24
|
+
end
|
|
25
|
+
Page.browser.wait
|
|
26
|
+
sleep 0.02
|
|
27
|
+
}
|
|
28
|
+
rescue Timeout::Error
|
|
29
|
+
raise Watirmark::TestError, 'Timed out while waiting for modal dialog to open'
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Watirmark
|
|
2
|
+
class Matcher
|
|
3
|
+
class << self
|
|
4
|
+
@@matchers = {}
|
|
5
|
+
|
|
6
|
+
def add_matcher(name, &block)
|
|
7
|
+
@@matchers[name] = block
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def exists?(name)
|
|
11
|
+
@@matchers.has_key?(name)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def matches?(element, expected, actual)
|
|
15
|
+
instance_exec(element, actual, &@@matchers[expected])
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
require_relative '../models/cucumber_helper'
|
|
2
|
+
|
|
3
|
+
module CukeHelper
|
|
4
|
+
include Watirmark::Model::CucumberHelper
|
|
5
|
+
|
|
6
|
+
def log
|
|
7
|
+
Watirmark::Configuration.instance.logger
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def eval_keywords(hash)
|
|
11
|
+
hash.each do |key, value|
|
|
12
|
+
hash[key] = format_value(value)
|
|
13
|
+
end
|
|
14
|
+
hash
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# when the input is an array, eval each element
|
|
18
|
+
def eval_raw_record(row)
|
|
19
|
+
row.each_index do |col|
|
|
20
|
+
row[col] = format_value(row[col])
|
|
21
|
+
end
|
|
22
|
+
row
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# calls the models method if of the pattern <name>.method
|
|
26
|
+
def call_model_methods(hash)
|
|
27
|
+
hash.each { |key, value| hash[key] = eval(value[1..value.length]) if value[0, 1].eql?("=") }
|
|
28
|
+
hash
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# return {:foo=1, :bar=2} from {'foo' =>1, 'bar' =>2}
|
|
32
|
+
def colonize(hash)
|
|
33
|
+
newhash = {}
|
|
34
|
+
hash.each { |k, v| newhash[k.to_sym] = v }
|
|
35
|
+
newhash
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# returns [{:foo=1, :bar=2}, {:foo=3, :bar=4}] list of hash records
|
|
39
|
+
# from table table where first row headers are keys and each row values
|
|
40
|
+
# | foo | bar |
|
|
41
|
+
# | 1 | 2 |
|
|
42
|
+
# | 3 | 4 |
|
|
43
|
+
def hash_record_list table
|
|
44
|
+
table.map_headers! { |h| h.to_sym }
|
|
45
|
+
records = table.hashes
|
|
46
|
+
records.map { |record| eval_keywords(record) }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# returns {:foo=1, :bar=2} hash record
|
|
50
|
+
# from a key, value 2 column table
|
|
51
|
+
# | foo | 1 |
|
|
52
|
+
# | bar | 2 |
|
|
53
|
+
def hash_record table
|
|
54
|
+
colonize eval_keywords(table.rows_hash)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# returns .raw but still handles eval-ing the keywords
|
|
58
|
+
def raw_record table
|
|
59
|
+
table.raw.map { |record| eval_raw_record(record) }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#Given a list of keys or strings (call it key), return a string composed of
|
|
63
|
+
#record_hash[key] or the string is key isn't really a key. Yea, screwy I know
|
|
64
|
+
def compose_string_from(record_hash, key_list)
|
|
65
|
+
result = ''
|
|
66
|
+
key_list.each do |key|
|
|
67
|
+
if record_hash[key]
|
|
68
|
+
result += record_hash[key]
|
|
69
|
+
elsif key.is_a? String
|
|
70
|
+
result += key
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
result
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Allows expected values for a cucumber table field to be different
|
|
77
|
+
# based on whether you are using Service Bus or DataSync. Use case is
|
|
78
|
+
# for a bug in DataSync that was not replicated in Service Bus
|
|
79
|
+
# In this example: DataSync incorrectly assigns 'Donation' and Service
|
|
80
|
+
# Bus correctly assigns 'TeamRaiser Gift' to transaction type field
|
|
81
|
+
# # VERIFY ---------------+-------------------------------------------+
|
|
82
|
+
# | accountname | Tr01_Hellraiser Eventdonor Household |
|
|
83
|
+
# | type | Individual Gift |
|
|
84
|
+
# | transactiontype | =syncmode('TeamRaiser Gift','Donation') |
|
|
85
|
+
def syncmode(expected_bus, expected_datasync)
|
|
86
|
+
if ENV['SYNCMODE'] == 'DataSync'
|
|
87
|
+
expected_datasync
|
|
88
|
+
else
|
|
89
|
+
expected_bus
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# if a block provided raises VerificationException we verify again
|
|
94
|
+
# this method acts as a gateway to prevent false negatives in testing CRM objects that we expect to change their values after being
|
|
95
|
+
# updated by the service bus
|
|
96
|
+
# motivation:
|
|
97
|
+
# After serivce bus sends a message to a CRM it takes a while sometimes for the updates to the object to occur.
|
|
98
|
+
# When we verify the state of the object we may still look at old values.
|
|
99
|
+
# We want to introduce a pooling mechanism that would re-verify one or more times after a duration of time
|
|
100
|
+
# and only fail after the specified count of tries.
|
|
101
|
+
# usage:
|
|
102
|
+
# verify_failure { controller.verify } #=> provide block that can fail with VerificationException
|
|
103
|
+
def verify_failure(tries_count=6, seconds_between_tries=30)
|
|
104
|
+
counter = 0
|
|
105
|
+
loop do
|
|
106
|
+
counter += 1
|
|
107
|
+
begin
|
|
108
|
+
yield
|
|
109
|
+
rescue Watirmark::VerificationException => e
|
|
110
|
+
Watirmark.logger.warn "*** reverifying failure: #{e}"
|
|
111
|
+
raise e if counter >= tries_count
|
|
112
|
+
sleep seconds_between_tries
|
|
113
|
+
else
|
|
114
|
+
break
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# given a hash and list of keys, make the values into a float if they exist
|
|
120
|
+
# FIXME: this is a work around until the Cucumber tests use a new matcher
|
|
121
|
+
# in convio_watir by making strings into floats
|
|
122
|
+
#
|
|
123
|
+
# record={:amountreceived => "10.00", :probability => "100"}
|
|
124
|
+
# floatify(record, [:amountreceived, :probability])
|
|
125
|
+
# changes record into
|
|
126
|
+
# record={:amountreceived => 10.0, :probability => 100.0}
|
|
127
|
+
def floatify(record_hash, key_list)
|
|
128
|
+
key_list.each do |key|
|
|
129
|
+
record_hash[key] = record_hash[key].to_f if record_hash[key]
|
|
130
|
+
end
|
|
131
|
+
record_hash
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# merges sequentially a list of hashes
|
|
135
|
+
def multimerge *hashes
|
|
136
|
+
hashes.inject({}) { |memo, hash| hash.nil? ? memo : memo.merge(hash) }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def create_ts(with_separators=true)
|
|
140
|
+
if with_separators
|
|
141
|
+
Time.now.strftime "%Y:%m:%d:%H:%M:%S"
|
|
142
|
+
else
|
|
143
|
+
Time.now.strftime "%Y%m%d%H%M%S"
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
module EmailHelper
|
|
2
|
+
|
|
3
|
+
# Access the list of emails we've read and cached
|
|
4
|
+
def emails
|
|
5
|
+
EmailCollection
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Parse the email body into an object
|
|
9
|
+
def email_body(body)
|
|
10
|
+
EmailBody.new(body)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class EmailCollection
|
|
14
|
+
class << self
|
|
15
|
+
def email
|
|
16
|
+
@email ||= {}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Connect to the INBOX
|
|
20
|
+
def qa_inbox(model)
|
|
21
|
+
WatirmarkEmail::QAMail.new(email_address(model) )
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Return an email if we've seen it
|
|
25
|
+
def found_email(model)
|
|
26
|
+
email[model.model_name]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Read the contents of an email, cache it and delete the email
|
|
30
|
+
def read_email(model, subject, timeout=30)
|
|
31
|
+
email_content = qa_inbox(model).get_email_text(["SUBJECT", subject, "TO", model.email], timeout)
|
|
32
|
+
email[model.model_name] = EmailBody.new(email_content)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def log_email(model)
|
|
36
|
+
Watirmark.logger.info "Email Received"
|
|
37
|
+
Watirmark.logger.info email[model.model_name].body.inspect
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Access a cached copy of an email
|
|
41
|
+
def [](model)
|
|
42
|
+
email[model.model_name]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Remove our cached copy of the email
|
|
46
|
+
def delete(model)
|
|
47
|
+
email[model.model_name] = nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Format the email address so we're always referring to the qasendmail domain
|
|
51
|
+
def email_address(model)
|
|
52
|
+
model.email.gsub(/\+.+/,'').gsub(/@.+/, '@qasendmail.corp.convio.com')
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
class EmailLink
|
|
58
|
+
attr_accessor :href, :text
|
|
59
|
+
|
|
60
|
+
def initialize(doc)
|
|
61
|
+
@href = doc['href']
|
|
62
|
+
@text = doc.content
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
class EmailBody
|
|
67
|
+
attr_accessor :doc, :body
|
|
68
|
+
|
|
69
|
+
def initialize(body)
|
|
70
|
+
@body = body
|
|
71
|
+
@doc = ::Nokogiri::HTML.parse body
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def links
|
|
75
|
+
unless @links
|
|
76
|
+
@links = []
|
|
77
|
+
@doc.xpath('//a').each do |link|
|
|
78
|
+
@links << EmailLink.new(link)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
@links
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def link(how, matcher)
|
|
85
|
+
links.each do |link|
|
|
86
|
+
case how
|
|
87
|
+
when :text
|
|
88
|
+
return link if /#{matcher}/.matches link.text
|
|
89
|
+
when :href
|
|
90
|
+
return link if /#{matcher}/.matches link.href
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
nil
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def inspect
|
|
97
|
+
@doc.to_s
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require 'watirmark/cucumber/cuke_helper'
|
|
2
|
+
require 'watirmark/cucumber/email_helper'
|
|
3
|
+
require 'watirmark/cucumber/model_helper'
|
|
4
|
+
require 'watirmark/cucumber/transforms'
|
|
5
|
+
require 'watirmark/cucumber/hooks'
|
|
6
|
+
|
|
7
|
+
World CukeHelper
|
|
8
|
+
World EmailHelper
|
|
9
|
+
World ModelHelper
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Around('@catch-post-failure') do |scenario, block|
|
|
2
|
+
Watirmark::Session.instance.catch_post_failures(&block)
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
# Initialize post failures so we don't get leakage between scenarios
|
|
6
|
+
Before('~@catch-post-failure') do
|
|
7
|
+
Watirmark::Session.instance.post_failure = nil
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
After do |scenario|
|
|
11
|
+
image = "#{Time.now.to_i}-#{UUID.new.generate(:compact)}.png"
|
|
12
|
+
path = "reports/screenshots"
|
|
13
|
+
FileUtils.mkdir_p path unless File.directory? path
|
|
14
|
+
Page.browser.screenshot.save "#{path}/#{image}"
|
|
15
|
+
embed "screenshots/#{image}", 'image/png'
|
|
16
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module ModelHelper
|
|
2
|
+
def add_model_debug_values(table)
|
|
3
|
+
table.raw.each do |row|
|
|
4
|
+
DebugModelValues[row[0]][row[1]] = row[2]
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def update_model(model, table)
|
|
9
|
+
model.update(hash_record(table))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def with_updated_model(model, table, &block)
|
|
13
|
+
unless model.includes?(hash_record(table))
|
|
14
|
+
update_model(model, table)
|
|
15
|
+
block.call
|
|
16
|
+
Watirmark.logger.info "Updated models '#{model.model_name}':\n#{hash_record(table).inspect}"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Perform an action using a models and update
|
|
21
|
+
# the models if that action is successful
|
|
22
|
+
def with_model(model, table, &block)
|
|
23
|
+
orig_model = model.clone
|
|
24
|
+
update_model(model, table)
|
|
25
|
+
block.call
|
|
26
|
+
if Watirmark::Session.instance.post_failure
|
|
27
|
+
Watirmark.logger.info "Reverting Model #{Watirmark::Session.instance.post_failure}"
|
|
28
|
+
model.update(orig_model.to_h) # revert models on failure
|
|
29
|
+
elsif model.to_h != orig_model.to_h
|
|
30
|
+
Watirmark.logger.info "Updated model '#{model.model_name}' #{hash_record(table).inspect}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# This is a globally accessible static hash to
|
|
2
|
+
# store all models declared by the test automation. Making it available
|
|
3
|
+
# allows us to use the models values as table parameters in the gherkin!
|
|
4
|
+
DataModels = {}
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module Watirmark
|
|
8
|
+
module Transforms
|
|
9
|
+
class << self
|
|
10
|
+
def new_model model_name, user_defined_name
|
|
11
|
+
if model_exists?(user_defined_name) && !temporary_model?(user_defined_name)
|
|
12
|
+
DataModels[user_defined_name]
|
|
13
|
+
else
|
|
14
|
+
DataModels[user_defined_name] = model_class(model_name).new(:model_name => user_defined_name)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def model_exists?(name)
|
|
21
|
+
DataModels.key?(name)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def model_class(name)
|
|
25
|
+
model_class_name(name).split('::').inject(Kernel) {|context, x| context.const_get x}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def model_class_name(name)
|
|
29
|
+
"#{name.split.map(&:camelize).join}Model"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def temporary_model?(user_defined_name)
|
|
33
|
+
DataModels[user_defined_name].kind_of?(ModelOpenStruct)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Create a new models and add it to the DataModels hash
|
|
40
|
+
NEW_MODEL = Transform /^\[new (\S+) (\S+)\]$/ do |model_name, user_defined_name|
|
|
41
|
+
model_name.chop! if model_name.end_with?(':')
|
|
42
|
+
Watirmark::Transforms.new_model model_name, user_defined_name
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
OLD_STYLE_MODEL = Transform /^\[new ([^:]+): (\S+)\]$/ do |model_name, user_defined_name|
|
|
46
|
+
model_name = model_name.camelize
|
|
47
|
+
model_name.chop! if model_name.end_with?(':')
|
|
48
|
+
Watirmark::Transforms.new_model model_name, user_defined_name
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Return the models from the collection of existing models
|
|
52
|
+
MODEL = Transform /^\[(\S+)\]$/ do |model_name|
|
|
53
|
+
DataModels[model_name] ||= ModelOpenStruct.new(:model_name => model_name)
|
|
54
|
+
end
|
|
55
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Watirmark
|
|
2
|
+
class Watirmark::MatcherNotFound < RuntimeError ;end
|
|
3
|
+
class Watirmark::TestError < RuntimeError ;end
|
|
4
|
+
class Watirmark::TestFailure < RuntimeError ;end
|
|
5
|
+
class Watirmark::PostFailure < RuntimeError ;end
|
|
6
|
+
class Watirmark::TDPage < RuntimeError; end
|
|
7
|
+
class Watirmark::SecurityIssue < RuntimeError; end
|
|
8
|
+
class Watirmark::WebPageElementNotFound < RuntimeError ;end
|
|
9
|
+
class Watirmark::ModelNotFound < RuntimeError ;end
|
|
10
|
+
class Watirmark::ModelCreationError < RuntimeError ;end
|
|
11
|
+
class Watirmark::InvalidConfigurationFile < RuntimeError ;end
|
|
12
|
+
class Watirmark::VerificationException < RuntimeError
|
|
13
|
+
attr_accessor :actual, :expected
|
|
14
|
+
end
|
|
15
|
+
end
|