Reputation: 25
I'm trying to use browser.scroll.to :bottom but nothing happens. I know that it works because I've tried it on public facing sites such as the BBC and Wikipedia, but for some reason, these scroll commands don't work on our in-house browser based app.
Does anyone know of any reasons or settings that could be preventing this from happening? Things such as browser.refresh and browser.window.maximize work fine but the scrolling literally refuses to budge.
Here's what my code looks like:
require 'watir'
require_relative 'regression_config_bob01.rb'
require 'date'
require 'faker'
require 'slack-notifier'
require 'watir-scroll'
user_name = "blah"
password = "blah"
test_env = "the Site"
browser = Watir::Browser.new
browser.goto(test_env)
# Login
browser.text_field(:name => 'P101_USERNAME').set user_name
browser.text_field(:tabindex=> '2').set password
browser.link(:text => "Log in").click
sleep 20
browser.wd.action.scroll_by(0, 1000).perform # Suggested Scroll line
print "done"
sleep 30
temporary_exp.rb:62:in <main>': undefined method
scroll_by' for #<Selenium::WebDriver::W3CActionBuilder:0x000000014ac54bd0 @bridge=#<Selenium::WebDriver::Remote::W3C::Bridge:0x000000014ac1e440 @capabilities=#<Selenium::WebDriver::Remote::W3C::Capabilities:0x000000014ac1e940 @capabilities={:proxy=>nil, :browser_name=>"chrome", :browser_version=>"106.0.5249.119", :platform_name=>"mac os x", :accept_insecure_certs=>false, :page_load_strategy=>"normal", :implicit_timeout=>0, :page_load_timeout=>300000, :script_timeout=>30000, :remote_session_id=>nil, :accessibility_checks=>nil, :profile=>nil, :rotatable=>nil, :device=>nil, "chrome"=>{"chromedriverVersion"=>"105.0.5195.52 (412c95e518836d8a7d97250d62b29c2ae6a26a85-refs/branch-heads/5195@{#853})", "userDataDir"=>"/var/folders/hb/h_0h2t79183fkkppsr6r19nc0000gn/T/.com.google.Chrome.BV85VD"}, "goog:chromeOptions"=>{"debuggerAddress"=>"localhost:50818"}, "networkConnectionEnabled"=>false, "setWindowRect"=>true, "strictFileInteractability"=>false, "unhandledPromptBehavior"=>"dismiss and notify", "webauthn:extension:credBlob"=>true, "webauthn:extension:largeBlob"=>true, "webauthn:virtualAuthenticators"=>true}>, @session_id="8c59128dd44054681f62819d2fed25cf", @http=#<Watir::HttpClient:0x000000014ab6e298 @open_timeout=60, @read_timeout=nil, @server_url=#<URI::HTTP http://127.0.0.1:9515/>, @proxy=nil, @http=#<Net::HTTP 127.0.0.1:9515 open=true>>, @file_detector=nil, @escaper=#URI::RFC2396_Parser:0x000000014b0cbbc8, @manage=#<Selenium::WebDriver::W3CManager:0x000000014ab640b8 @bridge=#<Selenium::WebDriver::Remote::W3C::Bridge:0x000000014ac1e440 ...>, @window=#<Selenium::WebDriver::Window:0x000000014aa17ca0 @bridge=#<Selenium::WebDriver::Remote::W3C::Bridge:0x000000014ac1e440 ...>>>>, @devices=[#<Selenium::WebDriver::Interactions::PointerInput:0x000000014ac54f40 @name="mouse", @actions=[], @kind=:mouse>, #<Selenium::WebDriver::Interactions::KeyInput:0x000000014ac54d38 @name="keyboard", @actions=[]>], @async=false> (NoMethodError)
Upvotes: 0
Views: 197
Reputation: 4194
The current scroll implementation is using javascript to move the page around. For some reason your app is not responding to the JS commands in the normal way.
Selenium has recently released native scrolling via the drivers that Watir has not yet been updated. Take a look at the Selenium documentation on it: https://www.selenium.dev/documentation/webdriver/actions_api/wheel/?language=ruby
To use this in watir, you just need to add the line to the top: driver = browser.wd
So to scroll down by 2000 pixels, you can do:
driver = browser.wd
driver.action
.scroll_by(0, 2000)
.perform
Upvotes: 1
Reputation: 76
like Titus said, Watir is a wrapper for Selenium and lets you write shorter and prettier code, like
browser.scroll.to :bottom
browser.scroll.to :top
browser.element(id: "asd").scroll.to
but when (for any reason) it doesn't work you can use Selenium syntax directly by sending commands to browser.wd
instead browser
like this:
browser.wd.action.scroll_by(0, 1000).perform #this scrolls bottom
browser.wd.action.scroll_by(0, -1000).perform #this scrolls top
browser.wd.action.scroll_to(browser.wd.find_element(id: "asd")).perform
but instead of writing browser.wd
every time you need to talk to driver directly, you can type driver = browser.wd
so your code is more clear:
driver = browser.wd
driver.action.scroll_by(0, 1000).perform #this scrolls bottom
driver.action.scroll_by(0, -1000).perform #this scrolls top
some_element = driver.find_element(id: "asd")
driver.action.scroll_to(some_element).perform
There are countless examples where using Watir is more efficient than talking to driver directly, you just happened to encounter an edge case.
Also try avoiding sleep
when possible, instead, wait for something to show, like:
browser.element(id: 'asd').wait_until(&:present?)
browser.element(id: 'asd').wait_until({ |el| el.text == "Success" })
some_element = browser.element(id: 'asd')
browser.wait_until(30){some_element.present?}
Instead of .element
you can use correct subclass like .div
, .button
, .span
etc
Upvotes: 0