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 +4 -4
- data/.circleci/config.yml +2 -0
- data/.gitignore +1 -1
- data/README.md +12 -2
- data/lib/rutl.rb +8 -0
- data/lib/rutl/interface/base_interface.rb +7 -1
- data/lib/rutl/interface/elements/click_to_change_state_mixin.rb +7 -3
- data/lib/rutl/screencam.rb +71 -0
- data/lib/rutl/version.rb +1 -1
- data/rutl.gemspec +21 -4
- metadata +32 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '03966911ea3475762f121b4735aaee43a66af675c6b5baa255e329810c5fd890'
|
4
|
+
data.tar.gz: 4fbc7ec877d27b7daddae7f02c5b35396d9b6a5f59ffee90a5e4a29896627e1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1cfe7eecf5fb7ab352d10408412835b827b7cb276959efeac9085a538d008bd8a829ad468b158135353b85c4a9277a6af9cab5eae200932667c10ce425c6e2e5
|
7
|
+
data.tar.gz: ab287a5457fd4b3fe81ed869b3316f3165c1f97fbd92c3af04c42a935366488911f5e0b51d335c6c89621817ada69d766eec157a00f8db0317d1f7271475d095
|
data/.circleci/config.yml
CHANGED
@@ -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
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 ______?
|
data/lib/rutl.rb
CHANGED
@@ -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
|
data/lib/rutl/version.rb
CHANGED
data/rutl.gemspec
CHANGED
@@ -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.
|
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-
|
11
|
+
date: 2018-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: selenium-webdriver
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
type: :
|
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: '
|
26
|
+
version: '3.12'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: webdrivers
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0
|
34
|
-
type: :
|
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
|
40
|
+
version: '3.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
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: '
|
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:
|
84
|
+
name: coveralls
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
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: '
|
96
|
+
version: '0.8'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: rspec
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0
|
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
|
110
|
+
version: '3.0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
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.
|
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.
|
124
|
+
version: '0.3'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
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
|
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
|
138
|
+
version: '0.1'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
140
|
+
name: rubocop
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
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: '
|
152
|
+
version: '0.55'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: rubocop-rspec
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
157
|
- - "~>"
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
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: '
|
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
|