Class: Unmagic::Browser::Emulation
- Inherits:
-
Object
- Object
- Unmagic::Browser::Emulation
- Defined in:
- lib/unmagic/browser/emulation.rb
Overview
Everything about how a page renders — colour scheme, viewport, device, locale, timezone, geolocation, media type — in one immutable value object.
It's the only place emulation lives, and it's set in exactly two places: passed to #open, or changed live with Session#emulate.
Anything left unset renders at a fixed default — a plain desktop viewport, light, screen media — rather than at whatever the machine underneath happens to prefer. That's what makes re-applying an older Emulation a clean revert rather than a patch, and what stops the same page rendering differently on a laptop and on CI.
Constant Summary collapse
- DEFAULT_VIEWPORT =
What a page looks like with nothing emulated. Applied for any viewport key the caller leaves out, so reverting is always total.
{ width: 1280, height: 800, scale: 1, mobile: false, touch: false, }.freeze
- COLOR_SCHEMES =
What
prefers-color-schemecan be told to report. [:light, :dark, :no_preference].freeze
- REDUCED_MOTIONS =
What
prefers-reduced-motioncan be told to report. [:reduce, :no_preference].freeze
- MEDIA_TYPES =
What the page can be told it's being rendered for.
[:screen, :print].freeze
- DEFAULT_USER_AGENT =
Present as a current desktop Chrome rather than as a headless build: pages render the way a real visitor sees them, and modern-browser gates let us through.
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 " \ "(KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
Instance Attribute Summary collapse
-
#color_scheme ⇒ Object
readonly
Returns the value of attribute color_scheme.
-
#device ⇒ Object
readonly
Returns the value of attribute device.
-
#geolocation ⇒ Object
readonly
Returns the value of attribute geolocation.
-
#locale ⇒ Object
readonly
Returns the value of attribute locale.
-
#media ⇒ Object
readonly
Returns the value of attribute media.
-
#reduced_motion ⇒ Object
readonly
Returns the value of attribute reduced_motion.
-
#timezone ⇒ Object
readonly
Returns the value of attribute timezone.
-
#user_agent ⇒ Object
readonly
Returns the value of attribute user_agent.
-
#viewport ⇒ Object
readonly
Returns the value of attribute viewport.
Class Method Summary collapse
-
.build(value) ⇒ Emulation
Coerce whatever a caller passed as
emulate:into an Emulation.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
(also: #eql?)
Whether the other emulation has the same settings.
-
#apply(page) ⇒ void
Push the whole configuration onto a live page.
-
#default? ⇒ Boolean
Whether every knob is at Chrome's default.
-
#hash ⇒ Integer
A hash of the settings, so an emulation works as a hash key.
-
#initialize(color_scheme: nil, reduced_motion: nil, viewport: nil, device: nil, user_agent: nil, locale: nil, timezone: nil, geolocation: nil, media: nil) ⇒ Emulation
constructor
A new instance of Emulation.
-
#merge(other) ⇒ Emulation
A copy with +other+'s settings layered on top.
-
#resolved_user_agent ⇒ String
The user agent sent to Chrome.
-
#resolved_viewport ⇒ Puppeteer::Viewport
The viewport actually sent to Chrome: the device's, with any explicit
viewport:keys layered over it, over the plain-desktop default. -
#to_h ⇒ Hash
The knobs, unset ones included as nil.
Constructor Details
#initialize(color_scheme: nil, reduced_motion: nil, viewport: nil, device: nil, user_agent: nil, locale: nil, timezone: nil, geolocation: nil, media: nil) ⇒ Emulation
Returns a new instance of Emulation.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/unmagic/browser/emulation.rb', line 77 def initialize(color_scheme: nil, reduced_motion: nil, viewport: nil, device: nil, user_agent: nil, locale: nil, timezone: nil, geolocation: nil, media: nil) @color_scheme = validate_symbol(:color_scheme, color_scheme, COLOR_SCHEMES) @reduced_motion = validate_symbol(:reduced_motion, reduced_motion, REDUCED_MOTIONS) @media = validate_symbol(:media, media, MEDIA_TYPES) @viewport = &.transform_keys(&:to_sym)&.freeze @device = device @user_agent = user_agent @locale = locale @timezone = timezone @geolocation = geolocation&.transform_keys(&:to_sym)&.freeze validate_device! freeze end |
Instance Attribute Details
#color_scheme ⇒ Object (readonly)
Returns the value of attribute color_scheme.
65 66 67 |
# File 'lib/unmagic/browser/emulation.rb', line 65 def color_scheme @color_scheme end |
#device ⇒ Object (readonly)
Returns the value of attribute device.
65 66 67 |
# File 'lib/unmagic/browser/emulation.rb', line 65 def device @device end |
#geolocation ⇒ Object (readonly)
Returns the value of attribute geolocation.
65 66 67 |
# File 'lib/unmagic/browser/emulation.rb', line 65 def geolocation @geolocation end |
#locale ⇒ Object (readonly)
Returns the value of attribute locale.
65 66 67 |
# File 'lib/unmagic/browser/emulation.rb', line 65 def locale @locale end |
#media ⇒ Object (readonly)
Returns the value of attribute media.
65 66 67 |
# File 'lib/unmagic/browser/emulation.rb', line 65 def media @media end |
#reduced_motion ⇒ Object (readonly)
Returns the value of attribute reduced_motion.
65 66 67 |
# File 'lib/unmagic/browser/emulation.rb', line 65 def reduced_motion @reduced_motion end |
#timezone ⇒ Object (readonly)
Returns the value of attribute timezone.
65 66 67 |
# File 'lib/unmagic/browser/emulation.rb', line 65 def timezone @timezone end |
#user_agent ⇒ Object (readonly)
Returns the value of attribute user_agent.
65 66 67 |
# File 'lib/unmagic/browser/emulation.rb', line 65 def user_agent @user_agent end |
#viewport ⇒ Object (readonly)
Returns the value of attribute viewport.
65 66 67 |
# File 'lib/unmagic/browser/emulation.rb', line 65 def @viewport end |
Class Method Details
.build(value) ⇒ Emulation
Coerce whatever a caller passed as emulate: into an Emulation.
54 55 56 57 58 59 60 61 62 |
# File 'lib/unmagic/browser/emulation.rb', line 54 def build(value) case value when nil then new when Emulation then value when Hash then new(**value) else raise ArgumentError, "emulate: expects an Unmagic::Browser::Emulation or a Hash, got #{value.class}" end end |
Instance Method Details
#==(other) ⇒ Boolean Also known as: eql?
Returns whether the other emulation has the same settings.
126 127 128 |
# File 'lib/unmagic/browser/emulation.rb', line 126 def ==(other) other.is_a?(Emulation) && other.to_h == to_h end |
#apply(page) ⇒ void
This method returns an undefined value.
Push the whole configuration onto a live page. Every knob is sent every time — including the ones left unset, which are sent as their defaults — so applying an Emulation always lands the page in exactly this state, whatever it was in before.
143 144 145 146 147 148 149 150 |
# File 'lib/unmagic/browser/emulation.rb', line 143 def apply(page) page. = page.user_agent = resolved_user_agent page.emulate_locale(@locale) page.emulate_timezone(@timezone) apply_geolocation(page) apply_media(page) end |
#default? ⇒ Boolean
Returns whether every knob is at Chrome's default.
120 121 122 |
# File 'lib/unmagic/browser/emulation.rb', line 120 def default? to_h.values.all?(&:nil?) end |
#hash ⇒ Integer
Returns a hash of the settings, so an emulation works as a hash key.
132 133 134 |
# File 'lib/unmagic/browser/emulation.rb', line 132 def hash to_h.hash end |
#merge(other) ⇒ Emulation
A copy with +other+'s settings layered on top. Only keys the other side
actually set are overridden, so emulate(color_scheme: :dark) on a
session that's already emulating a phone keeps the phone.
99 100 101 102 |
# File 'lib/unmagic/browser/emulation.rb', line 99 def merge(other) other = self.class.build(other) self.class.new(**to_h.merge(other.to_h) { |_key, mine, theirs| theirs.nil? ? mine : theirs }) end |
#resolved_user_agent ⇒ String
Returns the user agent sent to Chrome.
169 170 171 |
# File 'lib/unmagic/browser/emulation.rb', line 169 def resolved_user_agent @user_agent || puppeteer_device&.user_agent || DEFAULT_USER_AGENT end |
#resolved_viewport ⇒ Puppeteer::Viewport
The viewport actually sent to Chrome: the device's, with any explicit
viewport: keys layered over it, over the plain-desktop default.
156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/unmagic/browser/emulation.rb', line 156 def base = DEFAULT_VIEWPORT.merge().merge(@viewport || {}) Puppeteer::Viewport.new( width: base[:width], height: base[:height], device_scale_factor: base[:scale] || 1, is_mobile: !!base[:mobile], has_touch: !!base[:touch], is_landscape: base[:width] > base[:height], ) end |
#to_h ⇒ Hash
Returns the knobs, unset ones included as nil.
105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/unmagic/browser/emulation.rb', line 105 def to_h { color_scheme: @color_scheme, reduced_motion: @reduced_motion, viewport: @viewport, device: @device, user_agent: @user_agent, locale: @locale, timezone: @timezone, geolocation: @geolocation, media: @media, } end |