Skip to content

Clicking a link which inserts a lazy loaded iframe times out #303

@martinschaflitzl1

Description

@martinschaflitzl1

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions