testable 0.5.0 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c59c802e12f855543871b0917b7043a6dca602714c79cf5624d0033b86f8ce68
4
- data.tar.gz: 3011ecba1297734eff0491ce54f4b8192bc5bdafe61b2736598af3649b790455
3
+ metadata.gz: 025f6e480d7fcc805e5f5315133169d8544210a60107b71436f5eb0564056175
4
+ data.tar.gz: 0111cd004bfcdcc8f64b889a5edd5728922d77a24349f9e05003422f3b491f55
5
5
  SHA512:
6
- metadata.gz: c9b98f008221c0bd278f690f6aee6fe32c5ea84ffe3c55a977d015ef25100846291bf9a753080caffec7e13d8fcc81f9f3e757cdf7e9f980ab4ce0abf8289ae0
7
- data.tar.gz: b977fd589e01f32b48af6ed449087c2a3db1d05ed0aa0f87ee2b74d876259695b61ec0d117f1691f426b77f285ed7809876324243fd0e1e2d42fdee5436df903
6
+ metadata.gz: 65992ba040e1175ceded847c9a7024c80e9b52bf0c5f08a51a7ff53964a4cff39a43c9de44d0c6e172b64ea3d31eda09c35066d809e10f7260743aee86b14440
7
+ data.tar.gz: a1f782e5b1f3a7d19247b2e02e7b415061de7e4be4a24a8593e7173ebf81a33e5499b86c3cc85826445eef58281904ffe7cea64a2e69c581e44e942e81b5a59f
data/.gitignore CHANGED
@@ -1,3 +1,7 @@
1
+ # Testable Generated
2
+
3
+ testable.log
4
+
1
5
  # Ruby Generated
2
6
 
3
7
  /Gemfile.lock
data/README.md CHANGED
@@ -8,6 +8,12 @@
8
8
 
9
9
  ----
10
10
 
