heroku / heroku-buildpack-chrome-for-testing

Heroku Buildpack that installs Chrome for Testing
16 stars 10 forks source link

Ferrum screenshots failing after buildpack switch from heroku/google-chrome #27

Open kanejamison opened 2 weeks ago

kanejamison commented 2 weeks ago

I switched over from heroku/google-chrome this week and followed the instructions on Migrating from Separate Buildpacks (though I used the Heroku app settings UI to remove and add the new buildpacks instead of CLI): image

Since then we have a cron job running screenshots using Ferrum that has started failing with the following error:

ERROR taking screenshot: Browser did not produce websocket url within 10 seconds, try to increase:process_timeout. See https://github.com/rubycdp/ferrum#customization

Actions I've taken to try and resolve:

Are there any clear gotchas I should be looking for related to the buildpack usage or migration that I'm missing?

Relevant app settings:

Here's the script I'm running that is failing in case it's helpful. We don't have a specific Ferrum config outside of this call to Ferrum::Browser.new(). The final rescue StandardError => e is where my exception is getting tracked.

# frozen_string_literal: true

module ScreenshotCaptureable
  extend ActiveSupport::Concern

  included do
    BROWSER_WINDOW_SIZE = [1200, 900]

    def filename
      @filename ||= ["screenshot", self.class.name, id, Time.now.to_i].compact.map(&:to_s).map(&:parameterize).join("-")
    end

    def file_path
      @file_path ||= "public/screenshot-#{self.class.name}-#{self.id}.jpeg"
    end

    def save_screenshot_to_s3
      screenshot.attach({filename: "#{filename}.png", io: File.open(file_path), content_type: "image/jpeg"})
      self.update_columns(screenshot_updated_at: Time.current)
    end

    def capture_screenshot_via_ferrum(context)
      page = context.create_page
      url = "#{ENV['BASE_URL']}/l/#{special_screenshot_link&.uuid}/template?headless=1"
      Rails.logger.info "#{'*' * 50} #{url.inspect} #{'*' * 50}"

      page.go_to(url)
      page.mouse.scroll_to(10, 60)
      page.screenshot(path: file_path)
    end

    def self.update_next_batch_pending_screenshots
      if next_batch_for_screenshot.count == 0
        Rails.logger.info "No Templates to capture screenshots"
        return
      end

      begin
        next_batch_for_screenshot.each {|model| model.create_sharing_links unless model.readonly_sharing_link&.uuid }

        browser = Ferrum::Browser.new(slowmo: 6, window_size: BROWSER_WINDOW_SIZE, timeout: 15, process_timeout: 20)
        context = browser.contexts.create
        threads = []

        Rails.logger.info "Processing next #{next_batch_for_screenshot.count} Templates"

        next_batch_for_screenshot.each do |model|
          threads << Thread.new(context) do |c|
            begin
              model.capture_screenshot_via_ferrum(context)
              model.save_screenshot_to_s3
            rescue StandardError => e
              Rails.logger.error e.message
            end
          end
        end

        threads.each(&:join)
        context.dispose # dispose the context
        browser.quit # quit the browser instance
      rescue StandardError => e
        Rails.logger.error e.message
        Honeybadger.notify("ERROR taking screenshot: #{e.message}")
      end
    end
  end

end

Thanks for any assistance - I know this is on the support edge between the buildpack and the gem itself, but since the buildpack is what I'm migrating I wanted to start by posting here.

kanejamison commented 1 week ago

I'll add in a quick note here that which chrome and which chromedriver appears to be running successfully when our team connects via CLI, so please feel free to close if this ticket might be better for Ferrum repo.

image

mars commented 1 week ago

It seems like CDP / Chrome Devtools Protocol (apparently used by Ferrum) somehow broke with Chrome v128.

We heard reports of this issue with Selenium, and have a PR open with a draft fix/workaround.

I personally do not know much about exactly what changed in CDP, but maybe this context can help you find the cause.