rutl 0.2.1 → 0.3.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: 2cc8b6905f9d8a505779925d3d85bca28fa334677a8c3c301eca6f960fd4795a
4
- data.tar.gz: 841b286a1a36c99642495bd8a638cc68c361254f6a0a3a2c673ff0b155da634a
3
+ metadata.gz: '03966911ea3475762f121b4735aaee43a66af675c6b5baa255e329810c5fd890'
4
+ data.tar.gz: 4fbc7ec877d27b7daddae7f02c5b35396d9b6a5f59ffee90a5e4a29896627e1c
5
5
  SHA512:
6
- metadata.gz: fec1a528ed212affc96add10a953bc5aabb76016f34d9efc9b676c5d7df4cc44a4695b9ce87a096ff882ae8ff845340385e88a25080584787ae0b9bc4668f8f6
7
- data.tar.gz: 4c3aebb3e24f4dbbd5ac5260ea2a48a1a21a0513ec7288c51c2fa5e0261897bbece23f04cee0d0cf2f3560a9a3b53392cbb74b317dce47129f9a29a3ecfb1611
6
+ metadata.gz: 1cfe7eecf5fb7ab352d10408412835b827b7cb276959efeac9085a538d008bd8a829ad468b158135353b85c4a9277a6af9cab5eae200932667c10ce425c6e2e5
7
+ data.tar.gz: ab287a5457fd4b3fe81ed869b3316f3165c1f97fbd92c3af04c42a935366488911f5e0b51d335c6c89621817ada69d766eec157a00f8db0317d1f7271475d095
@@ -55,6 +55,7 @@ jobs:
55
55
  - run:
56
56
  name: run tests
57
57
  command: |
58
+ mkdir /tmp/screenshots
58
59
  mkdir /tmp/test-results
59
60
  TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
60
61
 
@@ -70,3 +71,4 @@ jobs:
70
71
  - store_artifacts:
71
72
  path: /tmp/test-results
72
73
  destination: test-results
74
+
data/.gitignore CHANGED
@@ -1,5 +1,5 @@
1
1
  /.bundle/
