Validating generated PDFs in automated end-to-end tests can be tricky. Here is a comprehensive guide on how to handle PDF downloading, parsing, and structured data assertion in a Web UI automation framework using Playwright, Cucumber (BDD), pdf-parse, and ajv schema validation.
Overview & Workflow
The automated end-to-end PDF validation flow follows these steps:
Navigate through the UI to trigger a PDF download.
Capture the download event using Playwright and store the PDF locally in reports/downloads/pdf/.
Extract and parse text from the downloaded file.
Perform assertions using static text matches, dynamic JSON data paths, or Regex extractions verified against JSON Schemas.
1. Prerequisites & Dependencies
Ensure your project has pdf-parse and ajv installed:
{
"dependencies": {
"pdf-parse": "^1.1.1",
"ajv": "^8.17.1"
}
}
Enable download handling in your Playwright configuration (setup/hooks.js):
// Browser context setup
acceptDownloads: true
2. Core Utility Helper
Create a helper module (utils/PdfHelper.js) to handle file downloads, text normalization, and schema validation:
// Core functions implemented in PdfHelper.js
- downloadPdfFromSelector(page, selector, options) // Captures Playwright download event & saves file
- parsePdf(filePath) / parsePdfBuffer(buffer) // Normalizes raw text output
- assertTextContains(text, expectedValues, options) // Handles case-insensitive and whitespace-normalized checks
- extractBySchema(text, extractionRules) // Extracts fields using JS Regex
- validateWithSchema(fieldData, schemaPath) // Validates structure with AJV
3. BDD Step Definitions
Wire your Cucumber steps (step-definitions/ui/pdfValidationSteps.js) to interact with the helper and scenario context:
When the user downloads a PDF from selector "<selector>"
When the user parses the downloaded PDF
Then the downloaded PDF should contain text "<text>"
Then the downloaded PDF should contain values from json "<jsonPath>" at path "<dataPath>"
When the user extracts PDF fields using rules from "<rulesPath>"
Then the extracted PDF fields should match schema "<schemaPath>"
Then the downloaded PDF page count should be at least <n>
4. Extraction Rules & Schema Validation Example
For complex documents, define regex patterns to extract fields and validate them against a schema.
Regex Rules (test-data/json/pdfExtractionRules.sample.json):
{
"rules": [
{
"key": "bondNumber",
"pattern": "Bond\\s*Number\\s*:\\s*([A-Z0-9-]+)",
"flags": "i",
"group": 1
}
]
}
Feature File Integration:
And the user downloads a PDF from selector "<stable-selector>"
And the user parses the downloaded PDF
Then the downloaded PDF should contain values from json "test-data/json/BondTestData.json" at path "accountName"
And the downloaded PDF page count should be at least 1
5. Running Tests & Best Practices
Add test scripts to your package.json:
{
"scripts": {
"test:ui:pdf:dry": "npx cucumber-js features/ui/pdfValidation.feature --import setup/hooks.js --import setup/assertions.js --import step-definitions/ui --dry-run",
"test:ui:pdf:run": "npx cucumber-js features/ui/pdfValidation.feature --import setup/hooks.js --import setup/assertions.js --import step-definitions/ui -f progress -f json:reports/cucumber_report.json --parallel 1"
}
}
Key Recommendations:
Selectors: Prefer stable data-testid attributes over text-only selectors.
Environment Safety: Store expected test data in JSON files rather than hardcoding values.
Security & Cleanup: Do not keep sensitive PDF payloads longer than necessary, and clean up downloads in post-test runs.
Top comments (0)