Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
### Changed

### Fixed
- `set_viewport` and `resize` turned touch emulation off on every desktop viewport, which reset hover and pointer and
undid `--blink-settings` overrides. `mobile:` defaults to `nil` and leaves touch as is, `false` turns it off [#664]

### Removed

Expand Down
7 changes: 6 additions & 1 deletion docs/14-emulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ Overrides device screen dimensions and emulates viewport. When `:mobile` is
* :width `Integer`, viewport width. `0` by default
* :height `Integer`, viewport height. `0` by default
* :scale_factor `Float`, device scale factor. `0` by default
* :mobile `Boolean`, whether to emulate mobile device and enable touch. `false` by default
* :mobile `Boolean | nil`, `true` emulates a mobile device with touch, `false` a desktop without touch, `nil` a
desktop and leaves touch emulation as is. `nil` by default

```ruby
page.set_viewport(width: 1000, height: 600, scale_factor: 3)
Expand All @@ -29,3 +30,7 @@ size preset:
```ruby
page.set_viewport(mobile: true)
```

Turning touch emulation off with `mobile: false` makes Chrome reset hover and pointer media features to the
detected input devices, which undoes `--blink-settings` overrides such as `primaryHoverType` until the next
navigation. Leave `:mobile` out unless the page was switched to mobile before.
14 changes: 6 additions & 8 deletions lib/ferrum/page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -191,22 +191,20 @@ def close_connection
#
# @param [Float] scale_factor device scale factor value. 0 disables the override
#
# @param [Boolean] mobile whether to emulate mobile device and enable touch
# @param [Boolean, nil] mobile `true` emulates a mobile device with touch, `false` a desktop without touch, `nil`
# a desktop and leaves touch emulation as is. Turning touch off resets hover and pointer to the detected input
# devices, which undoes `--blink-settings` overrides until the next navigation
#
def set_viewport(width: 0, height: 0, scale_factor: 0, mobile: false)
command(
"Emulation.setTouchEmulationEnabled",
enabled: mobile,
maxTouchPoints: 1
)
def set_viewport(width: 0, height: 0, scale_factor: 0, mobile: nil)
command("Emulation.setTouchEmulationEnabled", enabled: mobile, maxTouchPoints: 1) unless mobile.nil?

command(
"Emulation.setDeviceMetricsOverride",
slowmoable: true,
width: width,
height: height,
deviceScaleFactor: scale_factor,
mobile: mobile
mobile: mobile || false
)
end

Expand Down
2 changes: 1 addition & 1 deletion sig/ferrum/page.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ module Ferrum

def close_connection: () -> void

def set_viewport: (?width: ::Integer, ?height: ::Integer, ?scale_factor: ::Float, ?mobile: bool) -> Hash[String, untyped]
def set_viewport: (?width: ::Integer, ?height: ::Integer, ?scale_factor: ::Float, ?mobile: bool?) -> Hash[String, untyped]

def resize: (?width: ::Numeric?, ?height: ::Numeric?, ?fullscreen: bool) -> Hash[String, untyped]

Expand Down
26 changes: 26 additions & 0 deletions spec/page_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,32 @@ def is_mobile?
end.not_to(change { is_mobile? })
end
end

context "when mobile is not given" do
it "keeps the pointer type set with --blink-settings", :launch do
browser = Ferrum::Browser.new(browser_options: { "blink-settings" => "primaryPointerType=2,availablePointerTypes=2" })
browser.go_to(base_url)

expect do
browser.set_viewport(width: 500, height: 300)
end.not_to(change { browser.evaluate("matchMedia('(pointer: coarse)').matches") }.from(true))
ensure
browser&.quit
end
end

context "when mobile was true before" do
it "disables touch/mobile emulation again" do
page.go_to("/")
page.set_viewport(mobile: true)
page.reload

expect do
page.set_viewport(mobile: false)
page.reload
end.to change { is_mobile? }.from(true).to(false)
end
end
end

describe "#on" do
Expand Down
Loading