Checking existence of images and favicons with RSpec and Capybara

describe "check images and favicon" do
  before { visit "url/to/check")

  it "should have the images" do
    page.should have_css('img', text: "image1.jpg")

  it "should have the favicon" do
    page.should have_xpath("/html/head/link[@href='favicon.ico']"
  end 
end

# frozen_string_literal: true

module Capybara
  module CustomMatchers
    include Capybara::DSL

    class Asset
      def asset_exists?(actual, src)
        js_script = <<JSS
xhr = new XMLHttpRequest();
xhr.open('GET', '#{src}', true);
xhr.send();
JSS
        actual.execute_script(js_script)
        status = actual.evaluate_script('xhr.status') # get js variable value
        status == 200 || status == 302
      end
    end

    class LoadImage < Asset
      def initialize(*args)
        @args = args
        @src = args.first
      end

      def matches?(actual)
        is_present = actual.has_selector?("img[src='#{@src}']")
        is_present && asset_exists?(actual, @src)
      end

      def does_not_match?(actual)
        actual.has_no_selector?("img[src='#{@src}']")
      end

      def failure_message
        "No image loaded with source: '#{@src}'"
      end

      def failure_message_when_negated
        "Image loaded with source: '#{@src}'"
      end

      def description
        "Verify if image with source: '#{@src}' is loaded"
      end
    end

    class LoadFavicon < Asset
      def initialize(*args)
        @args = args
        @rel = args.first
        @href = args.second
      end

      def matches?(actual)
        is_present = actual.has_selector?("link[rel='#{@rel}'][href='#{@href}']", visible: false)
        is_present && asset_exists?(actual, @href)
      end

      def does_not_match?(actual)
        actual.has_no_selector?("link[rel='#{@rel}'][href='#{@href}']", visible: false)
      end

      def failure_message
        "No favicon loaded with rel: '#{@rel}' and href: '#{@href}'"
      end

      def failure_message_when_negated
        "Favicon loaded with rel: '#{@rel}' and href: '#{@href}'"
      end

      def description
        "Verify if favicon with rel: '#{@rel}' and href: '#{@href}' is loaded"
      end
    end

    def load_image(*args)
      LoadImage.new(*args)
    end

    def load_favicon(*args)
      LoadFavicon.new(*args)
    end
  end
end

RSpec.configure do |config|
  config.include Capybara::CustomMatchers
end

Check https://gist.github.com/yovasx2/1c767114f2e003474a546c89ab4f90db to star and download


The question is to find out if the actual img and favicon are present. Here is the code to check that all images for the slider are present.

page.all('#carousel img').each do |img|
  visit img[:src]
  page.status_code.should be 200
end

For individual image with id myimage use

visit page.find('img#myimage')[:src]
page.status_code.should be 200

And for favicon simplest is to run the following

page.all('link[rel~="icon"]', visible: :any).each do |fav|
  visit fav[:href]
  page.status_code.should be 200
end