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_selector '.blank-state'
142   have_selector 'h1#hola', text: 'Welcome'
143   have_button 'Save'
144   have_checked_field '#field'
145   have_unchecked_field
146   have_css '.class'
147   have_field '#field'
148   have_table '#table'
149   have_xpath '//div'
150 ```
151
152 ```ruby
153   have_link 'Logout', href: logout_path
154 ```
155
156 ```ruby
157   have_select 'Language',
158     selected: 'German'
159     options: ['Engish', 'German']
160     with_options: ['Engish', 'German'] # partial match
161 ```
162
163 ```ruby
164   have_text 'Hello',
165     type: :visible # or :all
166     # alias: have_content
167 ```
168
169 ### Common options
170
171 All matchers have these options:
172 {: .-setup}
173
174 ```ruby
175   text: 'welcome'
176   text: /Hello/
177   visible: true
178   count: 4
179   between: 2..5
180   minimum: 2
181   maximum: 5
182   wait: 10
183 ```
184
185 ## Other features
186
187 ### Finding
188
189 ```ruby
190 find(selector)
191 find_button(selector)
192 find_by_id(id)
193 find_field(selector)
194 find_link(selector)
195 locate
196 ```
197
198 ### Scoping
199
200 ```ruby
201 within '#delivery' do
202   fill_in 'Street', with: 'Hello'
203 end
204 ```
205
206 ```ruby
207 within :xpath, '//article'
208 within_fieldset
209 within_table
210 within_frame
211 scope_to
212 ```
213
214 ```ruby
215 find('#x').fill_in('Street', with: 'Hello')
216 # same as within
217 ```
218
219 ### Scripting
220
221 ```ruby
222 execute_script('$("input").trigger("change")')
223 evaluate_script('window.ga')
224 ```
225
226 Executes JavaScript.
227
228 ### Debugging
229
230 ```ruby
231 save_and_open_page
232 ```
233
234 Opens the webpage in your browser.
235
236 ### Page
237
238 ```ruby
239 page
240   .all('h3')
241   .body
242   .html
243   .source
244   .current_host
245   .current_path
246   .current_url
247 ```
248
249 ### AJAX
250
251 ```ruby
252 using_wait_time 10 do
253   ...
254 end
255 ```
256
257 ### Misc
258
259     drag
260     field_labeled
261
262 ### Page object
263
264 ```ruby
265 page.status_code == 200
266 page.response_headers
267 ```
268
269 See: <http://www.rubydoc.info/github/jnicklas/capybara/master/Capybara/Session>
270
271 ### Poltergeist
272
273 ```ruby
274 Capybara.register_driver :poltergeist do |app|
275   Capybara::Poltergeist::Driver.new(app, :inspector => true)
276 end
277 Capybara.javascript_driver = :poltergeist
278 ```
279
280 Use [poltergeist](https://github.com/teampoltergeist/poltergeist) to integrate PhantomJS.
281
282 ### Blacklist
283
284 ```ruby
285 config.before :each, :js do
286   page.driver.browser.url_blacklist = [
287     'fonts.googleapis.com',
288     'use.typekit.net',
289     'f.vimeocdn.com',
290     'player.vimeo.com',
291     'www.googletagmanager.com'
292   ].flat_map { |domain| [ "http://#{domain}", "https://#{domain}" ] }
293 end
294 ```
295
296 ### Debugging
297
298 Enable `inspector: true` and then:
299 {: .-setup}
300
301 ```ruby
302 page.driver.debug
303 ```
304
305 To pause execution for a while:
306
307 ```ruby
308 page.driver.pause
309 ```
310
311 ## Selenium
312
313 ### Accepting confirm() and alert()
314
315 ```ruby
316 accept_alert { ... }
317 dismiss_confirm { ... }
318 accept_prompt(with: 'hi') { ... }
319 ```
320
321 Alternatively:
322
323 ```ruby
324 page.driver.browser.switch_to.alert.accept
325 ```
326
327 ### Updating session
328
329 ```ruby
330 page.set_rack_session(foo: 'bar')
331 ```
332
333 ## See also
334 {: .-one-column}
335
336 - <http://rubydoc.info/github/jnicklas/capybara/Capybara/RSpecMatchers>
337 - <http://www.rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Matchers>