ferrum icon indicating copy to clipboard operation
ferrum copied to clipboard

innerHeight is incorrect and frozen

Open Nakilon opened this issue 3 years ago • 6 comments

br = Ferrum::Browser.new   # no matter :headless true or false
br.evaluate "[innerHeight, outerHeight]"

The innerHeight is expected to be smaller than outerHeight: https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight But in fact they are equal and innerHeight is frozen (at 768). When I resize the window it does not change. Also because of this the third-party JS scripts are unable to correctly obtain the client area and resize the content beyond it.

v 0.11, macOS Big Sur

Nakilon avatar Oct 17 '21 22:10 Nakilon

I've commented this out https://github.com/rubycdp/ferrum/blob/7f376402a07409696d8166e616adf918f88435ed/lib/ferrum/page.rb#L104-L109 and the issue is gone. What is that anyway? Its parameters don't even match the https://chromedevtools.github.io/devtools-protocol/tot/Emulation/#method-setDeviceMetricsOverride

Nakilon avatar Oct 17 '21 23:10 Nakilon

These are params that are passed to Emulation.setDeviceMetricsOverride except slowmoable. Could you write a failing test?

route avatar Oct 18 '21 05:10 route

except slowmoable

I don't see fitwiondow neither. I guess it's just outdated. I tried to find what's the point of this command at all but it dates to the first commit of the repo.

Could you write a failing test?

I suppose the simplest assertion is that innerHeight should be smaller than outerHeight in non-fullscreen mode that should be true for any browser.

Other than that probably more reliable would be to craft a HTML page with a node absolutely positioned from 0 to inner... and maybe Ferrum provides a method to see if the node is fully visible. Or maybe if there is only a method to check partial visibility then to craft 4 lines just outside and inside the borders of the rect. Unless these methods depend on the malfunctioning inner...` in the first place

Or maybe try to issue a mouse click event on a positioned element -- pretty sure it won't work if the element is really outside.

Nakilon avatar Oct 18 '21 05:10 Nakilon

I thought about creating a 1x1 pixel buttons to test if they are clickable but if you zoom it you'd see that buttons are catching the click event on a larger area even with CSS styles applied to make them rectangle and small.

Then I thought that you could screenshot a page and see (with help of chunky_png that is already in the Gemfile) how the rectangle drawn within inner isn't taking all the window space but it appeared that ferrum's screenshot thing is taking exactly the html or body tag size and does not have a clue the real window was larger. (btw, the addition to the initial report: the simplest way to see that it's bugged is that when you resize the window the page remains intact, because those sizes are frozen for the html page runtime). So the only way to screenshot the issue is on the OS level.

P.S.: the "allows the window to be positioned" in bundle exec rspec spec/browser_spec.rb fails on my machine because the initial coordinates appear to be not (0,0) and I'm not sure why the tests even assume that. AFAIK when I was adding/editing those tests I explicitly wrote them in a way that does not assume the starting coordinates, idk why it was changed.

Nakilon avatar Apr 28 '22 22:04 Nakilon

Another thing I see (called binding.irb at the start of some test) is that the things are fixed right after any programmatic resizing:

irb(#<RSpec::ExampleGroups::FerrumBrowser:0x00007ff5c82718f0>):002:0> browser.evaluate "[innerHeight, outerHeight]"
=> [768, 768]
irb(#<RSpec::ExampleGroups::FerrumBrowser:0x00007ff5c82718f0>):003:0> browser.evaluate "[innerWidth, outerWidth]"
=> [1024, 1024]
irb(#<RSpec::ExampleGroups::FerrumBrowser:0x00007ff5c82718f0>):004:0> browser.resize width: 100, height: 100
=> {}
irb(#<RSpec::ExampleGroups::FerrumBrowser:0x00007ff5c82718f0>):005:0> browser.evaluate "[innerWidth, outerWidth]"
=> [100, 514]
irb(#<RSpec::ExampleGroups::FerrumBrowser:0x00007ff5c82718f0>):006:0> browser.evaluate "[innerHeight, outerHeight]"
=> [100, 385]

UPD: nevermind, it's just because of the minimal possible window size. If you increase the window, you'd see the issue is still there:

irb(#<RSpec::ExampleGroups::FerrumBrowser:0x00007ff4b02d6110>):030:0> browser.resize width: 2000, height: 1400
=> {}
irb(#<RSpec::ExampleGroups::FerrumBrowser:0x00007ff4b02d6110>):031:0> browser.evaluate "[innerWidth, outerWidth]"
=> [2000, 2000]
irb(#<RSpec::ExampleGroups::FerrumBrowser:0x00007ff4b02d6110>):032:0> browser.evaluate "[innerHeight, outerHeight]"
=> [1400, 1400]

Nakilon avatar Apr 28 '22 22:04 Nakilon

I would just delete that line if it does not break anything. As I said I see no reason why it's even there, since it's in the first commit. While it breaks the websites layout in the way that page does not fit the window and people have to scroll the page that would not be needed in a normal browser. At least on the headfull macOS. I see no way to fully test it without going to OS level screenshotting, and if not that then:

I suppose the simplest assertion is that innerHeight should be smaller than outerHeight in non-fullscreen mode that should be true for any browser.

Nakilon avatar Apr 28 '22 22:04 Nakilon

OS level screenshotting

For example, craft an html page with with 4 colored pixels on the absolute coordinates, then find the UI element with applescript, screenshot the region and analyze with some chunkypng. Can be done on headfull macOS.

Nakilon avatar Mar 29 '23 09:03 Nakilon

How about this fix I merged to master https://github.com/rubycdp/ferrum/pull/331 was it the reason for your issue?

route avatar Jul 14 '23 05:07 route

I believe I had to add it because of Cuprite that don't apply window-size on MacOS. I think after all that time it still doesn't work, so this resize on the browser start was done for that reason.

route avatar Sep 13 '23 10:09 route

How about this fix I merged to master #331 was it the reason for your issue?

I don't believe it's fixed.

my fork:

image

ruby 2.5 + manual patch,
ruby 2.6 + ferrum 0.14,
ruby 2.6 + ferrum master:

image

Nakilon avatar Sep 16 '23 08:09 Nakilon

BTW why are you still on ruby 2.6? isn't easy to upgrade?)

route avatar Sep 16 '23 09:09 route

Can you attach the script, for me for easy repro?

route avatar Sep 16 '23 10:09 route

require "ferrum"
browser = Ferrum::Browser.new window_size: [100, 100], headless: false
browser.go_to "https://vk.com"
gets
bundle install
bundle exec ruby main.rb
source "https://rubygems.org"
gem "ferrum", github: "rubycdp/ferrum"
image
source "https://rubygems.org"
gem "ferrum", github: "nakilon/ferrum"
image

or just any window size and try to resize the window with your mouse

Nakilon avatar Sep 16 '23 12:09 Nakilon

I'm removing this resize call when page is created. I think there was a confusion from my side about --window-size not working on MacOS back then and cuprite requirements.

I think we don't need to support all this in Ferrum as it has to involve less magick than Cuprite. You can resize any page whenever you want and new pages not obliged to inherit this sizу. It's useful for capybara and tests but not for Ferrum. So I'll just move this part to Cuprite.

As for incorrect and frozen innerHeight, well I guess in headless mode it goes nuts, but headful mode is ok. So this issue/question goes to Chrome team.

I hope that removal of the resize call will satisfy you. Let me know please.

route avatar Dec 21 '23 08:12 route