with_form 0.1.0 → 0.2.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/README.md +196 -0
- data/db/migrate/20200310042146_create_widget_records.rb +1 -1
- data/lib/with_form/engine.rb +18 -0
- data/lib/with_form/model_form.rb +8 -0
- data/lib/with_form/scope_form.rb +39 -3
- data/lib/with_form/translation_helpers.rb +11 -0
- data/lib/with_form/version.rb +1 -1
- metadata +20 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a78f39980ba03659bd61b33c94e65e8987dc590647ba8870271141a879eafca
|
4
|
+
data.tar.gz: ad43310ff4fd4a42ddb3f154af5c9e799f1a25c82dafdd46c9d18a6f41f48304
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a300ce3b20953400496bc7b7cf09e0bb9206870526c8d63cfb6987db7537ffe702788cd1543ad9eb28f83b99ac44bb39063b628be3677eac73069874a0bdbd6
|
7
|
+
data.tar.gz: b596e4300be6ac53de36e9e81e85514722d1763f3c877ed82aa1b5b38a04adb8d02995d625d89eb800a07938f42343a76d565aa62c0523e338e16845aa675e95
|
data/README.md
CHANGED
@@ -7,6 +7,8 @@ Your System Test's counterpart to `form_with`
|
|
7
7
|
Leverage Rails-generated `<label>` values to submit `<form>` elements in System
|
8
8
|
Tests.
|
9
9
|
|
10
|
+
### The `with_form` test helper
|
11
|
+
|
10
12
|
To add coverage to a form's fields that are generated by ActionView's
|
11
13
|
`form_with` helper, fill them using `with_form`:
|
12
14
|
|
@@ -60,6 +62,29 @@ The `with_form` helper method accepts two styles of options:
|
|
60
62
|
|
61
63
|
* `scope:` - the internationalization scope key to use when translating Capybara's
|
62
64
|
locator values
|
65
|
+
|
66
|
+
When submitting a `<form>` through a call to `form.click_button`, you can pass
|
67
|
+
an `action` as the translation scope. A `with_form(scope:)` call will default
|
68
|
+
to the `submit` key when one is not specified. For instance:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
form_with(scope: :post) do |form|
|
72
|
+
form.click_button
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
This call will search for an `<input type="text">` or `<button>` whose `value`
|
77
|
+
or text content is the String translated by the `helpers.submit.post.submit`
|
78
|
+
key.
|
79
|
+
|
80
|
+
That action can be overridden:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
form_with(scope: :post) do |form|
|
84
|
+
form.click_button :create
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
63
88
|
* `model:` - an instance of an `ActiveModel::Model` or `ActiveRecord::Base` to
|
64
89
|
be used to translate Capybara's locator values, and to populate the fields
|
65
90
|
with an attribute's value.
|
@@ -97,9 +122,65 @@ The `with_form` helper method accepts two styles of options:
|
|
97
122
|
`"New Title"`) will take precedence over the `post.title` attribute's value
|
98
123
|
(in this case, `"Old Title"`).
|
99
124
|
|
125
|
+
When submitting a `<form>` through a call to `form.click_button`, you can pass
|
126
|
+
an `action` as the translation scope. A `with_form(model:)` call will
|
127
|
+
determine the translation key based on [the `model`
|
128
|
+
argument's persistence state][persisted].
|
129
|
+
|
130
|
+
When a `model` instance is a new record, the key will use `create`. For
|
131
|
+
instance:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
post = Post.new
|
135
|
+
|
136
|
+
form_with(model: post) do |form|
|
137
|
+
form.click_button
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
This call will search for an `<input type="text">` or `<button>` whose `value`
|
142
|
+
or text content is the String translated by the `helpers.submit.post.create`
|
143
|
+
key.
|
144
|
+
|
145
|
+
That action can be overridden:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
post = Post.new
|
149
|
+
|
150
|
+
form_with(model: post) do |form|
|
151
|
+
form.click_button :submit
|
152
|
+
end
|
153
|
+
```
|
154
|
+
|
155
|
+
When a `model` instance is an existing persisted record, the key will use
|
156
|
+
`update`. For instance:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
post = Post.last
|
160
|
+
|
161
|
+
form_with(model: post) do |form|
|
162
|
+
form.click_button
|
163
|
+
end
|
164
|
+
```
|
165
|
+
|
166
|
+
This call will search for an `<input type="text">` or `<button>` whose `value`
|
167
|
+
or text content is the String translated by the `helpers.submit.post.update`
|
168
|
+
key.
|
169
|
+
|
170
|
+
That action can be overridden:
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
post = Post.last
|
174
|
+
|
175
|
+
form_with(model: post) do |form|
|
176
|
+
form.click_button :submit
|
177
|
+
end
|
178
|
+
```
|
179
|
+
|
100
180
|
[label]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label
|
101
181
|
[input]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input
|
102
182
|
[textarea]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea
|
183
|
+
[persisted]: https://api.rubyonrails.org/classes/ActiveModel/Model.html#method-i-persisted-3F
|
103
184
|
|
104
185
|
With the exception of `#click_link` and `#click_link_or_button`, the argument
|
105
186
|
yielded to `with_form` supports [all helper methods made available by
|
@@ -118,6 +199,117 @@ Those include:
|
|
118
199
|
|
119
200
|
[actions]: https://www.rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions
|
120
201
|
|
202
|
+
#### ActionText `rich_text_area` support
|
203
|
+
|
204
|
+
When [`ActionText`][actiontext] is available, `with_form` provides a
|
205
|
+
`#fill_in_rich_text_area` helper method.
|
206
|
+
|
207
|
+
The current implementation is inspired by
|
208
|
+
`ActionText::SystemTestHelper#fill_in_rich_text_area` that is currently declared
|
209
|
+
on the current [`rails@master` branch][fill_in_rich_text_area].
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
class UserInteractsWithRichTextAreasTest < ApplicationSystemTestCase
|
213
|
+
include WithForm::TestHelpers
|
214
|
+
|
215
|
+
test "makes a post with a scope: argument" do
|
216
|
+
visit new_post_path
|
217
|
+
with_form(scope: :post) do |form|
|
218
|
+
form.fill_in_rich_text_area :body, with: "My First Post"
|
219
|
+
form.click_button
|
220
|
+
end
|
221
|
+
|
222
|
+
assert_text "My First Post"
|
223
|
+
end
|
224
|
+
|
225
|
+
test "user makes a post with a model: argument" do
|
226
|
+
post = Post.new(body: "My First Post")
|
227
|
+
|
228
|
+
visit new_post_path
|
229
|
+
with_form(model: post) do |form|
|
230
|
+
form.fill_in_rich_text_area :body
|
231
|
+
form.click_button
|
232
|
+
end
|
233
|
+
|
234
|
+
assert_text "My First Post"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
```
|
238
|
+
|
239
|
+
There is a current limitation in how the [`rails@master`-inspired
|
240
|
+
`#fill_in_rich_text_area` implementation][fill_in_rich_text_area] resolves the
|
241
|
+
`locator` argument. Since the underlying `<trix-editor>` element is not a
|
242
|
+
default field provided by the browser, focussing on its corresponding `<label>`
|
243
|
+
element won't focus the `<trix-editor>`. To resolve that shortcoming, the
|
244
|
+
`#fill_in_rich_text_area` uses the `<trix-editor aria-label="...">` attribute as
|
245
|
+
the label text.
|
246
|
+
|
247
|
+
This is a helpful, but incomplete solution to the problem. This requires that
|
248
|
+
instead of declaring a `<label for="my_rich_text_field">` element
|
249
|
+
referencing the `<trix-editor id="my_rich_text_field">` element, the `<label>`
|
250
|
+
element's text (or rather, the text that _would be_ in the `<label>` element)
|
251
|
+
must be passed to the `<trix-editor aria-label="...">` attribute.
|
252
|
+
|
253
|
+
For example:
|
254
|
+
|
255
|
+
```html+erb
|
256
|
+
<%= form_with(model: Post.new) do |form %>
|
257
|
+
<%= form.label :my_rich_text_field %>
|
258
|
+
<%= form.rich_text_area :my_rich_text_field, "aria-label": translate(:my_rich_text_field, scope: "helpers.label.post") %>
|
259
|
+
<% end %>
|
260
|
+
```
|
261
|
+
|
262
|
+
[actiontext]: https://edgeguides.rubyonrails.org/action_text_overview.html#examples
|
263
|
+
[fill_in_rich_text_area]: https://github.com/rails/rails/blob/339be65d669c83fd4c64541a9e82086dc5e64682/actiontext/lib/action_text/system_test_helper.rb
|
264
|
+
|
265
|
+
### The `label` and `submit` test helpers
|
266
|
+
|
267
|
+
While `with_form` can simplify `<form>` element interactions with multiple
|
268
|
+
steps, there are times when a single line of instructions is more convenient.
|
269
|
+
|
270
|
+
Behind the scenes, `with_form` utilize the `#label` and `#submit` helper
|
271
|
+
methods to translate `<label>` and `<button>` text, along with `<input
|
272
|
+
type="submit">` values.
|
273
|
+
|
274
|
+
To put the same helpers to use within your test, include the
|
275
|
+
`WithForm::TranslationHelpers` module and invoke either:
|
276
|
+
|
277
|
+
* `label(model_name, attribute)`
|
278
|
+
|
279
|
+
* `submit(model_name, action = :submit)`
|
280
|
+
|
281
|
+
For example when clicking an `<input type="checkbox">` labelled by a translation
|
282
|
+
declared at `helpers.label.session.ready`:
|
283
|
+
|
284
|
+
```ruby
|
285
|
+
class UserInteractsWithFormsTest < ApplicationSystemTestCase
|
286
|
+
include WithForm::TranslationHelpers
|
287
|
+
|
288
|
+
test "user ticks a box" do
|
289
|
+
visit new_session_path
|
290
|
+
check label(:session, :ready)
|
291
|
+
|
292
|
+
assert_text "We're glad you're ready, user@example.com."
|
293
|
+
end
|
294
|
+
end
|
295
|
+
```
|
296
|
+
|
297
|
+
Or, to destroy a Post by clicking a button labelled by a translation declared at
|
298
|
+
`helpers.submit.post.destroy`:
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
class UserInteractsWithFormsTest < ApplicationSystemTestCase
|
302
|
+
include WithForm::TranslationHelpers
|
303
|
+
|
304
|
+
test "user deletes a post" do
|
305
|
+
visit new_post_path
|
306
|
+
click_on submit(:post, :destroy)
|
307
|
+
|
308
|
+
assert_text "Deleted Post."
|
309
|
+
end
|
310
|
+
end
|
311
|
+
```
|
312
|
+
|
121
313
|
## Installation
|
122
314
|
|
123
315
|
Add this line to your application's Gemfile:
|
@@ -186,6 +378,10 @@ I've used the [`formulaic` gem][formulaic] before. How is this gem different?
|
|
186
378
|
[form_with]: https://guides.rubyonrails.org/form_helpers.html#dealing-with-basic-forms
|
187
379
|
[rails-i18n]: https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-label
|
188
380
|
|
381
|
+
## Contributing
|
382
|
+
|
383
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
384
|
+
|
189
385
|
## License
|
190
386
|
|
191
387
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/lib/with_form/engine.rb
CHANGED
@@ -1,4 +1,22 @@
|
|
1
1
|
module WithForm
|
2
2
|
class Engine < ::Rails::Engine
|
3
|
+
ActiveSupport.on_load :action_dispatch_system_test_case do
|
4
|
+
Capybara.add_selector :rich_text_area do
|
5
|
+
label "rich-text area"
|
6
|
+
xpath do |locator|
|
7
|
+
if locator.nil?
|
8
|
+
XPath.descendant(:"trix-editor")
|
9
|
+
else
|
10
|
+
input_located_by_name = XPath.anywhere(:input).where(XPath.attr(:name) == locator).attr(:id)
|
11
|
+
|
12
|
+
XPath.descendant(:"trix-editor").where \
|
13
|
+
XPath.attr(:id).equals(locator) |
|
14
|
+
XPath.attr(:placeholder).equals(locator) |
|
15
|
+
XPath.attr(:"aria-label").equals(locator) |
|
16
|
+
XPath.attr(:input).equals(input_located_by_name)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
3
21
|
end
|
4
22
|
end
|
data/lib/with_form/model_form.rb
CHANGED
@@ -15,6 +15,14 @@ module WithForm
|
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
18
|
+
def fill_in_rich_text_area(attribute, with: nil, **options)
|
19
|
+
scope_form.fill_in_rich_text_area(
|
20
|
+
attribute,
|
21
|
+
with: with || @model.public_send(attribute),
|
22
|
+
**options,
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
18
26
|
def attach_file(attribute, path = nil, **options)
|
19
27
|
scope_form.attach_file(
|
20
28
|
attribute,
|
data/lib/with_form/scope_form.rb
CHANGED
@@ -1,18 +1,54 @@
|
|
1
|
+
require "with_form/translation_helpers"
|
2
|
+
|
1
3
|
module WithForm
|
2
4
|
class ScopeForm
|
3
5
|
include ActionView::Helpers::TranslationHelper
|
6
|
+
include WithForm::TranslationHelpers
|
4
7
|
|
5
|
-
delegate :
|
8
|
+
delegate :choose, to: :@page
|
6
9
|
|
7
10
|
def initialize(scope:, page:)
|
8
11
|
@page = page
|
9
12
|
@scope = scope
|
10
13
|
end
|
11
14
|
|
15
|
+
def check(attribute, **options)
|
16
|
+
case attribute
|
17
|
+
when Symbol
|
18
|
+
value = label(attribute)
|
19
|
+
else
|
20
|
+
value = attribute
|
21
|
+
end
|
22
|
+
|
23
|
+
@page.check value, **options
|
24
|
+
end
|
25
|
+
|
26
|
+
def uncheck(attribute, **options)
|
27
|
+
case attribute
|
28
|
+
when Symbol
|
29
|
+
value = label(attribute)
|
30
|
+
else
|
31
|
+
value = attribute
|
32
|
+
end
|
33
|
+
|
34
|
+
@page.uncheck value, **options
|
35
|
+
end
|
36
|
+
|
12
37
|
def fill_in(attribute, with:, **options)
|
13
38
|
@page.fill_in label(attribute), with: with, **options
|
14
39
|
end
|
15
40
|
|
41
|
+
def fill_in_rich_text_area(locator = nil, with:)
|
42
|
+
fill_in_script = <<~JS
|
43
|
+
this.editor.loadHTML(arguments[0])
|
44
|
+
JS
|
45
|
+
|
46
|
+
@page.find(:rich_text_area, label(locator)).execute_script(
|
47
|
+
fill_in_script,
|
48
|
+
with.to_s,
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
16
52
|
def select(value, from:, **options)
|
17
53
|
@page.select value, from: label(from), **options
|
18
54
|
end
|
@@ -30,11 +66,11 @@ module WithForm
|
|
30
66
|
end
|
31
67
|
|
32
68
|
def submit(action = nil)
|
33
|
-
|
69
|
+
super(@scope, action || :submit)
|
34
70
|
end
|
35
71
|
|
36
72
|
def label(attribute)
|
37
|
-
|
73
|
+
super(@scope, attribute)
|
38
74
|
end
|
39
75
|
end
|
40
76
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module WithForm
|
2
|
+
module TranslationHelpers
|
3
|
+
def submit(model_name, action = :submit)
|
4
|
+
translate(action, scope: [:helpers, :submit, model_name])
|
5
|
+
end
|
6
|
+
|
7
|
+
def label(model_name, attribute)
|
8
|
+
translate(attribute, scope: [:helpers, :label, model_name])
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/with_form/version.rb
CHANGED
metadata
CHANGED
@@ -1,35 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: with_form
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Doyle
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: railties
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 6.0.2
|
20
17
|
- - ">="
|
21
18
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
19
|
+
version: 5.2.0
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
|
-
- - "~>"
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: 6.0.2
|
30
24
|
- - ">="
|
31
25
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
26
|
+
version: 5.2.0
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: capybara
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,6 +52,20 @@ dependencies:
|
|
58
52
|
- - ">="
|
59
53
|
- !ruby/object:Gem::Version
|
60
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activerecord
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 5.2.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 5.2.0
|
61
69
|
- !ruby/object:Gem::Dependency
|
62
70
|
name: selenium-webdriver
|
63
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -104,6 +112,7 @@ files:
|
|
104
112
|
- lib/with_form/model_form.rb
|
105
113
|
- lib/with_form/scope_form.rb
|
106
114
|
- lib/with_form/test_helpers.rb
|
115
|
+
- lib/with_form/translation_helpers.rb
|
107
116
|
- lib/with_form/version.rb
|
108
117
|
homepage: https://github.com/seanpdoyle/with_form
|
109
118
|
licenses:
|