2
- /.gem
2
+ /*.gem
3
3
  /.yardoc
4
4
  /debug.log
5
5
  /Gemfile.lock
data/README.md CHANGED
@@ -158,13 +158,22 @@ To use it:
158
158
  require 'rutl/rspec/rutl_matchers'
159
159
  ```
160
160
 
161
+ ### Auto-screenshotting
162
+
163
+ If you have RUTL::SCREENSHOTS or ENV['SCREENSHOTS'] set to a directory, RUTL
164
+ will automatically take screenshots on page transitions.
165
+ If you're using RSpec, they'll be automatically named something based on the
166
+ RSpec description with an auto-incrementing number.
167
+ If you're not using RSpec, that's not terribly useful but you can always have
168
+ your tests screenshot anyway, just less magic.
161
169
 
162
170
  ## Roadmap
163
171
  Coming up soon in almost no order:
172
+ * Handle error pages/partials.
173
+ * Auto-screenshot on errors. Error destinations. Navigation errors. Unexpected exceptions?
164
174
  * A test framework should have better tests.
165
- * Put more info in this readme.
166
- * Take screenshots.
167
175
  * Diff screenshots. Make this smart so we don't have to be experts.
176
+ * Put more info in this readme.
168
177
  * Move bugs and would-be features to Github Issues instead of this readme and scattered through the code.
169
178
  * Make the framework make it easier to spot bugs in pages. Focus on exception-handling?
170
179
  * The webdriver gem should already include InternetExplorerDriver. Maybe run tests on AppVeyor.
@@ -177,6 +186,7 @@ Coming up soon in almost no order:
177
186
  * Same with iPhone.
178
187
  * Same Cordoba test app?
179
188
  * Documentation. RDoc?
189
+ * Auto-screenshot support frameworks other than RSpec.
180
190
  * Others?
181
191
  * Spidering page object maker. Or selector checker/fixer?
182
192
  * Possibly pair the null browser with auto-generated pages for ______?
@@ -10,4 +10,12 @@ module RUTL
10
10
  # or set ENV['RUTL_PAGES']
11
11
  # or Browser intialize will raise.
12
12
  PAGES = nil
13
+
14
+ # If this RUTL::SCREENSHOT_DIR or ENV['SCREENSHOT_DIR']
15
+ # or Browser initialize is set, we take screenshots.
16
+ SCREENSHOTS = nil
17
+
18
+ # This one is for diffing against.
19
+ # RUTL::KNOWN_GOOD_SCREENSHOTS
20
+ REFERENCE_SCREENSHOTS = nil
13
21
  end
@@ -1,5 +1,5 @@
1
1
  require 'rutl/utilities'
2
-
2
+ require 'rutl/screencam'
3
3
  #
4
4
  # I might need to consider renaming these.
5
5
  # The *interface classes lie between Browser and the webdriver-level classes.
@@ -8,15 +8,21 @@ class BaseInterface
8
8
  include Utilities
9
9
 
10
10
  attr_accessor :driver
11
+ attr_reader :camera
11
12
  attr_accessor :pages
12
13
 
13
14
  def initialize
14
15
  raise 'Child interface class must set @driver.' if @driver.nil?
16
+ # base_name avoids collisions when unning the same tests with
17
+ # different browsers.
18
+ name = self.class.to_s .sub('Interface', '')
19
+ @camera = ScreenCam.new(@driver, base_name: name)
15
20
  end
16
21
 
17
22
  def goto(page)
18
23
  raise 'expect Page class' unless page.ancestors.include?(BasePage)
19
24
  find_page(page).go_to_here
25
+ @camera.screenshot
20
26
  end
21
27
 
22
28
  def current_page
@@ -5,10 +5,14 @@
5
5
  #
6
6
  module ClickToChangeStateMixin
7
7
  def click
8
+ # Screenshot before clicking. Is this really necessary?
9
+ @context.interface.camera.screenshot
8
10
  this_css.click
9
-
10
- # TODO: Is this part of the instance-stamping problem???
11
11
  # returns the page it found
12
- @context.interface.wait_for_transition(@context.destinations)
12
+ result = @context.interface.wait_for_transition(@context.destinations)
13
+ # And after clicking and going to new state. This seems more needed
14
+ # because we want to see where we went.
15
+ @context.interface.camera.screenshot
16
+ result
13
17
  end
14
18
  end
@@ -0,0 +1,71 @@
1
+ require 'fileutils'
2
+ #
3
+ # class to take photos of the screen (and diff them?)
4
+ #
5
+ class ScreenCam
6
+ def guard
7
+ # When running headless, Selenium seems not to drop screenshots.
8
+ # So that makes this safe in places like Travis.
9
+ #
10
+ # We still need to guard against NullDriver or we'll to to screencap
11
+ # it when we're running head-fully.
12
+ #
13
+ # Will there be others?
14
+ @driver.is_a? NullDriver
15
+ end
16
+
17
+ def initialize(driver, base_name: '')
18
+ @counter = 0
19
+ @driver = driver
20
+ return if guard
21
+ @base_name = base_name
22
+ @dir = File.join(RUTL::SCREENSHOTS, base_name)
23
+ FileUtils.mkdir_p @dir
24
+ end
25
+
26
+ def shoot(path = nil)
27
+ return if guard
28
+ # Magic path is used for all auto-screenshots.
29
+ name = path || magic_path
30
+
31
+ FileUtils.mkdir_p @dir
32
+ file = File.join(@dir, pathify(name))
33
+ @driver.save_screenshot(file)
34
+ end
35
+ alias screenshot shoot
36
+
37
+ def clean_dir(dir)
38
+ FileUtils.rm_rf dir
39
+ FileUtils.mkdir_p dir
40
+ end
41
+
42
+ def counter
43
+ @counter += 1
44
+ # In the unlikely even that we have > 9 screenshots in a test case,
45
+ # format the counter to be two digits, zero padded.
46
+ format('%02d', @counter)
47
+ end
48
+
49
+ def magic_path
50
+ if defined? RSpec
51
+ RSpec.current_example.metadata[:full_description].to_s
52
+ else
53
+ # TODO: The behavior for non-RSpec users is ugly and broken.
54
+ # Each new test case will start taking numbered "auto-screenshot" pngs.
55
+ # And the next test case will overwrite them. Even if they didn't
56
+ # overwrite, I don't know how to correllate tests w/ scrrenshots. I'm
57
+ # leaving this broken for now.
58
+ # You can still tell it to take your own named screenshots whenever you
59
+ # like, of course.
60
+ 'auto-screenshot'
61
+ end
62
+ end
63
+
64
+ def pathify(path)
65
+ # Replace any of these with an underscore:
66
+ # space, octothorpe, slash, backslash, colon, period
67
+ name = path.gsub(%r{[ \#\/\\\:\.]}, '_')
68
+ # Also insert a counter and make sure we end with .png.
69
+ name.sub(/.png$/, '') + '_' + counter + '.png'
70
+ end
71
+ end
@@ -1,3 +1,3 @@
1
1
  module RUTL
2
- VERSION = '0.2.1'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
@@ -27,15 +27,32 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ['lib']
29
29
 
30
+ # These are *some* webdriver-related dependencies. They don't include
31
+ # brwosers. Or anything for non-browssr testing. Or image diffing code.
32
+ # Maybe all browser stuff should be its own sub-gem.
33
+ spec.add_dependency 'selenium-webdriver', '~> 3.12'
34
+ # webdrivers gem can pull down these webdrivers: chromedriver, geckodriver,
35
+ # IEDriverServer and MicrosoftWebDriver. It does not install the browser.
36
+ #
37
+ # CitcleCI can't use this to install webdrivers.
38
+ # Works locally and with Travis.
39
+ spec.add_dependency 'webdrivers', '~> 3.0'
40
+
41
+ # Dependencies for development only.
30
42
  spec.add_development_dependency 'bundler', '~> 1.15'
31
- spec.add_development_dependency 'coveralls', '~> 0.8'
32
- spec.add_development_dependency 'drewcoo-cops', '~> 0.1'
33
43
  spec.add_development_dependency 'gem-release', '~> 1.0'
34
44
  spec.add_development_dependency 'rake', '~> 12.3'
45
+
46
+ # Code coverage service.
47
+ spec.add_development_dependency 'coveralls', '~> 0.8'
48
+
49
+ # RSpec is used to test the RUTL. It might not be the test engine chosen
50
+ # by the person using RUTL.
35
51
  spec.add_development_dependency 'rspec', '~> 3.0'
36
52
  spec.add_development_dependency 'rspec_junit_formatter', '~> 0.3'
53
+
54
+ # Linting with RuboCop
55
+ spec.add_development_dependency 'drewcoo-cops', '~> 0.1'
37
56
  spec.add_development_dependency 'rubocop', '~> 0.55'
38
57
  spec.add_development_dependency 'rubocop-rspec', '~> 1.25'
39
- spec.add_development_dependency 'selenium-webdriver', '~> 3.12'
40
- spec.add_development_dependency 'webdrivers', '~> 3.0'
41
58
  end
metadata CHANGED
@@ -1,57 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rutl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Drew Cooper
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-06-05 00:00:00.000000000 Z
11
+ date: 2018-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: selenium-webdriver
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.15'
20
- type: :development
19
+ version: '3.12'
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.15'
26
+ version: '3.12'
27
27
  - !ruby/object:Gem::Dependency
28
- name: coveralls
28
+ name: webdrivers
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.8'
34
- type: :development
33
+ version: '3.0'
34
+ type: :runtime
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: '0.8'
40
+ version: '3.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: drewcoo-cops
42
+ name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.1'
47
+ version: '1.15'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.1'
54
+ version: '1.15'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: gem-release
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -81,89 +81,89 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '12.3'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rspec
84
+ name: coveralls
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '3.0'
89
+ version: '0.8'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '3.0'
96
+ version: '0.8'
97
97
  - !ruby/object:Gem::Dependency
98
- name: rspec_junit_formatter
98
+ name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0.3'
103
+ version: '3.0'
104
104
  type: :development
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: '0.3'
110
+ version: '3.0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: rubocop
112
+ name: rspec_junit_formatter
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0.55'
117
+ version: '0.3'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '0.55'
124
+ version: '0.3'
125
125
  - !ruby/object:Gem::Dependency
126
- name: rubocop-rspec
126
+ name: drewcoo-cops
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '1.25'
131
+ version: '0.1'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '1.25'
138
+ version: '0.1'
139
139
  - !ruby/object:Gem::Dependency
140
- name: selenium-webdriver
140
+ name: rubocop
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '3.12'
145
+ version: '0.55'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '3.12'
152
+ version: '0.55'
153
153
  - !ruby/object:Gem::Dependency
154
- name: webdrivers
154
+ name: rubocop-rspec
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: '3.0'
159
+ version: '1.25'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: '3.0'
166
+ version: '1.25'
167
167
  description: This is a UI library under construction at the moment.
168
168
  email:
169
169
  - drewcoo@gmail.com
@@ -204,6 +204,7 @@ files:
204
204
  - lib/rutl/interface/elements/text.rb
205
205
  - lib/rutl/interface/firefox_interface.rb
206
206
  - lib/rutl/interface/null_interface.rb
207
+ - lib/rutl/screencam.rb
207
208
  - lib/rutl/utilities.rb
208
209
  - lib/rutl/version.rb
209
210
  - rutl.gemspec