Top Level Namespace

Defined Under Namespace

Modules: Bidi2pdf

Constant Summary collapse

ChromedriverTestcontainer =

alias the long class name

Bidi2pdf::TestHelpers::Testcontainers::ChromedriverContainer

Instance Method Summary collapse

Instance Method Details

#chromedriver_tests_present?Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/bidi2pdf/test_helpers/testcontainers/chromedriver_test_helper.rb', line 80

def chromedriver_tests_present?
  test_of_kind_present? :chromedriver
end

#contains_pdf_textBoolean

Custom RSpec matcher for checking whether a PDF document contains specific text.

This matcher allows you to assert that a certain string or regular expression is present in the sanitized text of a PDF document.

It supports chaining with ‘.at_page(n)` to limit the search to a specific page.

## Examples

expect(pdf_data).to contains_pdf_text("Total: 123.45")
expect(pdf_data).to contains_pdf_text(/Invoice #\d+/).at_page(2)

Parameters:

  • expected (String, Regexp)

    The text or pattern to match inside the PDF.

Returns:

  • (Boolean)

    true if the expected content is found (on the given page if specified)



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/bidi2pdf/test_helpers/matchers/contains_pdf_text.rb', line 20

RSpec::Matchers.define :contains_pdf_text do |expected|
  chain :at_page do |page_number|
    @page_number = page_number
  end

  match do |actual|
    Bidi2pdf::TestHelpers::PDFTextSanitizer.contains?(actual, expected, @page_number)
  end

  failure_message do |actual|
    pages = Bidi2pdf::TestHelpers::PDFTextSanitizer.clean_pages(actual)

    return "Document does not contain page #{@page_number}" if @page_number && !(@page_number && @page_number <= pages.size)

    <<~MSG
      PDF text did not contain expected content.

      --- Expected (#{expected.inspect}) ---
      On page #{@page_number || "any"}:

      --- Actual ---
      #{pages.each_with_index.map { |text, i| "Page #{i + 1}:\n#{text}" }.join("\n\n")}
    MSG
  end

  description do
    desc = "contain #{expected.inspect} in PDF"
    desc += " on page #{@page_number}" if @page_number
    desc
  end
end

#have_pdf_page_countRSpec::Matchers::Matcher

Note:

This matcher depends on ‘Bidi2pdf::TestHelpers::PDFReaderUtils.pdf_reader_for` to extract the page count. Make sure it supports all your intended input formats.

RSpec matcher to assert the number of pages in a PDF document.

This matcher is useful for verifying the structural integrity of generated or uploaded PDFs, especially in tests for reporting, invoice generation, or document exports.

It supports a variety of input types:

  • Raw PDF data as a ‘String`

  • File paths (‘String`)

  • ‘StringIO` or `File` objects

  • Even Base64-encoded strings, if your ‘pdf_reader_for` method handles it

## Example

expect(pdf_data).to have_pdf_page_count(5)
expect(StringIO.new(pdf_data)).to have_pdf_page_count(3)

If the PDF is malformed, the matcher will gracefully fail and show the error message.

Parameters:

  • expected_count (Integer)

    The number of pages the PDF is expected to contain.

Returns:

  • (RSpec::Matchers::Matcher)

    The matcher object for use in specs.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/bidi2pdf/test_helpers/matchers/have_pdf_page_count.rb', line 29

RSpec::Matchers.define :have_pdf_page_count do |expected_count|
  match do |pdf_data|
    reader = Bidi2pdf::TestHelpers::PDFReaderUtils.pdf_reader_for(pdf_data)
    @actual_count = reader.page_count
    @actual_count == expected_count
  rescue PDF::Reader::MalformedPDFError => e
    @error_message = e.message
    false
  end

  failure_message do |_pdf_data|
    if @error_message
      "Expected a valid PDF with #{expected_count} pages, but encountered an error: #{@error_message}"
    else
      "Expected PDF to have #{expected_count} pages, but it has #{@actual_count} pages"
    end
  end

  description do
    "have #{expected_count} PDF pages"
  end
end

#match_pdf_textRSpec::Matchers::Matcher

Note:

Ensure ‘PDFTextSanitizer.match?` and `PDFTextSanitizer.clean_pages` are implemented to handle your specific PDF processing logic.

Custom RSpec matcher to compare the **sanitized text content** of two PDF files.

This matcher is useful for comparing PDF documents where formatting and metadata may differ, but the actual visible text content should be the same. It uses ‘PDFTextSanitizer` internally to normalize and clean the text before comparison.

## Example

expect(actual_pdf).to match_pdf_text(expected_pdf)

If the texts don’t match, it prints a diff-friendly message showing cleaned text content.

Parameters:

  • expected (String, StringIO, File)

    The expected PDF content (can be a file path, StringIO, or raw string).

Returns:

  • (RSpec::Matchers::Matcher)

    An RSpec matcher to compare against an actual PDF.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/bidi2pdf/test_helpers/matchers/match_pdf_text.rb', line 22

RSpec::Matchers.define :match_pdf_text do |expected|
  match do |actual|
    Bidi2pdf::TestHelpers::PDFTextSanitizer.match?(actual, expected)
  end

  failure_message do |actual|
    cleaned_actual = Bidi2pdf::TestHelpers::PDFTextSanitizer.clean_pages(actual)
    cleaned_expected = Bidi2pdf::TestHelpers::PDFTextSanitizer.clean_pages(expected)

    <<~MSG
      PDF text did not match.

      --- Expected ---
      #{cleaned_expected.join("\n")}

      --- Actual ---
      #{cleaned_actual.join("\n")}
    MSG
  end

  description do
    "match sanitized PDF text content"
  end
end

#start_chromedriver_container(build_dir:, mounts:, shared_network:) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/bidi2pdf/test_helpers/testcontainers/chromedriver_test_helper.rb', line 91

def start_chromedriver_container(build_dir:, mounts:, shared_network:)
  container = ChromedriverTestcontainer.new(ChromedriverTestcontainer::DEFAULT_IMAGE,
                                            build_dir: build_dir,
                                            docker_file: "docker/Dockerfile.chromedriver")
                                       .with_network(shared_network)
                                       .with_network_aliases("remote-chrome")

  container.with_filesystem_binds(mounts) if mounts&.any?

  container.start

  container
end

#stop_container(container) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/bidi2pdf/test_helpers/testcontainers/chromedriver_test_helper.rb', line 63

def stop_container(container)
  if container&.running?

    if ENV["SHOW_CONTAINER_LOGS"]
      puts "Container logs:"
      logs_std, logs_error = container.logs

      puts logs_error
      puts logs_std
    end

    puts "🧹 #{container.image} stopping container..."
    container.stop
  end
  container&.remove
end

#test_of_kind_present?(type) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/bidi2pdf/test_helpers/testcontainers/chromedriver_test_helper.rb', line 84

def test_of_kind_present?(type)
  RSpec.world.filtered_examples.values.flatten.any? { |example| example.[type] }
end