OSDN Git Service

Regular updates
[twpd/master.git] / capybara.md
1 ---
2 title: Capybara
3 category: Ruby libraries
4 layout: 2017/sheet
5 weight: -5
6 updated: 2020-06-13
7 tags: [Featurable]
8 ---
9
10 ### Navigating
11
12     visit articles_path
13
14 ### Clicking links and buttons
15
16 ```ruby
17 click_on 'Link Text'
18 click_button
19 click_link
20 ```
21
22 ### Interacting with forms
23
24 ```ruby
25 attach_file 'Image', '/path/to/image.jpg'
26 fill_in 'First Name', with: 'John'
27 ```
28
29 ```ruby
30 check 'A checkbox'
31 uncheck 'A checkbox'
32 ```
33
34 ```ruby
35 choose 'A radio button'
36 ```
37
38 ```ruby
39 select 'Option', from: 'Select box'
40 unselect
41 ```
42
43 ### Limiting
44
45 ```ruby
46 within '.classname' do
47   click '...'
48 end
49 ```
50
51 ```ruby
52 within_fieldset :id do
53   ...
54 end
55 ```
56
57 ## Querying
58
59 ### Predicates
60
61 ```ruby
62 page.has_css?('.button')
63 expect(page).to have_css('.button')
64 page.should have_css('.button')
65 ```
66 {: .-setup}
67
68 | Positive                          | Negative               |
69 | ---                               | ---                    |
70 | `has_content?`                    | `has_no_content?`      |
71 | ---                               | ---                    |
72 | `has_css?` _(selector)_           | `has_no_css?`          |
73 | ---                               | ---                    |
74 | `has_xpath?` _(path)_             | `has_no_xpath?`        |
75 | ---                               | ---                    |
76 | `has_link?` _(selector)_          | `has_no_link?`         |
77 | ---                               | ---                    |
78 | `has_button?` _(selector)_        | `has_no_button?`       |
79 | ---                               | ---                    |
80 | `has_field?` _(selector)_         | `has_no_field?`        |
81 | ---                               | ---                    |
82 | `has_checked_field?` _(selector)_ | `has_unchecked_field?` |
83 | ---                               | ---                    |
84 | `has_table?` _(selector)_         | `has_no_table?`        |
85 | ---                               | ---                    |
86 | `has_select?` _(selector)_        | `has_no_select?`       |
87 {: .-headers.-left-align}
88
89 In Rspec, these also map to matchers like `page.should have_content`.
90
91 ### Selectors
92
93 ```ruby
94 expect(page).to have_button('Save')
95 ```
96
97 ```ruby
98 expect(page).to have_button('#submit')
99 ```
100
101 ```ruby
102 expect(page).to have_button('//[@id="submit"]')
103 ```
104
105 The `selector` arguments can be text, CSS selector, or XPath expression.
106
107 ### RSpec assertions
108
109 ```ruby
110 page.has_button?('Save')
111 ```
112
113 ```ruby
114 expect(page).to have_no_button('Save')
115 ```
116
117 In RSpec, you can use `page.should` assertions.
118
119 ### About negatives
120
121 ```ruby
122 expect(page).to have_no_button('Save')   # OK
123 ```
124 ```ruby
125 expect(page).not_to have_button('Save')  # Bad
126 ```
127
128 Use `should have_no_*` versions with RSpec matchers because
129 `should_not have_*` doesn't wait for a timeout from the driver.
130
131 ## RSpec
132
133 ### Matchers
134
135 ```ruby
136 expect(page).to \
137 ```
138 {: .-setup}
139
140 ```ruby
141   have_current_path(expected_path)
142   have_selector '.blank-state'
143   have_selector 'h1#hola', text: 'Welcome'
144   have_button 'Save'
145   have_checked_field '#field'
146   have_unchecked_field
147   have_css '.class'
148   have_field '#field'
149   have_table '#table'
150   have_xpath '//div'
151 ```
152
153 ```ruby
154   have_link 'Logout', href: logout_path
155 ```
156
157 ```ruby
158   have_select 'Language',
159     selected: 'German'
160     options: ['Engish', 'German']
161     with_options: ['Engish', 'German'] # partial match
162 ```
163
164 ```ruby
165   have_text 'Hello',
166     type: :visible # or :all
167     # alias: have_content
168 ```
169
170 ### Common options
171
172 All matchers have these options:
173 {: .-setup}
174
175 ```ruby
176   text: 'welcome'
177   text: /Hello/
178   visible: true
179   count: 4
180   between: 2..5
181   minimum: 2
182   maximum: 5
183   wait: 10
184 ```
185
186 ## Other features
187
188 ### Finding
189
190 ```ruby
191 find(selector)
192 find_button(selector)
193 find_by_id(id)
194 find_field(selector)
195 find_link(selector)
196 locate
197 ```
198
199 ### Scoping
200
201 ```ruby
202 within '#delivery' do
203   fill_in 'Street', with: 'Hello'
204 end
205 ```
206
207 ```ruby
208 within :xpath, '//article'
209 within_fieldset
210 within_table
211 within_frame
212 scope_to
213 ```
214
215 ```ruby
216 find('#x').fill_in('Street', with: 'Hello')
217 # same as within
218 ```
219
220 ### Scripting
221
222 ```ruby
223 execute_script('$("input").trigger("change")')
224 evaluate_script('window.ga')
225 ```
226
227 Executes JavaScript.
228
229 ### Debugging
230
231 ```ruby
232 save_and_open_page
233 ```
234
235 Opens the webpage in your browser.
236
237 ### Page
238
239 ```ruby
240 page
241   .all('h3')
242   .body
243   .html
244   .source
245   .current_host
246   .current_path
247   .current_url
248 ```
249
250 ### AJAX
251
252 ```ruby
253 using_wait_time 10 do
254   ...
255 end
256 ```
257
258 ### Misc
259
260     drag
261     field_labeled
262
263 ### Page object
264
265 ```ruby
266 page.status_code == 200
267 page.response_headers
268 ```
269
270 See: <https://www.rubydoc.info/github/jnicklas/capybara/master/Capybara/Session>
271
272 ### Poltergeist
273
274 ```ruby
275 Capybara.register_driver :poltergeist do |app|
276   Capybara::Poltergeist::Driver.new(app, :inspector => true)
277 end
278 Capybara.javascript_driver = :poltergeist
279 ```
280
281 Use [poltergeist](https://github.com/teampoltergeist/poltergeist) to integrate PhantomJS.
282
283 ### Blacklist
284
285 ```ruby
286 config.before :each, :js do
287   page.driver.browser.url_blacklist = [
288     'fonts.googleapis.com',
289     'use.typekit.net',
290     'f.vimeocdn.com',
291     'player.vimeo.com',
292     'www.googletagmanager.com'
293   ].flat_map { |domain| [ "http://#{domain}", "https://#{domain}" ] }
294 end
295 ```
296
297 ### Debugging
298
299 Enable `inspector: true` and then:
300 {: .-setup}
301
302 ```ruby
303 page.driver.debug
304 ```
305
306 To pause execution for a while:
307
308 ```ruby
309 page.driver.pause
310 ```
311
312 ## Selenium
313
314 ### Accepting confirm() and alert()
315
316 ```ruby
317 accept_alert { ... }
318 dismiss_confirm { ... }
319 accept_prompt(with: 'hi') { ... }
320 ```
321
322 Alternatively:
323
324 ```ruby
325 page.driver.browser.switch_to.alert.accept
326 ```
327
328 ### Updating session
329
330 ```ruby
331 page.set_rack_session(foo: 'bar')
332 ```
333
334 ## See also
335 {: .-one-column}
336
337 - <https://rubydoc.info/github/jnicklas/capybara/Capybara/RSpecMatchers>
338 - <https://www.rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Matchers>