poltergeist 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f710cbda8c2d259e3f8819259d0e207871fe7276
4
+ data.tar.gz: db63a077b1335c06eb9cd91d09c0ef81ef3f11b9
5
+ SHA512:
6
+ metadata.gz: 75f64909a5703a3a34802a01817a2b02dd76310102513208bd909cfed38cff551930793c3c07514f3efbb9a9ef5051187ba88b2189ea20c9030a0119559c4248
7
+ data.tar.gz: 20a98f89b9e22ec9d3207ce34ffdcf6bf117194669b001001bf9419ac1efd1471fda11811dbab0128a9e80adfa710d3750d10237416234eb795fd4bddb175c35
data/README.md CHANGED
@@ -105,6 +105,8 @@ and the following optional features:
105
105
  * `page.status_code`
106
106
  * `page.response_headers`
107
107
  * `page.save_screenshot`
108
+ * `page.render_base64`
109
+ * `page.scroll_to`
108
110
  * cookie handling
109
111
  * drag-and-drop
110
112
 
@@ -119,6 +121,15 @@ render feature, so you can specify other extensions like `.pdf`, `.gif`, etc.)
119
121
  By default, only the viewport will be rendered (the part of the page that is in view). To render
120
122
  the entire page, use `save_screenshot('/path/to/file.png', :full => true)`.
121
123
 
124
+ You also have an ability to render selected element. Pass option `selector` with
125
+ any valid element selector to make a screenshot bounded by that element
126
+ `save_screenshot('/path/to/file.png', :selector => '#id')`.
127
+
128
+ If you need for some reasons base64 encoded screenshot you can simply call
129
+ `render_base64` that will return you encoded image. Additional options are the
130
+ same as for `save_screenshot` except the first argument which is format (:png by
131
+ default, acceptable :png, :gif, :jpeg).
132
+
122
133
  ### Resizing the window ###
123
134
 
124
135
  Sometimes the window size is important to how things are rendered. Poltergeist sets the window
