public
Last active

Test PDF within Cucumber and Capybara

  • Download Gist
Gemfile
Ruby
1 2 3 4 5 6
# normal Gem dependancy declarations
# ...
 
group :test, :cucumber do
gem 'pdf-reader'
end
pdf_steps.rb
Ruby
1 2 3 4 5 6 7 8
When /^I follow the PDF link "([^"]+)"$/ do |label|
click_link(label)
temp_pdf = Tempfile.new('pdf')
temp_pdf << page.source.force_encoding('UTF-8')
temp_pdf.close
pdf_text = PDF::PdfToText.new(temp_pdf.path)
page.driver.response.instance_variable_set('@body', pdf_text.get_text)
end
pdf_test.feature
Cucumber
1 2 3 4
Scenario: Check printable PDF
When I follow the PDF link "Print"
Then I should see "My name"
And I should see "Something else"
pdf_to_text.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12
module PDF
class PdfToText
def initialize(pdf_file)
@receiver = PDF::SimplePageTextReceiver.new
pdf = PDF::Reader.file(pdf_file, @receiver)
end
 
def get_text
@receiver.content.inspect
end
end
end
simple_page_text_receiver.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
module PDF
class SimplePageTextReceiver
attr_accessor :content
 
def initialize
@content = []
end
 
# Called when page parsing starts
def begin_page(arg = nil)
@content << ""
end
 
# record text that is drawn on the page
def show_text(string, *params)
@content.last << string.strip
end
 
# there's a few text callbacks, so make sure we process them all
alias :super_show_text :show_text
alias :move_to_next_line_and_show_text :show_text
alias :set_spacing_next_line_show_text :show_text
 
# this final text callback takes slightly different arguments
def show_text_with_positioning(*params)
params = params.first
params.each { |str| show_text(str) if str.kind_of?(String)}
end
end
end

Thank you for the page.driver.response.instance_variable_set bit, I was trying to figure that out for the last 2 hours. I was able to avoid using any temp files or extra modules by using pdf-inspector instead of pdf-reader:

require "pdf/inspector"

Then /^I should be served the referral document as a PDF$/ do
  page.response_headers['Content-Type'].should == "application/pdf"
  pdf = PDF::Inspector::Text.analyze(page.source).strings.join(" ")
  page.driver.response.instance_variable_set('@body', pdf)
end

Then /^I should see the referral document details$/ do
  page.should have_content("#{@document.customer.name}")
  page.should have_content("#{@document.resources.first.resource.name}")
  page.should have_content("Document opened at #{@document.created_at.strftime("%e-%b-%4Y %r")}")
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.