testable 0.5.0 → 0.6.0
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 +5 -5
- data/.gitignore +4 -0
- data/README.md +17 -1
- data/examples/testable-watir-test.rb +15 -2
- data/lib/testable/deprecator.rb +40 -0
- data/lib/testable/extensions/data_setter.rb +36 -1
- data/lib/testable/logger.rb +16 -0
- data/lib/testable/page.rb +1 -1
- data/lib/testable/version.rb +1 -1
- data/lib/testable.rb +102 -0
- data/testable.gemspec +3 -1
- metadata +10 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 55d21339896a1676d7a2b36d9942d3a80f474d40
|
4
|
+
data.tar.gz: 7c796814221cbdcd10f614c4f0736ac7792bdb93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7f461b5083946eb8e524ab30ac5e2b33ffad2ac78f89cd8e08b107dee053cdbffdf54ee545039f675366f6de06d613b0ed03517c21b53ec5484a213e7720536
|
7
|
+
data.tar.gz: a1e611dd2294fdd506595192bd7d17915fe0b4ae3dc490d59c5886c760b2cc10d3a352ff8d9cda84a4ac65628fd0f553e9c1b7ba0de90c548d6f4e98c5012876
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -8,6 +8,12 @@
|
|
8
8
|
|
9
9
|
----
|
10
10
|
|
11
|
+
[](http://badge.fury.io/rb/testable)
|
12
|
+
[](https://github.com/jeffnyman/testable/blob/master/LICENSE.md)
|
13
|
+
|
14
|
+
[](http://rubydoc.info/github/jeffnyman/testable/master/frames)
|
15
|
+
[](http://inch-ci.org/github/jeffnyman/github)
|
16
|
+
|
11
17
|
Testable is an automated test micro-framework that provides a thin wrapper around [Watir](http://watir.com/) and [Capybara](http://teamcapybara.github.io/capybara/). Testable is based on many ideas from tools like [SitePrism](https://github.com/natritmeyer/site_prism) and [Watirsome](https://github.com/p0deje/watirsome), while also being a logical evolution of my own tool, [Tapestry](https://github.com/jeffnyman/tapestry).
|
12
18
|
|
13
19
|
One of the core goals of Testable is to be a mediating influence between higher-level tests (acceptance criteria) and lower-level implementations of those tests. You can see some of the design principles for more details on what guided construction.
|
@@ -36,7 +42,17 @@ You can also install Testable just as you would any other gem:
|
|
36
42
|
|
37
43
|
## Usage
|
38
44
|
|
39
|
-
|
45
|
+
Probably the best way to get a feel for the current state of the code is to look at the examples:
|
46
|
+
|
47
|
+
* [Testable Info](https://github.com/jeffnyman/testable/blob/master/examples/testable-info.rb)
|
48
|
+
* [Testable Basics](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir.rb)
|
49
|
+
* [Testable Watir](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir-test.rb)
|
50
|
+
* [Testable Context](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir-context.rb)
|
51
|
+
* [Ready script](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir-ready.rb)
|
52
|
+
* [Events script](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir-events.rb)
|
53
|
+
* [Data setter script](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir-datasetter.rb)
|
54
|
+
|
55
|
+
You'll see references to "Veilus" and a "localhost" in the script. I'm using my own [Veilus application](https://veilus.herokuapp.com/). As far as the localhost, you can use the [Veilus repo](https://github.com/jeffnyman/veilus) to get a local copy to play around with.
|
40
56
|
|
41
57
|
## Design Principles
|
42
58
|
|
@@ -2,9 +2,7 @@
|
|
2
2
|
$LOAD_PATH << "./lib"
|
3
3
|
|
4
4
|
require "rspec"
|
5
|
-
# rubocop:disable Style/MixinUsage
|
6
5
|
include RSpec::Matchers
|
7
|
-
# rubocop:enable Style/MixinUsage
|
8
6
|
|
9
7
|
require "testable"
|
10
8
|
|
@@ -46,6 +44,21 @@ end
|
|
46
44
|
|
47
45
|
Testable.start_browser :firefox
|
48
46
|
|
47
|
+
# Will default to UNKNOWN.
|
48
|
+
puts Testable.log_level
|
49
|
+
|
50
|
+
# Will not actually log.
|
51
|
+
Testable.logger.info("Testing an info log message.")
|
52
|
+
|
53
|
+
# Change the log.
|
54
|
+
Testable.log_level = :debug
|
55
|
+
|
56
|
+
# Will actually log.
|
57
|
+
Testable.logger.debug("Testing a debug log message.")
|
58
|
+
|
59
|
+
# Sets the Watir wire protocol level logging.
|
60
|
+
Testable.wire_level_logging = :info
|
61
|
+
|
49
62
|
page = Home.new
|
50
63
|
|
51
64
|
page.visit
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Testable
|
2
|
+
class Deprecator
|
3
|
+
class << self
|
4
|
+
def deprecate(current, upcoming = nil, known_version = nil)
|
5
|
+
if upcoming
|
6
|
+
warn(
|
7
|
+
"#{current} is being deprecated and should no longer be used. \
|
8
|
+
Use #{upcoming} instead."
|
9
|
+
)
|
10
|
+
else
|
11
|
+
warn("#{current} is being deprecated and should no longer be used.")
|
12
|
+
end
|
13
|
+
|
14
|
+
warn(
|
15
|
+
"#{current} will be removed in Testable #{known_version}."
|
16
|
+
) if known_version
|
17
|
+
end
|
18
|
+
|
19
|
+
def soft_deprecate(current, reason, known_version, upcoming = nil)
|
20
|
+
debug("The #{current} method is changing and is now configurable.")
|
21
|
+
debug("REASON: #{reason}.")
|
22
|
+
debug(
|
23
|
+
"Moving forwards into Testable #{known_version}, \
|
24
|
+
the default behavior will change."
|
25
|
+
)
|
26
|
+
debug("It is advised that you change to using #{upcoming}") if upcoming
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def warn(message)
|
32
|
+
Testable.logger.warn(message)
|
33
|
+
end
|
34
|
+
|
35
|
+
def debug(message)
|
36
|
+
Testable.logger.debug(message)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -59,7 +59,7 @@ module Testable
|
|
59
59
|
# Here "warp factor" would be converted to "warp_factor".
|
60
60
|
def using(data)
|
61
61
|
data.each do |key, value|
|
62
|
-
use_data_with(key, value) if object_enabled_for(key)
|
62
|
+
use_data_with(key, value.to_s) if object_enabled_for(key)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
@@ -78,10 +78,41 @@ module Testable
|
|
78
78
|
# with. These aspects are what tie this particular implementation to
|
79
79
|
# Watir.
|
80
80
|
def use_data_with(key, value)
|
81
|
+
value = preprocess_value(value, key)
|
82
|
+
|
81
83
|
element = send(key.to_s.tr(' ', '_'))
|
82
84
|
set_and_select(key, element, value)
|
83
85
|
check_and_uncheck(key, element, value)
|
86
|
+
click(key, element)
|
87
|
+
end
|
88
|
+
|
89
|
+
# rubocop:disable Metrics/AbcSize
|
90
|
+
# rubocop:disable Metrics/MethodLength
|
91
|
+
def preprocess_value(value, key)
|
92
|
+
return value unless value =~ /\(\(.*\)\)/
|
93
|
+
|
94
|
+
starter = value.index("((")
|
95
|
+
ender = value.index("))")
|
96
|
+
qualifier = value[starter + 2, ender - starter - 2]
|
97
|
+
|
98
|
+
if qualifier == "random_large"
|
99
|
+
value[starter..ender + 1] = rand(1_000_000_000_000).to_s
|
100
|
+
elsif qualifier == "random_ssn"
|
101
|
+
value = rand(9**9).to_s.rjust(9, '0')
|
102
|
+
value.insert 5, "-"
|
103
|
+
value.insert 3, "-"
|
104
|
+
elsif qualifier == "random_selection"
|
105
|
+
list = chain("#{key}.options.to_a")
|
106
|
+
|
107
|
+
selected = list.sample.text
|
108
|
+
selected = list.sample.text if selected.nil?
|
109
|
+
value = selected
|
110
|
+
end
|
111
|
+
|
112
|
+
value
|
84
113
|
end
|
114
|
+
# rubocop:enable Metrics/AbcSize
|
115
|
+
# rubocop:enable Metrics/MethodLength
|
85
116
|
|
86
117
|
def set_and_select(key, element, value)
|
87
118
|
key = key.to_s.tr(' ', '_')
|
@@ -97,6 +128,10 @@ module Testable
|
|
97
128
|
chain("#{key}.uncheck") if element.class == Watir::CheckBox
|
98
129
|
end
|
99
130
|
|
131
|
+
def click(key, element)
|
132
|
+
chain("#{key}.click") if element.class == Watir::Label
|
133
|
+
end
|
134
|
+
|
100
135
|
# This is a sanity check method to make sure that whatever element is
|
101
136
|
# being used as part of the data setting, it exists in the DOM, is
|
102
137
|
# visible (meaning, display is not 'none'), and is capable of accepting
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "logger"
|
2
|
+
|
3
|
+
module Testable
|
4
|
+
class Logger
|
5
|
+
def create(output = $stdout)
|
6
|
+
logger = ::Logger.new(output)
|
7
|
+
logger.progname = 'Testable'
|
8
|
+
logger.level = :UNKNOWN
|
9
|
+
logger.formatter = proc do |severity, time, progname, msg|
|
10
|
+
"#{time.strftime('%F %T')} - #{severity} - #{progname} - #{msg}\n"
|
11
|
+
end
|
12
|
+
|
13
|
+
logger
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/testable/page.rb
CHANGED
@@ -67,7 +67,7 @@ module Testable
|
|
67
67
|
end
|
68
68
|
|
69
69
|
alias displayed? has_correct_url?
|
70
|
-
alias loaded?
|
70
|
+
alias loaded? has_correct_url?
|
71
71
|
|
72
72
|
# A call to `title_attribute` returns what the value of the `title_is`
|
73
73
|
# attribute is for the given definition. It's important to note that
|
data/lib/testable/version.rb
CHANGED
data/lib/testable.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require "testable/version"
|
2
2
|
require "testable/page"
|
3
3
|
require "testable/ready"
|
4
|
+
require "testable/logger"
|
4
5
|
require "testable/context"
|
5
6
|
require "testable/element"
|
6
7
|
require "testable/locator"
|
7
8
|
require "testable/attribute"
|
9
|
+
require "testable/deprecator"
|
8
10
|
|
9
11
|
require "testable/capybara/page"
|
10
12
|
|
@@ -41,6 +43,106 @@ module Testable
|
|
41
43
|
attr_accessor :browser
|
42
44
|
|
43
45
|
class << self
|
46
|
+
# Provides a means to allow a configure block on Testable. This allows you
|
47
|
+
# to setup Testable, as such:
|
48
|
+
#
|
49
|
+
# Testable.configure do |config|
|
50
|
+
# config.driver_timeout = 5
|
51
|
+
# config.wire_level_logging = :info
|
52
|
+
# config.log_level = :debug
|
53
|
+
# end
|
54
|
+
def configure
|
55
|
+
yield self
|
56
|
+
end
|
57
|
+
|
58
|
+
# Watir provides a default timeout of 30 seconds. This allows you to change
|
59
|
+
# that in the Testable context. For example:
|
60
|
+
#
|
61
|
+
# Testable.driver_timeout = 5
|
62
|
+
#
|
63
|
+
# This would equivalent to doing this:
|
64
|
+
#
|
65
|
+
# Watir.default_timeout = 5
|
66
|
+
def driver_timeout=(value)
|
67
|
+
Watir.default_timeout = value
|
68
|
+
end
|
69
|
+
|
70
|
+
# The Testable logger object. To log messages:
|
71
|
+
#
|
72
|
+
# Testable.logger.info('Some information.')
|
73
|
+
# Testable.logger.debug('Some diagnostics')
|
74
|
+
#
|
75
|
+
# To alter or check the current logging level, you can call `.log_level=`
|
76
|
+
# or `.log_level`. By default the logger will output all messages to the
|
77
|
+
# standard output ($stdout) but it can be altered to log to a file or to
|
78
|
+
# another IO location by calling `.log_path=`.
|
79
|
+
def logger
|
80
|
+
@logger ||= Testable::Logger.new.create
|
81
|
+
end
|
82
|
+
|
83
|
+
# To enable logging, do this:
|
84
|
+
#
|
85
|
+
# Testable.log_level = :DEBUG
|
86
|
+
# Testable.log_level = 'DEBUG'
|
87
|
+
# Testable.log_level = 0
|
88
|
+
#
|
89
|
+
# This can accept any of a Symbol / String / Integer as an input
|
90
|
+
# To disable all logging, which is the case by default, do this:
|
91
|
+
#
|
92
|
+
# Testable.log_level = :UNKNOWN
|
93
|
+
def log_level=(value)
|
94
|
+
logger.level = value
|
95
|
+
end
|
96
|
+
|
97
|
+
# To query what level is being logged, do this:
|
98
|
+
#
|
99
|
+
# Testable.log_level
|
100
|
+
#
|
101
|
+
# The logging level will be UNKNOWN by default.
|
102
|
+
def log_level
|
103
|
+
%i[DEBUG INFO WARN ERROR FATAL UNKNOWN][logger.level]
|
104
|
+
end
|
105
|
+
|
106
|
+
# The writer method allows you to configure where you want the output of
|
107
|
+
# the Testable logs to go, with the default being standard output. Here
|
108
|
+
# is how you could change this to a specific file:
|
109
|
+
#
|
110
|
+
# Testable.log_path = 'testable.log'
|
111
|
+
def log_path=(logdev)
|
112
|
+
logger.reopen(logdev)
|
113
|
+
end
|
114
|
+
|
115
|
+
# The wire logger provides logging from Watir, which is very similar to the
|
116
|
+
# logging provided by Selenium::WebDriver::Logger. The default level is set
|
117
|
+
# to warn. This means you will see any deprecation notices as well as any
|
118
|
+
# warning messages. To see details on each element interaction the level
|
119
|
+
# can be set to info. To see details on what Watir is doing when it takes a
|
120
|
+
# selector hash and converts it into XPath, the level can be set to debug.
|
121
|
+
# If you want to ignore specific warnings that are appearing during test
|
122
|
+
# execution:
|
123
|
+
#
|
124
|
+
# Watir.logger.ignore :warning_name
|
125
|
+
#
|
126
|
+
# If you want to ignore all deprecation warnings in your tests:
|
127
|
+
#
|
128
|
+
# Watir.logger.ignore :deprecations
|
129
|
+
#
|
130
|
+
# To have the wire logger generate output to a file:
|
131
|
+
#
|
132
|
+
# Watir.logger.output = "wire.log"
|
133
|
+
|
134
|
+
def wire_path=(logdev)
|
135
|
+
Watir.logger.reopen(logdev)
|
136
|
+
end
|
137
|
+
|
138
|
+
def wire_level_logging=(value)
|
139
|
+
Watir.logger.level = value
|
140
|
+
end
|
141
|
+
|
142
|
+
def wire_level_logging
|
143
|
+
%i[DEBUG INFO WARN ERROR FATAL UNKNOWN][Watir.logger.level]
|
144
|
+
end
|
145
|
+
|
44
146
|
def watir_api
|
45
147
|
browser.methods - Object.public_methods -
|
46
148
|
Watir::Container.instance_methods
|
data/testable.gemspec
CHANGED
@@ -26,6 +26,8 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
27
|
spec.require_paths = ["lib"]
|
28
28
|
|
29
|
+
spec.required_ruby_version = ">= 2.3"
|
30
|
+
|
29
31
|
spec.add_development_dependency "bundler", "~> 2.0"
|
30
32
|
spec.add_development_dependency "rake", "~> 10.0"
|
31
33
|
spec.add_development_dependency "rspec", "~> 3.0"
|
@@ -33,7 +35,7 @@ Gem::Specification.new do |spec|
|
|
33
35
|
spec.add_development_dependency "rubocop"
|
34
36
|
spec.add_development_dependency "pry"
|
35
37
|
|
36
|
-
spec.add_runtime_dependency "watir", ["~> 6.
|
38
|
+
spec.add_runtime_dependency "watir", ["~> 6.16"]
|
37
39
|
spec.add_runtime_dependency "capybara", ["~> 3.0"]
|
38
40
|
spec.add_runtime_dependency "webdrivers", ["~> 4.0"]
|
39
41
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Nyman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -100,14 +100,14 @@ dependencies:
|
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '6.
|
103
|
+
version: '6.16'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '6.
|
110
|
+
version: '6.16'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: capybara
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -172,6 +172,7 @@ files:
|
|
172
172
|
- lib/testable/capybara/node.rb
|
173
173
|
- lib/testable/capybara/page.rb
|
174
174
|
- lib/testable/context.rb
|
175
|
+
- lib/testable/deprecator.rb
|
175
176
|
- lib/testable/element.rb
|
176
177
|
- lib/testable/errors.rb
|
177
178
|
- lib/testable/extensions/core_ruby.rb
|
@@ -179,6 +180,7 @@ files:
|
|
179
180
|
- lib/testable/extensions/dom_observer.js
|
180
181
|
- lib/testable/extensions/dom_observer.rb
|
181
182
|
- lib/testable/locator.rb
|
183
|
+
- lib/testable/logger.rb
|
182
184
|
- lib/testable/page.rb
|
183
185
|
- lib/testable/ready.rb
|
184
186
|
- lib/testable/situation.rb
|
@@ -192,7 +194,7 @@ metadata:
|
|
192
194
|
source_code_uri: https://github.com/jeffnyman/testable
|
193
195
|
changelog_uri: https://github.com/jeffnyman/testable/blob/master/CHANGELOG.md
|
194
196
|
post_install_message: "\n(::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::)\n
|
195
|
-
\ Testable 0.
|
197
|
+
\ Testable 0.6.0 has been installed.\n(::) (::) (::) (::) (::) (::) (::) (::) (::)
|
196
198
|
(::) (::) (::)\n "
|
197
199
|
rdoc_options: []
|
198
200
|
require_paths:
|
@@ -201,14 +203,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
201
203
|
requirements:
|
202
204
|
- - ">="
|
203
205
|
- !ruby/object:Gem::Version
|
204
|
-
version: '
|
206
|
+
version: '2.3'
|
205
207
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
206
208
|
requirements:
|
207
209
|
- - ">="
|
208
210
|
- !ruby/object:Gem::Version
|
209
211
|
version: '0'
|
210
212
|
requirements: []
|
211
|
-
|
213
|
+
rubyforge_project:
|
214
|
+
rubygems_version: 2.5.2
|
212
215
|
signing_key:
|
213
216
|
specification_version: 4
|
214
217
|
summary: Web and API Automation, using Capybara and Watir
|