11
+ [![Gem Version](https://badge.fury.io/rb/testable.svg)](http://badge.fury.io/rb/testable)
12
+ [![License](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/jeffnyman/testable/blob/master/LICENSE.md)
13
+
14
+ [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/github/jeffnyman/testable/master/frames)
15
+ [![Inline docs](http://inch-ci.org/github/jeffnyman/testable.png)](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
- Instructions will be coming soon. However, there are a series of scripts in the `examples` directory and a series of commands in the `Rakefile` that will let you execute those scripts.
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
 
File without changes
data/bin/setup CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -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
File without changes
@@ -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
 
@@ -14,7 +16,6 @@ require "testable/extensions/dom_observer"
14
16
 
15
17
  require "watir"
16
18
  require "capybara"
17
- require "webdrivers"
18
19
 
19
20
  module Testable
20
21
  def self.included(caller)
@@ -41,6 +42,106 @@ module Testable
41
42
  attr_accessor :browser
42
43
 
43
44
  class << self
45
+ # Provides a means to allow a configure block on Testable. This allows you
46
+ # to setup Testable, as such:
47
+ #
48
+ # Testable.configure do |config|
49
+ # config.driver_timeout = 5
50
+ # config.wire_level_logging = :info
51
+ # config.log_level = :debug
52
+ # end
53
+ def configure
54
+ yield self
55
+ end
56
+
57
+ # Watir provides a default timeout of 30 seconds. This allows you to change
58
+ # that in the Testable context. For example:
59
+ #
60
+ # Testable.driver_timeout = 5
61
+ #
62
+ # This would equivalent to doing this:
63
+ #
64
+ # Watir.default_timeout = 5
65
+ def driver_timeout=(value)
66
+ Watir.default_timeout = value
67
+ end
68
+
69
+ # The Testable logger object. To log messages:
70
+ #
71
+ # Testable.logger.info('Some information.')
72
+ # Testable.logger.debug('Some diagnostics')
73
+ #
74
+ # To alter or check the current logging level, you can call `.log_level=`
75
+ # or `.log_level`. By default the logger will output all messages to the
76
+ # standard output ($stdout) but it can be altered to log to a file or to
77
+ # another IO location by calling `.log_path=`.
78
+ def logger
79
+ @logger ||= Testable::Logger.new.create
80
+ end
81
+
82
+ # To enable logging, do this:
83
+ #
84
+ # Testable.log_level = :DEBUG
85
+ # Testable.log_level = 'DEBUG'
86
+ # Testable.log_level = 0
87
+ #
88
+ # This can accept any of a Symbol / String / Integer as an input
89
+ # To disable all logging, which is the case by default, do this:
90
+ #
91
+ # Testable.log_level = :UNKNOWN
92
+ def log_level=(value)
93
+ logger.level = value
94
+ end
95
+
96
+ # To query what level is being logged, do this:
97
+ #
98
+ # Testable.log_level
99
+ #
100
+ # The logging level will be UNKNOWN by default.
101
+ def log_level
102
+ %i[DEBUG INFO WARN ERROR FATAL UNKNOWN][logger.level]
103
+ end
104
+
105
+ # The writer method allows you to configure where you want the output of
106
+ # the Testable logs to go, with the default being standard output. Here
107
+ # is how you could change this to a specific file:
108
+ #
109
+ # Testable.log_path = 'testable.log'
110
+ def log_path=(logdev)
111
+ logger.reopen(logdev)
112
+ end
113
+
114
+ # The wire logger provides logging from Watir, which is very similar to the
115
+ # logging provided by Selenium::WebDriver::Logger. The default level is set
116
+ # to warn. This means you will see any deprecation notices as well as any
117
+ # warning messages. To see details on each element interaction the level
118
+ # can be set to info. To see details on what Watir is doing when it takes a
119
+ # selector hash and converts it into XPath, the level can be set to debug.
120
+ # If you want to ignore specific warnings that are appearing during test
121
+ # execution:
122
+ #
123
+ # Watir.logger.ignore :warning_name
124
+ #
125
+ # If you want to ignore all deprecation warnings in your tests:
126
+ #
127
+ # Watir.logger.ignore :deprecations
128
+ #
129
+ # To have the wire logger generate output to a file:
130
+ #
131
+ # Watir.logger.output = "wire.log"
132
+
133
+ def wire_path=(logdev)
134
+ Watir.logger.reopen(logdev)
135
+ end
136
+
137
+ def wire_level_logging=(value)
138
+ Watir.logger.level = value
139
+ end
140
+
141
+ def wire_level_logging
142
+ %i[DEBUG INFO WARN ERROR FATAL UNKNOWN][Watir.logger.level]
143
+ end
144
+
44
145
  def watir_api
45
146
  browser.methods - Object.public_methods -
46
147
  Watir::Container.instance_methods
@@ -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
@@ -67,7 +67,7 @@ module Testable
67
67
  end
68
68
 
69
69
  alias displayed? has_correct_url?
70
- alias loaded? has_correct_url?
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
@@ -1,7 +1,7 @@
1
1
  module Testable
2
2
  module_function
3
3
 
4
- VERSION = "0.5.0".freeze
4
+ VERSION = "0.10.0".freeze
5
5
 
6
6
  def version
7
7
  """
@@ -26,16 +26,17 @@ 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
- spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "rake", ">= 12.3.3"
31
33
  spec.add_development_dependency "rspec", "~> 3.0"
32
34
  spec.add_development_dependency "simplecov"
33
35
  spec.add_development_dependency "rubocop"
34
36
  spec.add_development_dependency "pry"
35
37
 
36
- spec.add_runtime_dependency "watir", ["~> 6.4"]
37
- spec.add_runtime_dependency "capybara", ["~> 3.0"]
38
- spec.add_runtime_dependency "webdrivers", ["~> 4.0"]
38
+ spec.add_runtime_dependency "watir", ["~> 6.16"]
39
+ spec.add_runtime_dependency "capybara", [">= 2", "< 4"]
39
40
 
40
41
  spec.post_install_message = %{
41
42
  (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::)
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.5.0
4
+ version: 0.10.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-08-13 00:00:00.000000000 Z
11
+ date: 2020-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -100,42 +100,34 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '6.4'
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.4'
110
+ version: '6.16'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: capybara
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '3.0'
118
- type: :runtime
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
115
+ - - ">="
123
116
  - !ruby/object:Gem::Version
124
- version: '3.0'
125
- - !ruby/object:Gem::Dependency
126
- name: webdrivers
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
117
+ version: '2'
118
+ - - "<"
130
119
  - !ruby/object:Gem::Version
131
- version: '4.0'
120
+ version: '4'
132
121
  type: :runtime
133
122
  prerelease: false
134
123
  version_requirements: !ruby/object:Gem::Requirement
135
124
  requirements:
136
- - - "~>"
125
+ - - ">="
137
126
  - !ruby/object:Gem::Version
138
- version: '4.0'
127
+ version: '2'
128
+ - - "<"
129
+ - !ruby/object:Gem::Version
130
+ version: '4'
139
131
  description: Provides a semantic DSL to construct fluent interfaces for test execution
140
132
  logic.
141
133
  email:
@@ -172,6 +164,7 @@ files:
172
164
  - lib/testable/capybara/node.rb
173
165
  - lib/testable/capybara/page.rb
174
166
  - lib/testable/context.rb
167
+ - lib/testable/deprecator.rb
175
168
  - lib/testable/element.rb
176
169
  - lib/testable/errors.rb
177
170
  - lib/testable/extensions/core_ruby.rb
@@ -179,6 +172,7 @@ files:
179
172
  - lib/testable/extensions/dom_observer.js
180
173
  - lib/testable/extensions/dom_observer.rb
181
174
  - lib/testable/locator.rb
175
+ - lib/testable/logger.rb
182
176
  - lib/testable/page.rb
183
177
  - lib/testable/ready.rb
184
178
  - lib/testable/situation.rb
@@ -192,7 +186,7 @@ metadata:
192
186
  source_code_uri: https://github.com/jeffnyman/testable
193
187
  changelog_uri: https://github.com/jeffnyman/testable/blob/master/CHANGELOG.md
194
188
  post_install_message: "\n(::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::)\n
195
- \ Testable 0.5.0 has been installed.\n(::) (::) (::) (::) (::) (::) (::) (::) (::)
189
+ \ Testable 0.10.0 has been installed.\n(::) (::) (::) (::) (::) (::) (::) (::) (::)
196
190
  (::) (::) (::)\n "
197
191
  rdoc_options: []
198
192
  require_paths:
@@ -201,14 +195,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
201
195
  requirements:
202
196
  - - ">="
203
197
  - !ruby/object:Gem::Version
204
- version: '0'
198
+ version: '2.3'
205
199
  required_rubygems_version: !ruby/object:Gem::Requirement
206
200
  requirements:
207
201
  - - ">="
208
202
  - !ruby/object:Gem::Version
209
203
  version: '0'
210
204
  requirements: []
211
- rubygems_version: 3.0.4
205
+ rubygems_version: 3.1.2
212
206
  signing_key:
213
207
  specification_version: 4
214
208
  summary: Web and API Automation, using Capybara and Watir