Skip to content

Commit b727708

Browse files
committed
chore: fix build and add CHANGELOG entry
1 parent 6a682f5 commit b727708

File tree

6 files changed

+53
-62
lines changed

6 files changed

+53
-62
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
- `Ferrum::Browser#debug` opens headless session in the browser devtools frontend [#519]
1212
- `Ferrum::Frame#parent` returns the parent frame if this frame is nested [#523]
1313
- `Ferrum::Frame#frame_element` returns the element in which the window is embedded [#524]
14+
- `Ferrum::Page#start_screencast` starts sending frames to record screencast [#494]
15+
- `Ferrum::Page#stop_screencast` stops sending frames [#494]
1416

1517
### Changed
1618

README.md

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ based on Ferrum and Mechanize.
3434
* [Navigation](https://github.com/rubycdp/ferrum#navigation)
3535
* [Finders](https://github.com/rubycdp/ferrum#finders)
3636
* [Screenshots](https://github.com/rubycdp/ferrum#screenshots)
37+
* [Screencast](https://github.com/rubycdp/ferrum#screencast)
3738
* [Network](https://github.com/rubycdp/ferrum#network)
3839
* [Downloads](https://github.com/rubycdp/ferrum#downloads)
3940
* [Proxy](https://github.com/rubycdp/ferrum#proxy)
@@ -136,7 +137,7 @@ browser.quit
136137
In docker as root you must pass the no-sandbox browser option:
137138

138139
```ruby
139-
Ferrum::Browser.new(browser_options: { 'no-sandbox': nil })
140+
Ferrum::Browser.new(browser_options: { "no-sandbox": nil })
140141
```
141142

142143
It has also been reported that the Chrome process repeatedly crashes when running inside a Docker container on an M1 Mac preventing Ferrum from working. Ferrum should work as expected when deployed to a Docker container on a non-M1 Mac.
@@ -415,7 +416,7 @@ page.screenshot(path: "google.jpg") # => 30902
415416
# Save to Base64 the whole page not only viewport and reduce quality
416417
page.screenshot(full: true, quality: 60, encoding: :base64) # "iVBORw0KGgoAAAANSUhEUgAABAAAAAMACAYAAAC6uhUNAAAAAXNSR0IArs4c6Q...
417418
# Save on the disk with the selected element in PNG
418-
page.screenshot(path: "google.png", selector: 'textarea') # => 11340
419+
page.screenshot(path: "google.png", selector: "textarea") # => 11340
419420
# Save to Base64 with an area of the page in PNG
420421
page.screenshot(path: "google.png", area: { x: 0, y: 0, width: 400, height: 300 }) # => 54239
421422
# Save with specific background color
@@ -459,9 +460,9 @@ page.mhtml(path: "google.mhtml") # => 87742
459460

460461
## Screencast
461462

462-
#### start_screencast(\*\*options) {|data, metadata, session_id| block }
463+
#### start_screencast(\*\*options) { |data, metadata, session_id| ... }
463464

464-
Starts sending each frame to the given block.
465+
Starts sending frames to record screencast to the given block.
465466

466467
* options `Hash`
467468
* :format `Symbol` `:jpeg` | `:png` The format the image should be returned in.
@@ -473,23 +474,23 @@ Starts sending each frame to the given block.
473474
* Block inputs:
474475
* data `String` Base64-encoded compressed image.
475476
* metadata `Hash` Screencast frame metadata.
476-
* 'offsetTop' `Integer` Top offset in DIP.
477-
* 'pageScaleFactor' `Integer` Page scale factor.
478-
* 'deviceWidth' `Integer` Device screen width in DIP.
479-
* 'deviceHeight' `Integer` Device screen height in DIP.
480-
* 'scrollOffsetX' `Integer` Position of horizontal scroll in CSS pixels.
481-
* 'scrollOffsetY' `Integer` Position of vertical scroll in CSS pixels.
482-
* 'timestamp' `Float` (optional) Frame swap timestamp in seconds since Unix epoch.
477+
* "offsetTop" `Integer` Top offset in DIP.
478+
* "pageScaleFactor" `Integer` Page scale factor.
479+
* "deviceWidth" `Integer` Device screen width in DIP.
480+
* "deviceHeight" `Integer` Device screen height in DIP.
481+
* "scrollOffsetX" `Integer` Position of horizontal scroll in CSS pixels.
482+
* "scrollOffsetY" `Integer` Position of vertical scroll in CSS pixels.
483+
* "timestamp" `Float` (optional) Frame swap timestamp in seconds since Unix epoch.
483484
* session_id `Integer` Frame number.
484485

485486
```ruby
486-
require 'base64'
487+
require "base64"
487488

488489
page.go_to("https://apple.com/ipad")
489490

490491
page.start_screencast(format: :jpeg, quality: 75) do |data, metadata|
491-
timestamp_ms = metadata['timestamp'] * 1000
492-
File.binwrite("image_#{timestamp_ms.to_i}.jpg", Base64.decode64(data))
492+
timestamp = (metadata["timestamp"] * 1000).to_i
493+
File.binwrite("image_#{timestamp}.jpg", Base64.decode64(data))
493494
end
494495

495496
sleep 10
@@ -498,14 +499,18 @@ page.stop_screencast
498499
```
499500

500501
> ### 📝 NOTE
501-
>
502+
>
502503
> Chrome only sends new frames while page content is changing. For example, if
503504
> there is an animation or a video on the page, Chrome sends frames at the rate
504505
> requested. On the other hand, if the page is nothing but a wall of static text,
505506
> Chrome sends frames while the page renders. Once Chrome has finished rendering
506507
> the page, it sends no more frames until something changes (e.g., navigating to
507508
> another location).
508509
510+
#### stop_screencast
511+
512+
Stops sending frames.
513+
509514
## Network
510515

511516
`page.network`
@@ -1142,7 +1147,7 @@ Returns the element in which the window is embedded.
11421147

11431148
#### execution_id : `Integer`
11441149

1145-
Execution context id which is used by JS, each frame has it's own context in
1150+
Execution context id which is used by JS, each frame has its own context in
11461151
which JS evaluates.
11471152

11481153
#### name : `String | nil`
@@ -1377,7 +1382,7 @@ Closes browser tabs opened by the `Browser` instance.
13771382

13781383
```ruby
13791384
# connect to a long-running Chrome process
1380-
browser = Ferrum::Browser.new(url: 'http://localhost:9222')
1385+
browser = Ferrum::Browser.new(url: "http://localhost:9222")
13811386

13821387
browser.go_to("https://github.com/")
13831388

lib/ferrum/frame/dom.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# any updates, for example, the node may be destroyed without any notification.
1515
# This is a way to keep a reference to the Node, when you don't necessarily want
1616
# to keep track of it. One example would be linking to the node from performance
17-
# data (e.g. relayout root node). BackendNodeId may be either resolved to
17+
# data (e.g. re-layout root node). BackendNodeId may be either resolved to
1818
# inspected node (DOM.pushNodesByBackendIdsToFrontend) or described in more
1919
# details (DOM.describeNode).
2020
module Ferrum

lib/ferrum/page.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ def prepare_page
490490
# opens a new window for which `frameStoppedLoading` event never
491491
# occurs and thus search for nodes cannot be completed. Here we check
492492
# the history and if the transitionType for example `link` then
493-
# content is already loaded and we can try to get the document.
493+
# content is already loaded, and we can try to get the document.
494494
document_node_id
495495
end
496496

lib/ferrum/page/screencast.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
module Ferrum
44
class Page
55
module Screencast
6-
# Starts yielding each frame to the given block.
6+
# Starts sending frames to record screencast to the given block.
77
#
88
# @param [Hash{Symbol => Object}] opts
99
#
@@ -57,13 +57,13 @@ module Screencast
5757
# Frame number.
5858
#
5959
# @example
60-
# require 'base64'
60+
# require "base64"
6161
#
6262
# page.go_to("https://apple.com/ipad")
6363
#
6464
# page.start_screencast(format: :jpeg, quality: 75) do |data, metadata|
65-
# timestamp_ms = metadata['timestamp'] * 1000
66-
# File.binwrite("image_#{timestamp_ms.to_i}.jpg", Base64.decode64(data))
65+
# timestamp = (metadata['timestamp'] * 1000).to_i
66+
# File.binwrite("image_#{timestamp}.jpg", Base64.decode64(data))
6767
# end
6868
#
6969
# sleep 10
@@ -87,7 +87,7 @@ def start_screencast(**opts)
8787
end
8888
end
8989

90-
# Stops sending each frame.
90+
# Stops sending frames.
9191
def stop_screencast
9292
command("Page.stopScreencast")
9393
end

spec/page/screencast_spec.rb

Lines changed: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,78 +7,62 @@
77
require "ferrum/rgba"
88

99
describe Ferrum::Page::Screencast do
10-
after(:example) do
11-
browser.stop_screencast
10+
let(:format) { :jpeg }
1211

13-
Dir.glob("#{PROJECT_ROOT}/spec/tmp/screencast_frame*") { File.delete _1 }
14-
end
12+
after(:example) { browser.stop_screencast }
1513

1614
describe "#start_screencast" do
1715
context "when the page has no changing content" do
18-
it "should continue screencasting frames" do
19-
browser.go_to "/ferrum/long_page"
16+
it "continues screencasting frames" do
17+
browser.go_to "/long_page"
2018

21-
format = :jpeg
2219
count = 0
23-
browser.start_screencast(format: format) do |data, _metadata, _session_id|
20+
browser.start_screencast(format: format) do |data|
21+
Base64.decode64(data) # decodable
2422
count += 1
25-
path = "#{PROJECT_ROOT}/spec/tmp/screencast_frame_#{format('%05d', count)}.#{format}"
26-
File.binwrite(path, Base64.decode64(data))
2723
end
28-
2924
sleep 5
3025

31-
expect(Dir.glob("#{PROJECT_ROOT}/spec/tmp/screencast_frame_*").count).to be_positive.and be < 5
32-
26+
expect(count).to be_between(1, 5)
27+
ensure
3328
browser.stop_screencast
3429
end
3530
end
3631

3732
context "when the page content continually changes" do
38-
it "should stop screencasting frames when the page has finished rendering" do
39-
browser.go_to "/ferrum/animation"
33+
it "stops screencasting frames when the page has finished rendering" do
34+
browser.go_to "/animation"
4035

41-
format = :jpeg
4236
count = 0
43-
browser.start_screencast(format: format) do |data, _metadata, _session_id|
37+
browser.start_screencast(format: format) do |data|
38+
Base64.decode64(data) # decodable
4439
count += 1
45-
path = "#{PROJECT_ROOT}/spec/tmp/screencast_frame_#{format('%05d', count)}.#{format}"
46-
File.binwrite(path, Base64.decode64(data))
4740
end
48-
4941
sleep 5
5042

51-
expect(Dir.glob("#{PROJECT_ROOT}/spec/tmp/screencast_frame_*").count).to be > 250
52-
43+
expect(count).to be > 250
44+
ensure
5345
browser.stop_screencast
5446
end
5547
end
5648
end
5749

5850
describe "#stop_screencast" do
5951
context "when the page content continually changes" do
60-
it "should stop screencasting frames when the page has finished rendering" do
61-
browser.go_to "/ferrum/animation"
52+
it "stops screencasting frames when the page has finished rendering" do
53+
browser.go_to "/animation"
6254

63-
format = :jpeg
6455
count = 0
65-
browser.start_screencast(format: format) do |data, _metadata, _session_id|
56+
browser.start_screencast(format: format) do |data|
57+
Base64.decode64(data)
6658
count += 1
67-
path = "#{PROJECT_ROOT}/spec/tmp/screencast_frame_#{format('%05d', count)}.#{format}"
68-
File.binwrite(path, Base64.decode64(data))
6959
end
70-
71-
sleep 5
72-
73-
browser.stop_screencast
74-
75-
number_of_frames_after_stop = Dir.glob("#{PROJECT_ROOT}/spec/tmp/screencast_frame_*").count
76-
7760
sleep 2
61+
expect(count).to be > 50
62+
browser.stop_screencast
63+
sleep 2 # wait for events on the fly to land
7864

79-
number_of_frames_after_delay = Dir.glob("#{PROJECT_ROOT}/spec/tmp/screencast_frame_*").count
80-
81-
expect(number_of_frames_after_stop).to be <= number_of_frames_after_delay
65+
expect { sleep 2 }.not_to(change { count })
8266
end
8367
end
8468
end

0 commit comments

Comments
 (0)