testable 0.5.0 → 0.10.0

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: 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