cuprite icon indicating copy to clipboard operation
cuprite copied to clipboard

Clicking a link which inserts a lazy loaded iframe times out

Open martinschaflitzl1 opened this issue 5 months ago • 0 comments

Hi,

I ran into an issue, when trying to insert a lazy loaded iframe into the page out of the viewport, i get a Ferrum::TimeoutError. Below is a boiled down test reproducing the issue. My theory is, that something waits for the page/network to be idle, but fails, as the request of that iframe is pending until scrolled into view. When the iframe is in view, the test is successful.

I feel like this should just work.

describe 'synchronization' do

  it 'does insert a iframe' do
    App.start_html = <<~HTML
      <a href="#" onclick="
        let iframe = document.createElement('iframe');
        iframe.setAttribute('loading', 'lazy');
        iframe.src = '/next';
        document.body.append(iframe);
      ">label</a>

      #{(1...500).map { |i| "<p>#{i}</p>" }.join}
    HTML

    visit '/start'
    page.find('a').click
  end

end

This fails with:

  1) iframe does add an iframe with [loading=lazy]
     Failure/Error: page.find('a').click
     
     Ferrum::TimeoutError:
       Timed out waiting for response. It's possible that this happened because something took a very long time (for example a page load was slow). If so, setting the :timeout option to a higher value might help.
     # ./spec/features/synchronization_spec.rb:17:in `block (2 levels) in <top (required)>'
Other relevant files

app.rb

require 'sinatra'
require 'active_support/core_ext/class/attribute'

class App < Sinatra::Base
  class_attribute :start_html, :start_script
  delegate :start_html, :start_script, :reset, to: :class

  get '/start' do
    render_body(<<~HTML)
      #{start_html}
      <script>#{start_script}</script>
    HTML
  end

  def self.reset
    self.start_html = 'hi world'
    self.start_script = 'console.log("loaded")'
  end

  private

  def render_body(content)
    <<~HTML
      <html>
        <head>
        </head>
        <body>
          #{content}
        </body>
      </html>
    HTML
  end

end

spec_helper.rb

require 'byebug'
require 'capybara'
require 'capybara/rspec'
require "rspec/wait"
require 'active_support/dependencies/autoload'
require 'active_support/core_ext/numeric'
require 'base64'
require 'selenium-webdriver'
require "capybara/cuprite"

# Load all files in spec/support
Dir["#{__dir__}/support/**/*.rb"].each { |f| require f }

RSpec.configure do |config|
  config.include Capybara::DSL
  config.include Capybara::RSpecMatchers
  config.before(:each) { App.reset }
  config.wait_timeout = 5
  config.wait_delay = 0.02
end


cuprite_options = {
  window_size: [1280, 1024],
  headless: !ENV['NO_HEADLESS'],
  timeout: 1, # Keep the short timeout for now
}

Capybara.register_driver :chrome_cuprite do |app|
  Capybara::Cuprite::Driver.new(app, **cuprite_options)
end

Capybara.default_driver = :chrome_cuprite

Capybara.configure do |config|
  config.app = App
  config.server_host = 'localhost'
  config.default_max_wait_time = 1
end

Gemfile

# frozen_string_literal: true

source "https://rubygems.org"

gem 'activesupport', '~> 6.0'
gem "rake", "~> 13.0"

gem "rspec", "~> 3.0"
gem "rspec-wait", '~> 0.0.10' 
gem 'sinatra'
gem 'thin' 
gem 'puma'
gem 'byebug'
gem 'gemika', '>= 0.8.1'
gem 'capybara', '>= 3'
gem 'selenium-webdriver', '>= 4'
gem 'cuprite'

gem 'base64' # needed by selenium-webdriver (and potentially others)
gem 'bigdecimal' # needed by activesupport (and potentially others)

Gemfile.lock

