Recommended Free Tools
To test a real PDF download in a Capybara system test, run a Selenium-controlled Chrome session, set a writable temporary download.default_directory, disable download prompts, click the link, and wait for the file (or use a synchronized download helper). Capybara’s :rack_test driver cannot run the JavaScript or remote requests that many PDF links require.
Choose the behavior you actually need to test
There are two different PDF scenarios. A download test exercises your application’s endpoint: the browser requests a PDF, receives a response, and saves a file. A print test asks Chrome to render the current page into a PDF. The setup, assertions, and failure modes are different.
Testing a download endpoint
Use this when a user clicks “Download PDF” and your application returns a PDF response. Assert the downloaded filename, file existence, response behavior, and—when useful—the PDF contents.
Printing a page with Chrome
Use Chrome’s headless command-line printing when your requirement is a visual snapshot of a URL, not the behavior of an HTTP download link. Chrome writes output.pdf in the current working directory when you use --print-to-pdf.
#1 Best Overall
- FULL HD IPS DISPLAY - Enjoy vibrant, crystal-clear images with 178-degree wide-viewing angles
- AMD RYZEN 3 30 PROCESSOR - Everyday performance you can count on; Multitask, stream, game casually, and edit photos smoothly with responsive power and vibrant HDR visuals
- ENJOY UP TO 14 HOURS AND 15 MINUTES OF BATTERY LIFE - HP Fast Charge restores battery from 0 to 50% in approximately 45 minutes
- AMD RADEON 610M GRAPHICS - Experience smooth entertainment; Built for streaming and multitasking, enjoy realistic visuals and efficient performance for work and play
- STORAGE AND MEMORY - 512 GB PCIe NVMe M.2 SSD offers fast speed and efficient storage; and 8 GB LPDDR5 RAM memory boosts performance with higher bandwidth
Why rack_test is not enough
Capybara’s :rack_test driver is fast, but it does not execute JavaScript and cannot access remote URLs. A JavaScript-generated link, a fetch request, or a PDF hosted outside the test application therefore needs a browser driver such as Selenium with Chrome.
Capybara includes :selenium_chrome and :selenium_chrome_headless. In a Rails system test, the supported shorthand is driven_by :selenium, using: :headless_chrome.
Configure a headless Selenium driver for downloads
Give every test run a directory that is writable, isolated, and known to the assertions. Do this before the browser session starts; changing preferences after Chrome has launched will not change that session’s download behavior.
Rails system-test configuration
# test/application_system_test_case.rb
require "test_helper"
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400]
end
That configuration is sufficient for ordinary system tests, but a download test normally needs a custom driver so Chrome can receive a test-specific directory.
Free tools Windows power users keep installed
One-click scans. No signup required.
Custom Capybara driver
# spec/support/capybara.rb or test setup
require "capybara/rails"
require "selenium-webdriver"
require "tmpdir"
DOWNLOAD_DIR = Dir.mktmpdir("pdf-downloads")
Capybara.register_driver :selenium_chrome_pdf do |app|
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument("--headless")
options.add_argument("--window-size=1400,1400")
options.add_preference("download.default_directory", DOWNLOAD_DIR)
options.add_preference("download.prompt_for_download", false)
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end
The exact headless argument supported depends on the Chrome version in your development or CI image. Keep the browser and driver versions recorded with the project rather than assuming one universal compatibility matrix. The directory must be writable by the user running the test.
Use an isolated directory per test when parallelizing
A process-wide directory is simple, but parallel tests can mistake one test’s file for another’s. Prefer a per-test temporary directory when your framework allows it, and remove it during teardown. If your application always uses a fixed filename such as report.pdf, clear stale files before clicking.
Rank #2
- Intel Celeron N4120: 4 Cores & Threads, 1.1GHz Base Clock, Up to 2.6GHz Boost Clock, 4MB Cache, Intel UHD Graphics 600. The perfect combination of performance, power consumption, and value helps your device handle multitasking smoothly and reliably with four processing cores to divide up the work.
- 14" HD Display: 14.0-inch diagonal, HD (1366 x 768), micro-edge, anti-glare. See your digital world in a whole new way. Enjoy movies and photos with the great image quality and high-definition detail of 1 million pixels.
- Memory & Storage: 4 GB LPDDR4x & 64 GB eMMC Storage. Adequate high-bandwidth RAM to smoothly run multiple applications and browser tabs all at once. An embedded multimedia card provides reliable flash-based storage.
- Ports:2 x USB 3.0 Type-A,1 x USB 3.0 Type-C,1 x HDMI,1 x Headphone Jack
- Chrome OS: Chromebook is a computer for the way the modern world works, with thousands of apps. Enjoy the seamless simplicity that comes with Google Chrome and Android apps, all integrated into one laptop. It’s fast, simple, and secure.
Write the download test
it "downloads the PDF" do
driven_by(:selenium_chrome_pdf)
visit "/reports"
click_link "Download PDF"
expect do
expect(File).to exist(File.join(DOWNLOAD_DIR, "report.pdf"))
end.to eventually_have_something # Use your test stack's wait matcher
end
The final matcher is deliberately framework-specific: RSpec, Minitest, and custom helpers expose different polling APIs. The important rule is to poll for completion instead of asserting immediately after the click. A download can create a temporary .crdownload file before the final name appears.
Use Capybara’s synchronized waiting
Capybara synchronizes element lookups, but a raw Ruby filesystem call does not automatically wait. Wrap the filesystem check in an explicit polling helper whose timeout is tied to Capybara.default_max_wait_time (or your project’s equivalent). Poll until the expected file exists and, if you validate content, until its size stops changing.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Optional Capybara::HeadlessChrome helper
require "capybara/headless_chrome"
page.downloads.reset
visit "/reports"
click_link "Download Report"
file = page.downloads["report.pdf"]
expect(file).to be_a(File)
This optional driver documents page.downloads.filenames, lookup by filename, synchronized waiting up to Capybara.default_max_wait_time, and page.downloads.reset. Reset downloads at the start of each example so a previous test cannot satisfy the lookup.
Verify more than filename existence
A successful browser save does not prove that the endpoint returned the intended document. Add the checks that match your contract:
- Filename: confirm the expected final name, including any user- or report-specific suffix.
- Completion: ensure the temporary download is gone and the file can be opened.
- Type: inspect the file header for the PDF signature (
%PDF-) or use a PDF parser available in your test stack. - Content: extract text or inspect page count when the report itself is part of the contract.
- Authorization: run the test as the same role that should be allowed to download, and verify an unauthorized user does not receive a PDF.
If the endpoint’s HTTP headers are the behavior under test, test those at the request level as well. A browser test confirms the user-visible save operation; it is not a substitute for every response-level assertion.
Why a PDF opens in Chrome instead of downloading
Set preferences before creating the session
Chrome may display an inline PDF viewer when the response is handled as inline content. Set download.default_directory and download.prompt_for_download before launching Chrome. The directory must be absolute and writable.
Rank #3
- Stunning 15.6" FHD IPS Display: Experience crisp 1920x1080 resolution on this 15.6 inch laptop with an IPS panel that delivers wide viewing angles and vivid colors. The narrow-bezel design maximizes screen real estate for comfortable viewing on this Win 11 laptop, whether you're studying or working.
- Celeron J4105 Processor & 256GB SSD: Powered by a reliable Celeron J4105 processor paired with 12GB DDR4 memory and a fast 256GB M.2 SSD. This laptop computer supports SSD expansion up to 2TB and TF card expansion up to 1TB, so your storage grows with your needs. Delivers smooth multitasking for daily productivity.
- AI-Powered Win 11 Laptop: Built-in AI features enhance your productivity with smart assistance for writing, summarizing, and task management. Pre-installed with Win 11 and includes Office 365 subscription. This student laptop is backed by 1-year warranty and 24/7 customer support.
- All-Day 7000mAh Battery & 180° Hinge: The high-capacity 7000mAh battery keeps this laptop powered through long classes or meetings. The 180-degree lay-flat hinge lets you share your screen effortlessly during presentations. This durable laptop computer adapts to your dynamic workflow.
- Versatile Connectivity Hub: Equipped with USB 3.2, Type-C, Mini HDMI, and 3.5mm audio jack to connect all your peripherals. Stay online anywhere with high-speed 5G WiFi and Bluetooth 4.2. This college laptop keeps you connected at home, in the library, or on the go.
Return an attachment when download behavior is required
Your server should send a download-oriented response, normally with a PDF content type and an attachment disposition containing the intended filename. If the product requirement is to preview the PDF in the browser, opening the viewer is correct; change the test to assert the preview behavior rather than forcing a file download.
Check the actual click target
A link may open a new tab, invoke JavaScript, or call an API that later creates the file. Confirm that the element you click is the same control a user sees and that the test account can reach every request it triggers.
Wait reliably in CI
- Create a unique temporary directory and verify its permissions.
- Launch Chrome with the download preferences already installed.
- Visit the page and trigger the download.
- Poll for the expected final filename until the configured timeout.
- Reject a still-present temporary file, zero-byte file, or invalid PDF.
- Include the directory listing and browser/driver versions in failure diagnostics.
- Remove the directory after the example or suite completes.
Do not use a fixed sleep as the primary synchronization mechanism. A sleep is either unnecessarily slow or too short for a busy CI worker. A bounded polling loop gives fast success and a useful timeout on failure.
Print the current page to PDF instead
When the requirement is page rendering rather than an HTTP download, invoke headless Chrome directly:
chrome --headless --print-to-pdf --no-pdf-header-footer --timeout=5000 https://example.test/report
--print-to-pdf writes output.pdf in the current working directory. --no-pdf-header-footer removes print headers and footers. --timeout=5000 bounds the wait for pages that need additional loading time. Older Chrome versions may use the historical --print-to-pdf-no-header spelling, so use the flag supported by the installed binary.
This command does not test your “Download PDF” button, attachment headers, or application download directory. It tests what Chrome can render from the supplied URL.
Rank #4
- Efficient Performance for Everyday Computing: Powered by Intel N150 processor with up to 3.6 GHz Intel Turbo Boost Technology, 6 MB L3 cache, 4 cores, and 4 threads, this HP laptop delivers responsive performance for web browsing, streaming, document editing, and multitasking. Paired with 4GB LPDDR5 RAM and 128GB UFS storage, it handles daily tasks smoothly. Includes 1-year Microsoft 365 Personal subscription for Word, Excel, PowerPoint, and cloud storage to maximize your productivity.
- 14-Inch HD Micro-Edge Display:Enjoy clear visuals on the 14-inch HD (1366 x 768) anti-glare screen with 250-nit brightness and 62.5% sRGB coverage. The micro-edge bezel delivers a 79% screen-to-body ratio in a compact design. An HP True Vision 720p HD camera with noise reduction and dual-array microphones supports clear video calls, remote work, and online learning.
- Modern Connectivity and Wireless Technology: Stay connected with Wi-Fi 6 (2x2) for faster wireless speeds and Bluetooth 5.4 for seamless pairing with accessories. Versatile port selection includes 1 USB Type-C 10Gbps with DisplayPort 1.2 for external displays, 2 USB Type-A 5Gbps ports for peripherals, 1 HDMI 1.4b port, 1 headphone/microphone combo jack, and 1 multi-format SD media card reader. Connect monitors, transfer files quickly, and expand your workspace with ease.
- All-Day Battery Life and Portable Design: Enjoy up to 11 hours of video playback, 7.5 hours of mixed usage, or 7.5 hours of wireless streaming on a single charge, perfect for students and professionals on the go. Weighing just 3.24 lb and measuring 12.76" x 8.86" x 0.71", this lightweight laptop fits easily in backpacks and bags. The stylish willow green top cover with matte finish and natural silver keyboard deck with vertical brushing pattern offer a modern, professional look.
- AI-Enhanced Productivity: Access Microsoft Copilot instantly with the dedicated Copilot key for faster assistance. AI Noise Reduction filters background sounds and improves voice clarity during calls. Dual speakers provide clear audio, while the full-size natural silver keyboard and HP Imagepad support comfortable typing and navigation.
Common failures and precise fixes
“The link does nothing” under rack_test
Cause: the control depends on JavaScript or a remote request. Fix: switch the example to Selenium Chrome (or another JavaScript-capable driver), and ensure the browser can reach the target host.
Chrome cannot start in CI
Cause: missing browser/driver binaries, incompatible versions, unsupported flags, or insufficient container permissions. Fix: print the installed Chrome and driver versions, verify both binaries are present, and use only options supported by that image.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsThe assertion races the download
Cause: the click returns before Chrome finishes writing the file. Fix: use page.downloads[...] or an explicit filesystem polling helper; do not assert immediately.
The expected filename never appears
Cause: the server supplied a different filename, the response was inline, authentication failed, or the request returned an HTML error page. Fix: list the download directory on failure, inspect the response contract, and validate the PDF signature.
The PDF is blank or incomplete
Cause: the page was printed before its data or fonts loaded. Fix: wait for a meaningful selector in the application test, or increase the print command’s timeout. For a download endpoint, investigate server-side PDF generation separately from browser timing.
Metadata appears on printed pages
Cause: Chrome’s print header/footer feature. Fix: add --no-pdf-header-footer, or the older supported spelling for an older Chrome binary.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Best Value
- 【Expansive Display】The 14 Non-touch display offers clear, and anti-glare coating, perfect for both work and entertainment.
Or skip the browser setup
If your goal is simply to obtain a clean PDF or screenshot from a URL, ScreenshotNeo provides a website capture API and MCP server. It can capture PDFs with paper size, margins, landscape mode, and page ranges without you maintaining Selenium, Chrome binaries, or CI download directories.
One request is enough:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for PDF parameters and the other 63 capture options. Before capture, it accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf.
The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account.
Practical decision guide
| Requirement | Best approach | Primary assertion |
|---|---|---|
| Verify a user downloads an attachment | Selenium Chrome with download preferences | Expected file appears and is a valid PDF |
| Exercise a JavaScript download link | Selenium Chrome, not rack_test | Click completes and download helper returns the file |
| Render a URL as a PDF | Chrome --print-to-pdf or ScreenshotNeo |
Output exists and rendering meets your content rules |
| Run reliably in CI | Writable isolated directory, pinned browser image, bounded polling | No prompt, race, stale file, or permission failure |
Frequently Asked Questions
Should I use Selenium for every PDF test?
No. Use request-level tests for headers and authorization, Selenium for browser download behavior, and Chrome printing or ScreenshotNeo when the requirement is page rendering.
Where should downloaded files go in CI?
Use an absolute, writable temporary directory unique to the test process or example, then clean it up after the test.
What does a .crdownload file mean?
Chrome is still writing the download. Wait for the final filename and validate that the temporary file has disappeared before asserting completion.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