@@ -153,17 +164,33 @@ Capybara.javascript_driver = :poltergeist_debug
153
164
  [Read more
154
165
  here](http://jonathanleighton.com/articles/2012/poltergeist-0-6-0/)
155
166
 
156
- ### Setting request headers ###
167
+ ### Manipulating request headers ###
168
+
169
+ You can manipulate HTTP request headers with these methods:
170
+
171
+ ``` ruby
172
+ page.driver.headers # => {}
173
+ page.driver.headers = { "User-Agent" => "Poltergeist" }
174
+ page.driver.add_headers("Referer" => "https://example.com")
175
+ page.driver.headers # => { "User-Agent" => "Poltergeist", "Referer" => "https://example.com" }
176
+ ```
157
177
 
158
- Additional HTTP request headers can be set like so:
178
+ Notice that `headers=` will overwrite already set headers. You should use
179
+ `add_headers` if you want to add a few more. These headers will apply to all
180
+ subsequent HTTP requests (including requests for assets, AJAX, etc). They will
181
+ be automatically cleared at the end of the test. You have ability to set headers
182
+ only for the initial request:
159
183
 
160
184
  ``` ruby
161
185
  page.driver.headers = { "User-Agent" => "Poltergeist" }
186
+ page.driver.add_header("Referer", "http://example.com", permanent: false)
187
+ page.driver.headers # => { "User-Agent" => "Poltergeist", "Referer" => "http://example.com" }
188
+ visit(login_path)
189
+ page.driver.headers # => { "User-Agent" => "Poltergeist" }
162
190
  ```
163
191
 
164
- The extra headers will apply to all subsequent HTTP requests (including
165
- requests for assets, AJAX, etc). They will be automatically cleared at
166
- the end of the test.
192
+ This way your temporary headers will be sent only for the initial request, all
193
+ subsequent request will only contain your permanent headers.
167
194
 
168
195
  ### Inspecting network traffic ###
169
196
 
@@ -186,6 +213,32 @@ The following methods are used to inspect and manipulate cookies:
186
213
  object.
187
214
  * `page.driver.remove_cookie(name)` - remove a cookie
188
215
 
216
+ ### Window switching ###
217
+
218
+ The following methods can be used to execute commands inside different windows:
219
+
220
+ * `page.driver.window_handles` - an array containing the names of all
221
+ the open windows.
222
+
223
+ * `page.within_window(name) { # actions }` - executes
224
+ the passed block in the context of the named window.
225
+
226
+ Example:
227
+
228
+ ``` ruby
229
+ find_link("Login with Facebook").trigger("click")
230
+
231
+ sleep(0.1)
232
+
233
+ fb_popup = page.driver.window_handles.last
234
+ page.within_window fb_popup do
235
+ fill_in "email", :with => "facebook_email@email.tst"
236
+ fill_in "pass", :with => "my_pass"
237
+ click_button "Log In"
238
+ end
239
+ ```
240
+
241
+
189
242
  ## Customization ##
190
243
 
191
244
  You can customize the way that Capybara sets up Poltegeist via the following code in your
@@ -205,7 +258,7 @@ end
205
258
  output, but this goes to `STDOUT` due to technical limitations.
206
259
  * `:logger` (Object responding to `puts`) - When present, debug output is written to this object
207
260
  * `:phantomjs_logger` (`IO` object) - Where the `STDOUT` from PhantomJS is written to. This is
208
- where you `console.log` statements will show up. Default: `STDOUT`
261
+ where your `console.log` statements will show up. Default: `STDOUT`
209
262
  * `:timeout` (Numeric) - The number of seconds we'll wait for a response
210
263
  when communicating with PhantomJS. Default is 30.
211
264
  * `:inspector` (Boolean, String) - See 'Remote Debugging', above.
@@ -294,6 +347,13 @@ documentation on asynchronous
294
347
  Javascript](https://github.com/jnicklas/capybara#asynchronous-javascript-ajax-and-friends)
295
348
  which explains the tools that Capybara provides for dealing with this.
296
349
 
350
+ ### Memory leak ###
351
+
352
+ If you run a few capybara sessions manually please make sure you've called
353
+ `session.driver.quit` when you don't need session anymore. Forgetting about this
354
+ causes memory leakage and your system's resources can be exhausted earlier than
355
+ you may expect.
356
+
297
357
  ### General troubleshooting hints ###
298
358
 
299
359
  * Configure Poltergeist with `:debug` turned on so you can see its
@@ -324,263 +384,8 @@ Include as much information as possible. For example:
324
384
 
325
385
  ## Changes ##
326
386
 
327
- ### 1.3.0 ###
328
-
329
- #### Features ####
330
-
331
- * Add support for PhantomJS 1.7's `cookiesEnabled` API
332
- (Micah Frost)
333
-
334
- #### Bug fixes ####
335
-
336
- * Fix logging of mouse event co-ordinates
337
- * Invalid selectors throw a useful error message
338
- * Tie us to the 0.4 version of faye-websocket since the 0.5 version
339
- contains breaking changes.
340
-
341
- ### 1.2.0 ###
342
-
343
- #### Features ####
344
-
345
- * Support for Windows hosted Poltergeist (Aaron Tull).
346
- * Capybara 2.1 support
347
-
348
- #### Bug fixes ####
349
-
350
- * Reverted the "native" implementation for filling in form fields,
351
- which was introduced in 1.0. This implementation caused various bugs
352
- and in general doesn't seem to be worth the trouble at the moment.
353
- It can be reconsidered in the future when PhantomJS has upgraded its
354
- WebKit version. [Issue #176, #223]
355
- * Run phantomjs in a new process group so ^C doesn't trigger a
356
- DeadClient error [Issue #252]
357
-
358
- ### 1.1.1 ###
359
-
360
- #### Features ####
361
-
362
- * Changed Capybara dependency to `~> 2.0.1` because Poltergeist 1.1 is
363
- not compatible with Capybara 2.1.
364
-
365
- ### 1.1.0 ###
366
-
367
- #### Features ####
368
-
369
- * Add support for custom phantomjs loggers via `:phantomjs_logger` option.
370
- (Gabe Bell)
371
- * Add `page.driver.click(x, y)` to click precise coordinates.
372
- (Micah Geisel)
373
- * Add Capybara 2.0 support. Capybara 1.1 and Ruby 1.8 are *no
374
- longer supported*. (Mauro Asprea) [Issue #163]
375
- * Add `node.base.double_click` to double click the node.
376
- (Andy Shen)
377
- * The `:debug` option now causes the PhantomJS portion of Poltergeist
378
- to output some additional debug info, which may be useful in
379
- figuring out timeout errors.
380
- * Add the ability to extend the phantomjs environment via browser
381
- options. e.g.
382
- `Capybara::Poltergeist::Driver.new( app, :extensions => ['file.js', 'another.js'])`
383
- (Jon Rowe)
384
-
385
- #### Bug fixes ####
386
-
387
- * Fix timing issue when using `within_frame` that could cause errors.
388
- [Issue #183, #211] (@errm, @motemen)
389
- * Fix bug with `within_frame` not properly switching the context back
390
- after the block has executed. [Issue #242]
391
- * Fix calculation of click position when clicking within a frame.
392
- [Issue #222, #225]
393
- * Fix error raising when calling `expires` if not set on cookie.
394
- [Issue #203] (@arnvald)
395
- * Fix the `:js_errors` option. Previously errors were not being
396
- reported, but would still cause commands to fail. [Issue #229]
397
- * Fix incorrect time zone handling when setting cookie expiry time
398
- [Issue #228]
399
- * Send SIGKILL to PhantomJS if it doesn't exit within 2 seconds
400
- [Issue #196]
401
- * Provide a more informative message for the `ObsoleteNode` error.
402
- [Issue #192]
403
- * Fix `ObsoleteNode` error when using `attach_file` with the `jQuery
404
- File Upload` plugin. [Issue #115]
405
- * Ensure that a `String` is passed over-the-wire to PhantomJS for
406
- file input paths, allowing `attach_file` to be called with arbitry
407
- objects such as a Pathname. (@mjtko) [Issue #215]
408
- * Cookies can now be set before the first request. [Issue #193]
409
-
410
- ### 1.0.2 ###
411
-
412
- #### Bug fixes ####
413
-
414
- * Clearing the value before setting a new value by sending a backspace.
415
- This fixes the issue that you can't set an empty value. [Issue #184]
416
-
417
- ### 1.0.1 ###
418
-
419
- #### Bug fixes ####
420
-
421
- * Don't use a fixed port number by default; find an available port.
422
- The port can still be configured to a fixed value using the `:port`
423
- option. The reverts the default behaviour to how it was before the
424
- 1.0 release. [Issue #174]
425
-
426
- ### 1.0 ###
427
-
428
- #### Features ####
429
-
430
- * Click co-ordinates are shown in the debug log. You can use this in
431
- combination with `page.driver.render` to work out where clicks are
432
- actually happening if you are having trouble.
433
- * Added `:port` configuration option and made the default port 44678
434
- rather than a random available port.
435
- * Support for Capybara's `page.response_headers` API to retrieve the
436
- headers of the last page load.
437
- * Support for cookie manipulation. [Issue #12]
438
- * Frame switching support now uses native PhantomJS APIs. (This might
439
- make it work better, but in general it's a badly tested area both in
440
- Capybara and Poltergeist.)
441
- * Support for the Capybara window switching API (`page.within_window`).
442
-
443
- #### Bug fixes ####
444
-
445
- * Prevent `TypeError: 'undefined' is not an object (evaluating
446
- 'rect.top')` error when clicking an element with `display: none`.
447
- The click will fail, but an obsolete node error will be raised, meaning
448
- that Capybara's retry mechanisms will kick in. [Issue #130]
449
- * Mouse over the element we will click, before clicking it. This
450
- enables `:hover` effects etc to trigger before the click happens,
451
- which can affect the click in some cases. [Issue #120]
452
- * Don't blow up when `evaluate_script` is called with a cyclic
453
- structure.
454
- * Fix the text method for title elements, so it doesn't return an
455
- empty string.
456
- * Fixed problem with cookies not being clearer between tests on
457
- PhantomJS 1.7
458
- * Fixed Javascript errors during page load causes TimeoutErrors.
459
- [Issue #124]
460
- * Ensure the User-Agent header can be set successfully. (Klaus Hartl)
461
- [Issue #127]
462
- * Use `el.innerText` for `Node#text`. This ensures that e.g. `<br>` is
463
- returned as a space. It also simplifies the method. [Issue #139]
464
- * Fix status code support when a response redirects to another URL.
465
- This was previously tested to ensure it would return the status code
466
- of the redirected URL, but the test was falsely broken and the
467
- implementation was also broken.
468
- * Fixed visiting URLs where only a hash change occurs (no HTTP
469
- request). [Issue #79]
470
- * Setting `page.driver.headers` now applies the headers to all
471
- requests, not just calls to `visit`. (So XHR, asset requests, etc
472
- will all receive the headers.) [Issue #149]
473
-
474
- ### 0.7 ###
475
-
476
- #### Features ####
477
-
478
- * Added an option `:js_errors`, allowing poltergeist to continue
479
- running after JS errors. (John Griffin & Tom Stuart) [Issue #62] [Issue #69]
480
- * Added an option `:window_size`, allowing users to specify
481
- dimensions to which the browser window will be resized.
482
- (Tom Stuart) [Issue #53]
483
- * Capybara 1.0 is no longer supported. Capybara ~> 1.1 is required.
484
- * Added ability to set arbitrary http request headers
485
- * Inspect network traffic on the page via
486
- `page.driver.network_traffic` (Doug McInnes) [Issue #77]
487
- * Added an option `:phantomjs_options`, allowing users to specify
488
- additional command-line options passed to phantomjs executable.
489
- (wynst) [Issue #97]
490
- * Scroll element into viewport if needed on click (Gabriel Sobrinho)
491
- [Issue #83]
492
- * Added status code support. (Dmitriy Nesteryuk and Jon Leighton) [Issue #37]
493
-
494
- #### Bug fixes ###
495
-
496
- * Fix issue with `ClickFailed` exception happening with a negative
497
- co-ordinate (which should be impossible). (Jon Leighton, Gabriel
498
- Sobrinho, Tom Stuart) [Issue #60]
499
- * Fix issue with `undefined method map for "[]":String`, which
500
- happened when dealing with pages that include JS rewriting
501
- Array.prototype.toJSON. (Tom Stuart) [Issue #63]
502
-
503
- ### 0.6 ###
504
-
505
- #### Features ####
506
-
507
- * Updated to PhantomJS 1.5.0, giving us proper support for reporting
508
- Javascript exception backtraces.
509
-
510
- ### 0.5 ###
511
-
512
- #### Features ####
513
-
514
- * Detect if clicking an element will fail. If the click will actually
515
- hit another element (because that element is in front of the one we
516
- want to click), the user will now see an exception explaining what
517
- happened and which element would actually be targeted by the click. This
518
- should aid debugging. [Issue #25]
519
- * Click elements at their middle position rather than the top-left.
520
- This is presumed to be more likely to succeed because the top-left
521
- may be obscured by overlapping elements, negative margins, etc. [Issue #26]
522
- * Add experimental support for using the remote WebKit web inspector.
523
- This will only work with PhantomJS 1.5, which is not yet released,
524
- so it won't be officially supported by Poltergeist until 1.5 is
525
- released. [Issue #31]
526
- * Add `page.driver.quit` method. If you spawn additional Capybara
527
- sessions, you might want to use this to reap the child phantomjs
528
- process. [Issue #24]
529
- * Errors produced by Javascript on the page will now generate an
530
- exception within Ruby. [Issue #27]
531
- * JRuby support. [Issue #20]
532
-
533
- #### Bug fixes ####
534
-
535
- * Fix bug where we could end up interacting with an obsolete element. [Issue #30]
536
- * Raise an suitable error if PhantomJS returns a non-zero exit status.
537
- Previously a version error would be raised, indicating that the
538
- PhantomJS version was too old when in fact it did not start at all. [Issue #23]
539
- * Ensure the `:timeout` option is actually used. [Issue #36]
540
- * Nodes need to know which page they are associated with. Before this,
541
- if Javascript caused a new page to load, existing node references
542
- would be wrong, but wouldn't raise an ObsoleteNode error. [Issue #39]
543
- * In some circumstances, we could end up missing an inline element
544
- when attempting to click it. This is due to the use of
545
- `getBoundingClientRect()`. We're now using `getClientRects()` to
546
- address this.
547
-
548
- ### 0.4 ###
549
-
550
- * Element click position is now calculated using the native
551
- `getBoundingClientRect()` method, which will be faster and less
552
- buggy.
553
- * Handle `window.confirm()`. Always returns true, which is the same
554
- as capybara-webkit. [Issue #10]
555
- * Handle `window.prompt()`. Returns the default value, if present, or
556
- null.
557
- * Fix bug with page Javascript page loading causing problems. [Issue #19]
558
-
559
- ### 0.3 ###
560
-
561
- * There was a bad bug to do with clicking elements in a page where the
562
- page is smaller than the window. The incorrect position would be
563
- calculated, and so the click would happen in the wrong place. This is
564
- fixed. [Issue #8]
565
- * Poltergeist didn't work in conjunction with the Thin web server,
566
- because that server uses Event Machine, and Poltergeist was assuming
567
- that it was the only thing in the process using EventMachine.
568
-
569
- To solve this, EventMachine usage has been completely removed, which
570
- has the welcome side-effect of being more efficient because we
571
- no longer have the overhead of running a mostly-idle event loop.
572
-
573
- [Issue #6]
574
- * Added the `:timeout` option to configure the timeout when talking to
575
- PhantomJS.
576
-
577
- ### 0.2 ###
578
-
579
- * First version considered 'ready', hopefully fewer problems.
580
-
581
- ### 0.1 ###
582
-
583
- * First version, various problems.
387
+ Version history and a list of next-release features and fixes can be found in
388
+ the [changelog](CHANGELOG.md).
584
389
 
585
390
  ## License ##
586
391
 
@@ -15,6 +15,7 @@ module Capybara
15
15
  require 'capybara/poltergeist/web_socket_server'
16
16
  require 'capybara/poltergeist/client'
17
17
  require 'capybara/poltergeist/inspector'
18
+ require 'capybara/poltergeist/json'
18
19
  require 'capybara/poltergeist/network_traffic'
19
20
  require 'capybara/poltergeist/errors'
20
21
  require 'capybara/poltergeist/cookie'
@@ -1,5 +1,5 @@
1
1
  require "capybara/poltergeist/errors"
2
- require 'json'
2
+ require 'multi_json'
3
3
  require 'time'
4
4
 
5
5
  module Capybara::Poltergeist
@@ -118,6 +118,10 @@ module Capybara::Poltergeist
118
118
  command 'pop_frame'
119
119
  end
120
120
 
121
+ def window_handles
122
+ command 'pages'
123
+ end
124
+
121
125
  def within_window(name, &block)
122
126
  command 'push_window', name
123
127
  yield
@@ -153,8 +157,18 @@ module Capybara::Poltergeist
153
157
  command 'reset'
154
158
  end
155
159
 
160
+ def scroll_to(left, top)
161
+ command 'scroll_to', left, top
162
+ end
163
+
156
164
  def render(path, options = {})
157
- command 'render', path.to_s, !!options[:full]
165
+ check_render_options!(options)
166
+ command 'render', path.to_s, !!options[:full], options[:selector]
167
+ end
168
+
169
+ def render_base64(format, options = {})
170
+ check_render_options!(options)
171
+ command 'render_base64', format.to_s, !!options[:full], options[:selector]
158
172
  end
159
173
 
160
174
  def resize(width, height)
@@ -174,10 +188,22 @@ module Capybara::Poltergeist
174
188
  command('equals', page_id, id, other_id)
175
189
  end
176
190
 
191
+ def get_headers
192
+ command 'get_headers'
193
+ end
194
+
177
195
  def set_headers(headers)
178
196
  command 'set_headers', headers
179
197
  end
180
198
 
199
+ def add_headers(headers)
200
+ command 'add_headers', headers
201
+ end
202
+
203
+ def add_header(header, permanent)
204
+ command 'add_header', header, permanent
205
+ end
206
+
181
207
  def response_headers
182
208
  command 'response_headers'
183
209
  end
@@ -221,7 +247,7 @@ module Capybara::Poltergeist
221
247
  message = { 'name' => name, 'args' => args }
222
248
  log message.inspect
223
249
 
224
- json = JSON.load(server.send(JSON.generate(message)))
250
+ json = JSON.load(server.send(JSON.dump(message)))
225
251
  log json.inspect
226
252
 
227
253
  if json['error']
@@ -240,5 +266,12 @@ module Capybara::Poltergeist
240
266
  def log(message)
241
267
  logger.puts message if logger
242
268
  end
269
+
270
+ def check_render_options!(options)
271
+ if !!options[:full] && options.has_key?(:selector)
272
+ warn "Ignoring :selector in #render since :full => true was given at #{caller.first}"
273
+ options.delete(:selector)
274
+ end
275
+ end
243
276
  end
244
277
  end