GEM
  remote: https://rubygems.org/
  specs:
    activesupport (6.1.7)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      i18n (>= 1.6, < 2)
      minitest (>= 5.1)
      tzinfo (~> 2.0)
      zeitwerk (~> 2.3)
    addressable (2.8.5)
      public_suffix (>= 2.0.2, < 6.0)
    base64 (0.2.0)
    bigdecimal (3.1.8)
    byebug (11.1.3)
    capybara (3.39.2)
      addressable
      matrix
      mini_mime (>= 0.1.3)
      nokogiri (~> 1.8)
      rack (>= 1.6.0)
      rack-test (>= 0.6.3)
      regexp_parser (>= 1.5, < 3.0)
      xpath (~> 3.2)
    childprocess (4.1.0)
    concurrent-ruby (1.1.10)
    cuprite (0.17)
      capybara (~> 3.0)
      ferrum (~> 0.17.0)
    daemons (1.4.1)
    diff-lcs (1.5.1)
    eventmachine (1.2.7)
    ferrum (0.17.1)
      addressable (~> 2.5)
      base64 (~> 0.2)
      concurrent-ruby (~> 1.1)
      webrick (~> 1.7)
      websocket-driver (~> 0.7)
    gemika (0.8.1)
    i18n (1.12.0)
      concurrent-ruby (~> 1.0)
    matrix (0.4.2)
    mini_mime (1.1.5)
    mini_portile2 (2.8.5)
    minitest (5.16.3)
    mustermann (3.0.0)
      ruby2_keywords (~> 0.0.1)
    nio4r (2.6.1)
    nokogiri (1.15.5)
      mini_portile2 (~> 2.8.2)
      racc (~> 1.4)
    public_suffix (5.0.4)
    puma (6.4.0)
      nio4r (~> 2.0)
    racc (1.7.3)
    rack (2.2.8)
    rack-protection (3.1.0)
      rack (~> 2.2, >= 2.2.4)
    rack-test (2.1.0)
      rack (>= 1.3)
    rake (13.1.0)
    regexp_parser (2.8.2)
    rexml (3.2.5)
    rspec (3.13.0)
      rspec-core (~> 3.13.0)
      rspec-expectations (~> 3.13.0)
      rspec-mocks (~> 3.13.0)
    rspec-core (3.13.0)
      rspec-support (~> 3.13.0)
    rspec-expectations (3.13.1)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.13.0)
    rspec-mocks (3.13.1)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.13.0)
    rspec-support (3.13.1)
    rspec-wait (0.0.10)
      rspec (>= 3.0)
    ruby2_keywords (0.0.5)
    rubyzip (2.3.2)
    selenium-webdriver (4.1.0)
      childprocess (>= 0.5, < 5.0)
      rexml (~> 3.2, >= 3.2.5)
      rubyzip (>= 1.2.2)
    sinatra (3.1.0)
      mustermann (~> 3.0)
      rack (~> 2.2, >= 2.2.4)
      rack-protection (= 3.1.0)
      tilt (~> 2.0)
    thin (1.8.2)
      daemons (~> 1.0, >= 1.0.9)
      eventmachine (~> 1.0, >= 1.0.4)
      rack (>= 1, < 3)
    tilt (2.3.0)
    tzinfo (2.0.5)
      concurrent-ruby (~> 1.0)
    webrick (1.9.1)
    websocket-driver (0.8.0)
      base64
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.5)
    xpath (3.2.0)
      nokogiri (~> 1.8)
    zeitwerk (2.6.0)

PLATFORMS
  ruby

DEPENDENCIES
  activesupport (~> 6.0)
  base64
  bigdecimal
  byebug
  capybara (>= 3)
  cuprite
  gemika (>= 0.8.1)
  puma
  rake (~> 13.0)
  rspec (~> 3.0)
  rspec-wait (~> 0.0.10)
  selenium-webdriver (>= 4)
  sinatra
  thin

BUNDLED WITH
   2.3.1

martinschaflitzl1 avatar Aug 04 '25 16:08 martinschaflitzl1