diff --git a/.skills/maestro-visual-testing.md b/.skills/maestro-visual-testing.md new file mode 100644 index 0000000..f7be976 --- /dev/null +++ b/.skills/maestro-visual-testing.md @@ -0,0 +1,433 @@ +# Maestro Visual Testing for CoolPDF Scenarios + +This skill documents the process for creating Maestro visual regression tests that compare CoolPDF implementation against react-native-pdf implementation for each scenario. + +## Overview + +The testing strategy uses: +- **Maestro** for UI automation and screenshot capture +- **Deep linking** for direct navigation to scenario screens +- **ImageMagick** for pixel-by-pixel visual comparison +- **HTML reports** for reviewing differences + +## Test Architecture + +### Directory Structure +``` +example/ +├── .maestro/ +│ ├── flows/ +│ │ ├── basic/ +│ │ │ ├── basic-no-cache.yaml +│ │ │ ├── basic-with-cache.yaml +│ │ │ └── basic-cache-filename.yaml +│ │ ├── navigation/ +│ │ ├── zoom/ +│ │ └── events/ +│ ├── utils/ +│ └── run-all-tests.yaml +├── scripts/ +│ └── compare-screenshots.js +└── visual-diff-results/ + └── visual-comparison-report.html +``` + +### Screenshot Storage +- Screenshots saved to: `/tmp/maestro-screenshots/` +- Naming pattern: `{scenario-name}-coolpdf.png` and `{scenario-name}-rnpdf.png` + +## Prerequisites + +### 1. Deep Link Configuration + +**App Config** (`app.config.js`): +```javascript +scheme: 'coolpdf' +``` + +**Navigation Linking** (`App.tsx`): +```typescript +const linking = { + prefixes: ['coolpdf://', 'expo.modules.coolpdf.example://'], + config: { + screens: { + ScenarioList: 'scenarios', + BasicNoCacheCoolPdf: 'basic-no-cache-cool', + BasicNoCacheReactNativePdf: 'basic-no-cache-rnpdf', + // Add route for each scenario screen pair + }, + }, +}; +``` + +**Route Naming Convention:** +- CoolPDF: `{CategoryName}{ScenarioName}CoolPdf: '{category}-{scenario}-cool'` +- RN-PDF: `{CategoryName}{ScenarioName}ReactNativePdf: '{category}-{scenario}-rnpdf'` + +### 2. Component Test IDs + +**Event Log Toggle** (`ScenarioEventLog.tsx`): +```typescript + setIsExpanded(!isExpanded)} +> +``` + +**Event Data** (for behavioral assertions): +```typescript + + {JSON.stringify(event.data, null, 2)} + +``` + +### 3. UI Consistency + +To minimize visual noise in comparisons: + +**Collapsible Headers** - Default collapsed to hide implementation-specific text +**Collapsible Event Logs** - Default collapsed to hide event data +**Unified Colors** - All scenarios use `#6b7280` (neutral gray) for headers and accents + +This reduces visual diff from ~12% to <1%. + +## Creating a New Test + +### Step 1: Add Deep Link Routes + +Edit `App.tsx` linking configuration: + +```typescript +screens: { + // ... existing routes ... + YourScenarioCoolPdf: 'category-scenario-cool', + YourScenarioReactNativePdf: 'category-scenario-rnpdf', +} +``` + +### Step 2: Create Maestro Test File + +**Template for Visual-Only Tests:** + +```yaml +appId: expo.modules.coolpdf.example +--- +# Test: Your Scenario Name +# Category: Loading|Navigation|Zoom|Events|Style|Password +# Description: Brief description of what this tests + +# Test CoolPDF implementation +- openLink: coolpdf://category-scenario-cool +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/scenario-name-coolpdf + +# Test react-native-pdf implementation +- openLink: coolpdf://category-scenario-rnpdf +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/scenario-name-rnpdf +``` + +**Template for Tests with Event Assertions:** + +```yaml +appId: expo.modules.coolpdf.example +--- +# Test: Your Scenario Name +# Category: Loading|Navigation|Zoom|Events|Style|Password +# Description: Brief description including event assertions + +# Test CoolPDF implementation +- openLink: coolpdf://category-scenario-cool +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Scroll down to see the event log +- scroll + +# Expand event log to check event data +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd + +# Scroll to see the event data if needed +- scroll + +# Assert on expected event data (use text matching within JSON) +- assertVisible: + text: "expected-value-in-event" + +# Collapse event log before screenshot +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd + +# Capture screenshot (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/scenario-name-coolpdf + +# Repeat for react-native-pdf implementation +- openLink: coolpdf://category-scenario-rnpdf +# ... same steps as above ... +``` + +### Step 3: Add to Master Test Suite + +Edit `.maestro/run-all-tests.yaml`: + +```yaml +# Category tests +- runFlow: flows/category/scenario-name.yaml +``` + +### Step 4: Run and Validate + +```bash +# Run single test +maestro test .maestro/flows/category/scenario-name.yaml + +# Generate visual comparison report +npm run test:visual:report + +# Run all tests with visual comparison +npm run test:visual +``` + +## Common Patterns + +### Navigation Tests + +For page navigation scenarios, add interaction before screenshot: + +```yaml +# Navigate to page 5 +- tapOn: + text: "5" +- waitForAnimationToEnd + +# Capture screenshot of page 5 +- takeScreenshot: /tmp/maestro-screenshots/scenario-name-coolpdf +``` + +### Zoom Tests + +For zoom scenarios, use pinch gestures: + +```yaml +# Pinch to zoom +- pinchToZoom: + scale: 2.0 + +# Wait for zoom animation +- waitForAnimationToEnd + +# Capture screenshot of zoomed view +- takeScreenshot: /tmp/maestro-screenshots/scenario-name-coolpdf +``` + +### Event Assertion Tips + +**Problem:** Maestro can't read text inside JSON.stringify output +**Solution:** Assert on substrings that appear in the JSON + +Example - checking cache path: +```yaml +# The full path is: /data/user/0/expo.modules.coolpdf.example/cache/my-file.pdf +# Assert on the unique part: +- assertVisible: + text: "cache/my-file.pdf" +``` + +**Problem:** Event log is off-screen +**Solution:** Scroll before tapping toggle +```yaml +- scroll +- tapOn: + id: "event-log-toggle" +``` + +**Problem:** Event data is below the fold inside event log +**Solution:** Scroll again after expanding +```yaml +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd +- scroll +- assertVisible: + text: "expected-value" +``` + +## Troubleshooting + +### "launchApp" conflicts with "openLink" +**Error:** Deep links don't work when `launchApp` is present +**Fix:** Remove `launchApp` - `openLink` launches the app automatically + +### Text not found in UI +**Error:** `Element not found: Text matching regex: X` +**Solutions:** +1. Check exact text including parentheses: `"Event Log (1)"` not `"Event Log"` +2. Add scroll command before assertion +3. Use testID instead: `tapOn: { id: "element-id" }` +4. Verify text is actually visible in debug screenshots at `~/.maestro/tests/*/screenshot-*.png` + +### Screenshot has wrong extension +**Error:** Screenshots saved as `file.png.png` +**Fix:** Don't include `.png` in `takeScreenshot` path - Maestro adds it automatically + +### Visual diff too high +**Solutions:** +1. Ensure headers are collapsed (default state) +2. Ensure event logs are collapsed (default state) +3. Verify all scenario screens use unified color `#6b7280` +4. Check that no dynamic timestamps or implementation names appear in UI + +### ImageMagick crashes on differences +**Error:** `compare` command exits with code 1 +**Fix:** Already handled in `compare-screenshots.js` - it catches the error and extracts diff count from stdout/stderr + +## Package Scripts + +```json +{ + "test:maestro": "maestro test .maestro/", + "test:maestro:basic": "maestro test .maestro/flows/basic/", + "test:visual": "maestro test .maestro/ && node scripts/compare-screenshots.js", + "test:visual:report": "node scripts/compare-screenshots.js" +} +``` + +## Visual Comparison Report + +The `compare-screenshots.js` script: +1. Finds all screenshot pairs in `/tmp/maestro-screenshots/` +2. Uses ImageMagick `compare -metric AE` to count different pixels +3. Calculates percentage difference +4. Categorizes as: Identical (0%), Minor (<5%), Significant (≥5%) +5. Generates HTML report with side-by-side comparisons +6. Opens report in browser + +**Report Location:** `example/visual-diff-results/visual-comparison-report.html` + +## Expected Results + +**Good Tests:** +- Visual diff: 0-1% (minor differences due to anti-aliasing, rendering variations) +- Status: "Identical" or "Minor differences" +- All assertions pass +- Screenshots captured at same PDF page/state + +**Bad Tests:** +- Visual diff: >5% (significant differences) +- Failed assertions +- Screenshots at different pages +- Headers/logs expanded in one screenshot but not the other + +## Complete Example: Basic Cache Filename + +**Routes in App.tsx:** +```typescript +BasicCacheFileNameCoolPdf: 'basic-cache-filename-cool', +BasicCacheFileNameReactNativePdf: 'basic-cache-filename-rnpdf', +``` + +**Test File:** `.maestro/flows/basic/basic-cache-filename.yaml` +```yaml +appId: expo.modules.coolpdf.example +--- +# Test: Basic Cache Filename +# Category: Loading +# Description: Tests loading a PDF from a URL with a custom cache filename + +# Test CoolPDF implementation +- openLink: coolpdf://basic-cache-filename-cool +- waitForAnimationToEnd +- waitForAnimationToEnd: + timeout: 10000 + +# Check cached path in event log +- scroll +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd +- scroll +- assertVisible: + text: "cache/my-custom-cached-file.pdf" +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd + +- takeScreenshot: /tmp/maestro-screenshots/basic-cache-filename-coolpdf + +# Test react-native-pdf implementation +- openLink: coolpdf://basic-cache-filename-rnpdf +- waitForAnimationToEnd +- waitForAnimationToEnd: + timeout: 10000 + +# Check cached path in event log +- scroll +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd +- scroll +- assertVisible: + text: "cache/my-custom-cached-file.pdf" +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd + +- takeScreenshot: /tmp/maestro-screenshots/basic-cache-filename-rnpdf +``` + +**Run Test:** +```bash +maestro test .maestro/flows/basic/basic-cache-filename.yaml +npm run test:visual:report +``` + +**Expected Output:** +``` +✓ Found 3 screenshot pair(s) +Comparing: basic-cache-filename +... +📊 Comparison Summary: + Minor differences: 3 + Significant differences: 0 +``` + +## Tips for Success + +1. **Always run `npx expo prebuild --clean`** after changing `app.config.js` +2. **Use testIDs** for reliable element selection over text matching +3. **Keep UI consistent** - collapsible components, unified colors +4. **Test incrementally** - run single test first, then add to suite +5. **Check debug screenshots** in `~/.maestro/tests/*/` when assertions fail +6. **Use scroll liberally** - better to scroll twice than miss an element +7. **Wait for animations** - add `waitForAnimationToEnd` after navigation and interactions +8. **Collapse UI before screenshots** - ensures visual consistency + +## Next Steps + +With this pattern established for 3 basic loading tests, replicate for: +- 4 more loading tests (7 total) +- 6 event tests +- 9 navigation tests +- 7 zoom tests +- 4 style tests +- 3 password tests + +**Total:** ~40 scenario comparisons with visual regression testing diff --git a/example/.maestro/README.md b/example/.maestro/README.md new file mode 100644 index 0000000..7c9f4eb --- /dev/null +++ b/example/.maestro/README.md @@ -0,0 +1,108 @@ +# Maestro Tests for cool-pdf + +This directory contains Maestro UI tests for the cool-pdf example app. The tests compare the CoolPDF implementation against react-native-pdf across various scenarios. + +## Prerequisites + +1. Install Maestro: https://maestro.mobile.dev/getting-started/installing-maestro +2. Have the example app built and ready to run on a simulator/emulator + +## Running Tests + +### Run a single test +```bash +# From the example/ directory +maestro test .maestro/flows/basic/basic-no-cache.yaml +``` + +### Run all tests in a category +```bash +maestro test .maestro/flows/basic/ +``` + +### Run all tests +```bash +maestro test .maestro/ +``` + +## Test Organization + +``` +.maestro/ +├── flows/ +│ ├── basic/ # Loading, caching, file sources +│ ├── navigation/ # Page navigation, scrolling, RTL +│ ├── zoom/ # Scale, zoom gestures +│ ├── events/ # Event callbacks +│ ├── style/ # Visual styling, indicators +│ └── password/ # Password-protected PDFs +└── utils/ # Shared helper flows +``` + +## Test Types + +### Behavioral Tests +Most tests are behavioral - they verify that: +- PDFs load without errors +- Events fire with correct data +- User interactions work as expected +- Navigation and scrolling behave correctly + +These tests use assertions to verify text appears in event logs and check for absence of error messages. + +### Visual Tests +Some tests (in `style/`) capture screenshots for visual comparison: +- Style prop rendering +- Activity indicators +- Annotations +- Border radius and styling + +## Writing New Tests + +1. Create a new YAML file in the appropriate category folder +2. Use the app structure: + - `launchApp` to start + - Navigate to category (e.g., "Loading", "Events", "Zoom & Scale") + - Tap on scenario name + - Test both implementations +3. Use helper flows from `utils/` for common patterns + +### Example Test Structure +```yaml +appId: expo.modules.coolpdf.example +--- +- launchApp +- tapOn: "CategoryName" +- waitForAnimationToEnd +- tapOn: "Scenario Name" +- waitForAnimationToEnd + +# Test CoolPDF +- tapOn: "View in CoolPDF" +- assertVisible: "CoolPDF Implementation" +# ... test actions ... +- tapOn: + label: "Go back" + +# Test react-native-pdf +- tapOn: "View in react-native-pdf" +- assertVisible: "react-native-pdf Implementation" +# ... test actions ... +- tapOn: + label: "Go back" +``` + +## Troubleshooting + +### App not found +Make sure the app is installed on your simulator/emulator with the correct bundle ID: `expo.modules.coolpdf.example` + +### Test timeout +PDFs may take time to load. Increase timeout values if needed: +```yaml +- waitForAnimationToEnd: + timeout: 10000 # 10 seconds +``` + +### Element not found +Check the exact text/label in the app. Maestro is case-sensitive. \ No newline at end of file diff --git a/example/.maestro/TESTING_STRATEGY.md b/example/.maestro/TESTING_STRATEGY.md new file mode 100644 index 0000000..326f8d3 --- /dev/null +++ b/example/.maestro/TESTING_STRATEGY.md @@ -0,0 +1,323 @@ +# Maestro Testing Strategy for cool-pdf + +## Overview + +This document outlines the comprehensive testing strategy for the cool-pdf Expo module using Maestro UI tests. The tests compare CoolPDF implementation against react-native-pdf across ~40 scenarios. + +## Current Implementation Status + +### ✅ Completed +- Directory structure created (`.maestro/flows/` organized by category) +- Shared helper flows for common actions +- Example test implemented: `basic-no-cache.yaml` +- Documentation and README + +### 🚧 To Be Implemented +- Remaining ~39 test scenarios across all categories +- Visual regression testing workflow +- CI/CD integration + +## Test Categories & Approaches + +### 1. **Loading Tests** (Basic Category - ~10 scenarios) +**Approach:** Behavioral assertions + +**Scenarios:** +- Basic No Cache ✅ (implemented) +- Basic With Cache +- Basic Cache File Name +- Basic Cache Expiration +- Custom HTTP Method +- Custom Headers +- Base64 PDF Rendering +- Require Local PDF +- Bundle Assets PDF +- File URI Local PDF + +**Testing Pattern:** +```yaml +- launchApp +- Navigate to scenario +- Test CoolPDF: Assert no error, verify PDF loads +- Test react-native-pdf: Assert no error, verify PDF loads +``` + +**Key Assertions:** +- Wait for load completion (timeout: 10s) +- Verify implementation header visible + +--- + +### 2. **Event Tests** (Events Category - 6 scenarios) +**Approach:** Behavioral - verify event log displays correct data + +**Scenarios:** +- OnLoadComplete +- OnLoadProgress +- OnPageChanged +- OnError +- OnPageSingleTap +- OnScaleChanged +- OnPressLink + +**Testing Pattern:** +```yaml +- Navigate to event scenario +- Trigger event (e.g., tap PDF, swipe page, pinch zoom) +- Assert event log shows expected data +- Example: assertVisible: "loadComplete" +- Example: assertVisible: "numberOfPages" +``` + +**Key Assertions:** +- Verify event type appears in log +- Check event data format/values +- Use regex patterns for flexible matching + +--- + +### 3. **Navigation Tests** (Navigation Category - 9 scenarios) +**Approach:** Behavioral - gestures + assertions + +**Scenarios:** +- Horizontal Scrolling +- Page Snapping +- Horizontal With Paging +- Custom Spacing +- Page Prop +- Spacing Prop +- Enable Paging Prop +- Horizontal Prop +- Enable RTL Prop +- Single Page + +**Testing Pattern:** +```yaml +- Navigate to scenario +- Perform swipe gestures +- Assert page number changes in event log +- Verify scrolling behavior matches expected +``` + +**Key Actions:** +- `swipe` for page navigation +- `scroll` for testing scroll behavior +- Check `onPageChanged` event data + +--- + +### 4. **Zoom Tests** (Zoom Category - 7 scenarios) +**Approach:** Behavioral - gestures + event verification + +**Scenarios:** +- Initial Zoom +- Custom Zoom Range +- Restricted Zoom +- Scale Prop +- Min Scale Prop +- Max Scale Prop +- Fit Policy Prop +- Enable Double Tap Zoom Prop + +**Testing Pattern:** +```yaml +- Navigate to scenario +- Perform pinch/double-tap gestures +- Verify onScaleChanged events +- Check scale values in event log +``` + +**Key Actions:** +- Double-tap for zoom testing +- Pinch gestures +- Verify scale values match expectations + +--- + +### 5. **Style/Visual Tests** (Style Category - 4 scenarios) +**Approach:** Visual regression - screenshots + comparison + +**Scenarios:** +- Style Prop (borders, dimensions) +- Render Activity Indicator +- Progress Container Style +- Enable Annotations +- Disable Annotations + +**Testing Pattern:** +```yaml +- Navigate to scenario +- Wait for render +- takeScreenshot: "coolpdf-{scenario}" +- Navigate to react-native-pdf +- takeScreenshot: "rnpdf-{scenario}" +- (External comparison with image diff tools) +``` + +**Visual Comparison Tools:** +- Maestro Cloud (built-in visual testing) +- External: Pixelmatch, Percy, Applitools +- Manual review during development + +--- + +### 6. **Password Tests** (Password Category - 3 scenarios) + +**Scenarios:** +- Password Prop +- Password Correct +- Password Incorrect + +**Testing Pattern:** +```yaml +- Navigate to scenario +- For incorrect: assertVisible: "Error" or password error message +- For correct: assertVisible: PDF content, no error +``` + +--- + +## Test File Naming Convention + +``` +.maestro/flows/{category}/{scenario-name-kebab-case}.yaml +``` + +Examples: +- `basic/basic-no-cache.yaml` +- `events/on-load-complete.yaml` +- `navigation/horizontal-scrolling.yaml` +- `zoom/enable-double-tap-zoom.yaml` +- `style/style-prop.yaml` + +--- + +## Shared Helper Flows + +### 1. `utils/navigate-to-scenario.yaml` +Reusable flow to navigate from home to any scenario. + +**Usage:** +```yaml +- runFlow: + file: utils/navigate-to-scenario.yaml + env: + CATEGORY: "Loading" + SCENARIO_NAME: "Basic No Cache" +``` + +### 2. `utils/test-both-implementations.yaml` +Tests both CoolPDF and react-native-pdf with the same test flow. + +**Usage:** +```yaml +- runFlow: + file: utils/test-both-implementations.yaml + env: + SCENARIO_NAME: "Basic No Cache" + TEST_FLOW: "flows/basic/basic-no-cache-actions.yaml" +``` + +--- + +## Implementation Roadmap + +### Phase 1: Core Behavioral Tests +1. Complete all loading tests (basic category) +2. Implement event tests with event log assertions +3. Add navigation tests with gestures + +**Estimated: 25 tests** + +### Phase 2: Advanced Interaction Tests +1. Implement zoom/scale tests +2. Add password tests +3. Test scroll indicators and interaction props + +**Estimated: 10 tests** + +### Phase 3: Visual Regression +1. Implement style/visual tests with screenshots +2. Set up visual comparison workflow +3. Create baseline images + +**Estimated: 5 tests** + +### Phase 4: CI/CD Integration +1. Add GitHub Actions workflow +2. Configure Maestro Cloud +3. Automate test runs on PR + +--- + +## Running Tests + +### Single Test +```bash +cd example +maestro test .maestro/flows/basic/basic-no-cache.yaml +``` + +### Category +```bash +maestro test .maestro/flows/basic/ +``` + +### All Tests +```bash +maestro test .maestro/ +``` + +### With Specific Device +```bash +maestro test --device "iPhone 15 Pro" .maestro/flows/basic/basic-no-cache.yaml +``` + +--- + +## Test Quality Guidelines + +1. **Wait Appropriately**: PDFs take time to load, use 10s timeout +2. **Clear Assertions**: Check for specific text, not just "visible" +3. **Clean Navigation**: Always navigate back properly between tests +4. **Descriptive Comments**: Explain what each test section does +5. **Handle Edge Cases**: Test both success and failure scenarios + +--- + +## CI/CD Integration (Future) + +### GitHub Actions Workflow +```yaml +name: Maestro Tests +on: [pull_request] +jobs: + test: + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + - uses: mobile-dev-inc/action-maestro-cloud@v1 + with: + api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }} + app-file: example/ios/build/CoolPdfExample.app + workspace: .maestro +``` + +--- + +## Next Steps + +1. **Implement remaining tests** following the patterns in `basic-no-cache.yaml` +2. **Test on both platforms** (iOS and Android) to ensure compatibility +3. **Create master flow files** that run all tests in each category +4. **Document edge cases** and platform-specific behaviors +5. **Set up visual regression** workflow for style tests + +--- + +## Additional Resources + +- [Maestro Documentation](https://maestro.mobile.dev) +- [Maestro Cloud](https://cloud.mobile.dev) +- [Example App Scenarios](../screens/scenarios/) +- [CoolPDF README](../../README.md) \ No newline at end of file diff --git a/example/.maestro/VISUAL_TESTING_GUIDE.md b/example/.maestro/VISUAL_TESTING_GUIDE.md new file mode 100644 index 0000000..a53c75c --- /dev/null +++ b/example/.maestro/VISUAL_TESTING_GUIDE.md @@ -0,0 +1,270 @@ +# Visual Testing Guide for cool-pdf + +This guide explains how to run automated visual comparison tests between CoolPDF and react-native-pdf implementations. + +## Overview + +The visual testing system: +1. Runs all Maestro tests +2. Captures screenshots of both CoolPDF and react-native-pdf for each scenario +3. Uses ImageMagick to generate visual diff images +4. Creates an HTML report showing side-by-side comparisons with metrics + +## Prerequisites + +1. **Maestro** - Mobile UI testing framework + ```bash + curl -Ls "https://get.maestro.mobile.dev" | bash + ``` + +2. **ImageMagick** - Image comparison tool + ```bash + brew install imagemagick + ``` + +3. **Running App** - Have the example app running on a simulator/emulator + ```bash + cd example + npx expo run:android # or run:ios + ``` + +## Running Visual Tests + +### Option 1: Run Tests + Generate Report (Recommended) +```bash +cd example +npm run test:visual +``` + +This will: +- Run all Maestro tests +- Capture screenshots automatically +- Generate visual diff images +- Create an HTML report +- Open the report in your browser + +### Option 2: Run Tests Only +```bash +npm run test:maestro +``` + +### Option 3: Generate Report from Existing Screenshots +```bash +npm run test:visual:report +``` + +## Test Organization + +``` +.maestro/ +├── flows/ +│ ├── basic/ # Loading tests (basic-no-cache.yaml, etc.) +│ ├── events/ # Event tests (on-load-complete.yaml, etc.) +│ ├── navigation/ # Navigation tests (page-prop.yaml, etc.) +│ ├── style/ # Visual/style tests (style-prop.yaml, etc.) +│ └── zoom/ # Zoom tests +├── utils/ # Shared helper flows +├── config.yaml # Global configuration +└── run-all-tests.yaml # Master test suite +``` + +## Screenshot Naming Convention + +For visual comparison to work, screenshots must follow this naming pattern: + +- **CoolPDF screenshot**: `{scenario-name}-coolpdf.png` +- **react-native-pdf screenshot**: `{scenario-name}-rnpdf.png` + +Example: +```yaml +# In a Maestro test +- takeScreenshot: basic-no-cache-coolpdf +# ...later in the same test +- takeScreenshot: basic-no-cache-rnpdf +``` + +## Understanding the Report + +The HTML report shows: + +### Summary Section +- Total number of tests +- Tests with identical results +- Tests with minor differences (< 1% difference) +- Tests with significant differences (≥ 1% difference) + +### Per-Test Comparison +Each test shows: +1. **CoolPDF screenshot** - Your implementation +2. **react-native-pdf screenshot** - Reference implementation +3. **Diff image** - Highlights differences in red +4. **Metrics**: + - Different Pixels: Count of pixels that don't match + - Difference %: Percentage of total pixels that differ + - Status: identical | minor-diff | significant-diff + +## Writing New Visual Tests + +### 1. Create the Test Flow + +```yaml +# .maestro/flows/basic/my-new-test.yaml +appId: expo.modules.coolpdf.example +--- +# Test CoolPDF implementation +- openLink: coolpdf://my-new-test-cool +- waitForAnimationToEnd +- assertVisible: "CoolPDF Implementation" +- waitForAnimationToEnd: + timeout: 10000 +- takeScreenshot: my-new-test-coolpdf + +# Test react-native-pdf implementation +- openLink: coolpdf://my-new-test-rnpdf +- waitForAnimationToEnd +- assertVisible: "react-native-pdf Implementation" +- waitForAnimationToEnd: + timeout: 10000 +- takeScreenshot: my-new-test-rnpdf +``` + +### 2. Add Deep Link Routes + +In `App.tsx`, add your screen routes to the linking config: + +```typescript +const linking = { + prefixes: ['coolpdf://', 'expo.modules.coolpdf.example://'], + config: { + screens: { + // ... existing routes + MyNewTestCoolPdf: 'my-new-test-cool', + MyNewTestReactNativePdf: 'my-new-test-rnpdf', + }, + }, +}; +``` + +### 3. Add to Master Test Suite + +In `.maestro/run-all-tests.yaml`: + +```yaml +- runFlow: flows/basic/my-new-test.yaml +``` + +## Tips for Better Visual Tests + +### 1. Wait for Content to Load +```yaml +# Always wait for PDFs to fully load +- waitForAnimationToEnd: + timeout: 10000 +``` + +### 2. Consistent Timing +Use the same wait times for both implementations to ensure fair comparison. + +### 3. Hide Dynamic Content +If your screens show timestamps or other dynamic data, consider hiding them for visual tests: + +### 4. Test Specific Features +Focus each test on a single feature (e.g., caching, page navigation, zoom) for easier debugging. + +## Troubleshooting + +### No Screenshots Found +- **Cause**: Tests didn't capture screenshots +- **Solution**: Check that your test uses `takeScreenshot` with correct naming (-coolpdf and -rnpdf suffixes) + +### ImageMagick Not Found +- **Cause**: ImageMagick not installed +- **Solution**: Run `brew install imagemagick` + +### Different Pixel Counts Very High +- **Cause**: Implementations render differently +- **Solution**: This is expected! Review the diff image to see what's different. Some differences are acceptable (e.g., slightly different antialiasing), others may indicate bugs. + +### Test Timeout +- **Cause**: PDF taking too long to load +- **Solution**: Increase timeout in test: + ```yaml + - waitForAnimationToEnd: + timeout: 15000 # 15 seconds + ``` + +### Deep Link Not Working +- **Cause**: Screen route not configured +- **Solution**: + 1. Check `app.config.js` has `scheme: 'coolpdf'` + 2. Add route to linking config in `App.tsx` + 3. Rebuild the app with `npx expo run:android` or `npx expo run:ios` + +## Output Locations + +- **Maestro test results**: `~/.maestro/tests/{timestamp}/` +- **Screenshots**: Captured in test results directory +- **Visual diff report**: `example/visual-diff-results/visual-comparison-report.html` +- **Diff images**: `example/visual-diff-results/{scenario-name}-diff.png` + +## CI/CD Integration + +To run tests in CI: + +```yaml +# .github/workflows/visual-tests.yml +name: Visual Tests +on: [pull_request] +jobs: + test: + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + - name: Install dependencies + run: brew install imagemagick + - name: Install Maestro + run: curl -Ls "https://get.maestro.mobile.dev" | bash + - name: Build app + run: cd example && npx expo run:ios --no-install + - name: Run visual tests + run: cd example && npm run test:visual + - name: Upload report + uses: actions/upload-artifact@v3 + with: + name: visual-test-report + path: example/visual-diff-results/ +``` + +## Best Practices + +1. **Run tests on same device/emulator** for consistent results +2. **Review diff images manually** - automated metrics don't catch everything +3. **Update baselines** when making intentional visual changes +4. **Test on both iOS and Android** - implementations may differ per platform +5. **Keep tests focused** - one scenario per test file +6. **Document expected differences** - some variations are acceptable + +## Example Workflow + +```bash +# 1. Make changes to CoolPDF implementation +vim ios/CoolPdfView.swift + +# 2. Rebuild the app +cd example +npx expo run:ios + +# 3. Run visual tests +npm run test:visual + +# 4. Review the HTML report that opens automatically + +# 5. If differences are expected, document them +# If differences are bugs, fix and retest +``` + +## Getting Help + +- Maestro Docs: https://maestro.mobile.dev +- ImageMagick Docs: https://imagemagick.org +- Project Issues: https://github.com/your-repo/issues \ No newline at end of file diff --git a/example/.maestro/config.yaml b/example/.maestro/config.yaml new file mode 100644 index 0000000..6d8f062 --- /dev/null +++ b/example/.maestro/config.yaml @@ -0,0 +1,8 @@ +appId: expo.modules.coolpdf.example +--- +# Maestro Configuration +# This file sets up environment variables for all tests + +env: + SCREENSHOTS_DIR: "/tmp/maestro-screenshots" + APP_ID: "expo.modules.coolpdf.example" \ No newline at end of file diff --git a/example/.maestro/flows/basic/basic-base64.yaml b/example/.maestro/flows/basic/basic-base64.yaml new file mode 100644 index 0000000..862ce66 --- /dev/null +++ b/example/.maestro/flows/basic/basic-base64.yaml @@ -0,0 +1,27 @@ +appId: expo.modules.coolpdf.example +--- +# Test: Base64 PDF Rendering +# Category: Loading +# Description: Visual regression test for rendering PDF from base64 string + +# Test CoolPDF implementation +- openLink: coolpdf://basic-base64-cool +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/basic-base64-coolpdf + +# Test react-native-pdf implementation +- openLink: coolpdf://basic-base64-rnpdf +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/basic-base64-rnpdf diff --git a/example/.maestro/flows/basic/basic-cache-expiration.yaml b/example/.maestro/flows/basic/basic-cache-expiration.yaml new file mode 100644 index 0000000..708f494 --- /dev/null +++ b/example/.maestro/flows/basic/basic-cache-expiration.yaml @@ -0,0 +1,77 @@ +appId: expo.modules.coolpdf.example +--- +# Test: Cache Expiration +# Category: Loading +# Verifies cache expires after 10s and triggers re-download (via loadProgress events) + +# === CoolPDF Implementation === + +# First load (establish cache) +- openLink: coolpdf://basic-cache-expiration-cool +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Navigate back to scenario list +- openLink: coolpdf://scenarios +- waitForAnimationToEnd + +# Wait for cache to expire (10s expiration + 2s buffer) +- runScript: + file: ../../utils/sleep.js + env: + sleepMs: 12000 + +# Second load - cache expired, should trigger re-download with progress events +- openLink: coolpdf://basic-cache-expiration-cool +- waitForAnimationToEnd + +# Wait for load to complete +- waitForAnimationToEnd: + timeout: 10000 + +# Expand event log +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd + +# Assert loadProgress event exists (indicates download happened) +- assertVisible: + text: "loadProgress" + +# === React-Native-PDF Implementation === + +# Navigate back to scenario list +- openLink: coolpdf://scenarios +- waitForAnimationToEnd + +# First load +- openLink: coolpdf://basic-cache-expiration-rnpdf +- waitForAnimationToEnd +- waitForAnimationToEnd: + timeout: 10000 + +# Navigate back +- openLink: coolpdf://scenarios +- waitForAnimationToEnd + +# Wait for cache to expire +- runScript: + file: ../../utils/sleep.js + env: + sleepMs: 12000 + +# Second load - re-download +- openLink: coolpdf://basic-cache-expiration-rnpdf +- waitForAnimationToEnd +- waitForAnimationToEnd: + timeout: 10000 + +# Check for loadProgress events +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd +- assertVisible: + text: "loadProgress" diff --git a/example/.maestro/flows/basic/basic-cache-filename.yaml b/example/.maestro/flows/basic/basic-cache-filename.yaml new file mode 100644 index 0000000..5c11eb3 --- /dev/null +++ b/example/.maestro/flows/basic/basic-cache-filename.yaml @@ -0,0 +1,54 @@ +appId: expo.modules.coolpdf.example +--- +# Test: Basic Cache Filename +# Category: Loading +# Description: Tests loading a PDF from a URL with a custom cache filename + +# Test CoolPDF implementation using deep link +- openLink: coolpdf://basic-cache-filename-cool +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Expand event log to check the cached path +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd + +# Assert that the path contains the custom cache filename with full path +- assertVisible: + text: ".*my-custom-cached-file.*" + +# Collapse event log before screenshot +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd + +# Capture screenshot of CoolPDF implementation (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/basic-cache-filename-coolpdf + +# Test react-native-pdf implementation +- openLink: coolpdf://basic-cache-filename-rnpdf +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Expand event log to check the cached path +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd +# Assert that the path contains the custom cache filename with full path +- assertVisible: + text: ".*my-custom-cached-file.*" + +# Collapse event log before screenshot +- tapOn: + id: "event-log-toggle" +- waitForAnimationToEnd + +# Capture screenshot of react-native-pdf implementation (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/basic-cache-filename-rnpdf diff --git a/example/.maestro/flows/basic/basic-no-cache.yaml b/example/.maestro/flows/basic/basic-no-cache.yaml new file mode 100644 index 0000000..6daccec --- /dev/null +++ b/example/.maestro/flows/basic/basic-no-cache.yaml @@ -0,0 +1,27 @@ +appId: expo.modules.coolpdf.example +--- +# Test: Basic No Cache +# Category: Loading +# Description: Tests loading a PDF from a URL without caching + +# Test CoolPDF implementation using deep link +- openLink: coolpdf://basic-no-cache-cool +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot of CoolPDF implementation (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/basic-no-cache-coolpdf + +# Test react-native-pdf implementation +- openLink: coolpdf://basic-no-cache-rnpdf +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot of react-native-pdf implementation (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/basic-no-cache-rnpdf \ No newline at end of file diff --git a/example/.maestro/flows/basic/basic-require-local.yaml b/example/.maestro/flows/basic/basic-require-local.yaml new file mode 100644 index 0000000..7ff96dd --- /dev/null +++ b/example/.maestro/flows/basic/basic-require-local.yaml @@ -0,0 +1,27 @@ +appId: expo.modules.coolpdf.example +--- +# Test: Require Local PDF +# Category: Loading +# Description: Visual regression test for loading local PDF using require() + +# Test CoolPDF implementation +- openLink: coolpdf://basic-require-local-cool +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/basic-require-local-coolpdf + +# Test react-native-pdf implementation +- openLink: coolpdf://basic-require-local-rnpdf +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/basic-require-local-rnpdf diff --git a/example/.maestro/flows/basic/basic-with-cache.yaml b/example/.maestro/flows/basic/basic-with-cache.yaml new file mode 100644 index 0000000..bde363b --- /dev/null +++ b/example/.maestro/flows/basic/basic-with-cache.yaml @@ -0,0 +1,27 @@ +appId: expo.modules.coolpdf.example +--- +# Test: Basic With Cache +# Category: Loading +# Description: Tests loading a PDF from a URL with caching enabled + +# Test CoolPDF implementation using deep link +- openLink: coolpdf://basic-with-cache-cool +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot of CoolPDF implementation (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/basic-with-cache-coolpdf + +# Test react-native-pdf implementation +- openLink: coolpdf://basic-with-cache-rnpdf +- waitForAnimationToEnd + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot of react-native-pdf implementation (with headers collapsed) +- takeScreenshot: /tmp/maestro-screenshots/basic-with-cache-rnpdf diff --git a/example/.maestro/flows/events/on-load-complete.yaml b/example/.maestro/flows/events/on-load-complete.yaml new file mode 100644 index 0000000..3f9d3f7 --- /dev/null +++ b/example/.maestro/flows/events/on-load-complete.yaml @@ -0,0 +1,57 @@ +appId: expo.modules.coolpdf.example +--- +# Test: On Load Complete +# Category: Events +# Description: Verifies the onLoadComplete event fires with correct parameters + +- launchApp +- tapOn: "Events" +- waitForAnimationToEnd +- tapOn: "On Load Complete" +- waitForAnimationToEnd + +# Test CoolPDF implementation +- tapOn: "View in CoolPDF" +- waitForAnimationToEnd +- assertVisible: "CoolPDF Implementation" +- assertVisible: "On Load Complete" + +# Wait for PDF to load and event to fire +- waitForAnimationToEnd: + timeout: 10000 + +# Assert the event log shows loadComplete event +- assertVisible: "loadComplete" + +# Assert event contains expected data fields +- assertVisible: "numberOfPages" +- assertVisible: "path" +- assertVisible: "dimensions" + +# Navigate back +- tapOn: + label: "Go back" +- waitForAnimationToEnd + +# Test react-native-pdf implementation +- tapOn: "View in react-native-pdf" +- waitForAnimationToEnd +- assertVisible: "react-native-pdf Implementation" +- assertVisible: "On Load Complete" + +# Wait for PDF to load and event to fire +- waitForAnimationToEnd: + timeout: 10000 + +# Assert the event log shows loadComplete event +- assertVisible: "loadComplete" + +# Assert event contains expected data fields +- assertVisible: "numberOfPages" +- assertVisible: "path" +- assertVisible: "dimensions" + +# Navigate back to home +- tapOn: + label: "Go back" +- waitForAnimationToEnd \ No newline at end of file diff --git a/example/.maestro/flows/navigation/page-prop.yaml b/example/.maestro/flows/navigation/page-prop.yaml new file mode 100644 index 0000000..d003271 --- /dev/null +++ b/example/.maestro/flows/navigation/page-prop.yaml @@ -0,0 +1,72 @@ +appId: expo.modules.coolpdf.example +--- +# Test: Page Prop +# Category: Navigation +# Description: Tests the page prop to verify PDF opens on the specified page + +- launchApp +- tapOn: "Navigation" +- waitForAnimationToEnd +- tapOn: "Page Prop" +- waitForAnimationToEnd + +# Test CoolPDF implementation +- tapOn: "View in CoolPDF" +- waitForAnimationToEnd +- assertVisible: "CoolPDF Implementation" +- assertVisible: "Page Prop" + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# The scenario should open on a specific page (not page 1) +# Check event log for pageChanged or loadComplete showing correct page +- assertVisible: "page" + +# Swipe to navigate between pages +- swipe: + direction: UP + duration: 500 + +# Wait for page change +- waitForAnimationToEnd: + timeout: 2000 + +# Verify page changed event fired +- assertVisible: "pageChanged" + +# Navigate back +- tapOn: + label: "Go back" +- waitForAnimationToEnd + +# Test react-native-pdf implementation +- tapOn: "View in react-native-pdf" +- waitForAnimationToEnd +- assertVisible: "react-native-pdf Implementation" +- assertVisible: "Page Prop" + +# Wait for PDF to load +- waitForAnimationToEnd: + timeout: 10000 + +# Check event log for correct initial page +- assertVisible: "page" + +# Swipe to navigate between pages +- swipe: + direction: UP + duration: 500 + +# Wait for page change +- waitForAnimationToEnd: + timeout: 2000 + +# Verify page changed event fired +- assertVisible: "pageChanged" + +# Navigate back to home +- tapOn: + label: "Go back" +- waitForAnimationToEnd \ No newline at end of file diff --git a/example/.maestro/flows/style/style-prop.yaml b/example/.maestro/flows/style/style-prop.yaml new file mode 100644 index 0000000..ca53209 --- /dev/null +++ b/example/.maestro/flows/style/style-prop.yaml @@ -0,0 +1,53 @@ +appId: expo.modules.coolpdf.example +--- +# Test: Style Prop +# Category: Style (Visual Regression) +# Description: Tests visual rendering of style props (border, dimensions) +# This test captures screenshots for visual comparison + +- launchApp +- tapOn: "Style" +- waitForAnimationToEnd +- tapOn: "Style Prop" +- waitForAnimationToEnd + +# Test CoolPDF implementation +- tapOn: "View in CoolPDF" +- waitForAnimationToEnd +- assertVisible: "CoolPDF Implementation" +- assertVisible: "Style Prop" + +# Wait for PDF to render fully +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot for visual comparison +- takeScreenshot: coolpdf-style-prop + +# Navigate back +- tapOn: + label: "Go back" +- waitForAnimationToEnd + +# Test react-native-pdf implementation +- tapOn: "View in react-native-pdf" +- waitForAnimationToEnd +- assertVisible: "react-native-pdf Implementation" +- assertVisible: "Style Prop" + +# Wait for PDF to render fully +- waitForAnimationToEnd: + timeout: 10000 + +# Capture screenshot for visual comparison +- takeScreenshot: rnpdf-style-prop + +# Navigate back to home +- tapOn: + label: "Go back" +- waitForAnimationToEnd + +# Note: Screenshots are saved to ~/.maestro/tests/{test-run-id}/ +# Compare the two screenshots manually or with image diff tools: +# - Maestro Cloud provides automatic visual regression +# - Locally: use tools like Pixelmatch or ImageMagick's compare \ No newline at end of file diff --git a/example/.maestro/run-all-tests.yaml b/example/.maestro/run-all-tests.yaml new file mode 100644 index 0000000..63cfb2d --- /dev/null +++ b/example/.maestro/run-all-tests.yaml @@ -0,0 +1,17 @@ +appId: expo.modules.coolpdf.example +--- +# Master test suite - runs all visual comparison tests + +# Basic/Loading tests +- runFlow: flows/basic/basic-no-cache.yaml +- runFlow: flows/basic/basic-with-cache.yaml +- runFlow: flows/basic/basic-cache-filename.yaml +- runFlow: flows/basic/basic-cache-expiration.yaml +- runFlow: flows/basic/basic-base64.yaml +- runFlow: flows/basic/basic-require-local.yaml + +# Add more test flows here as they're created +# - runFlow: flows/basic/basic-with-cache.yaml +# - runFlow: flows/events/on-load-complete.yaml +# - runFlow: flows/navigation/page-prop.yaml +# - runFlow: flows/style/style-prop.yaml \ No newline at end of file diff --git a/example/.maestro/utils/navigate-to-scenario.yaml b/example/.maestro/utils/navigate-to-scenario.yaml new file mode 100644 index 0000000..9b33087 --- /dev/null +++ b/example/.maestro/utils/navigate-to-scenario.yaml @@ -0,0 +1,12 @@ +appId: ${APP_ID} +env: + CATEGORY: ${CATEGORY} + SCENARIO_NAME: ${SCENARIO_NAME} +--- +# Shared flow to navigate to a specific scenario from home screen +# Usage: runFlow with CATEGORY and SCENARIO_NAME env vars + +- tapOn: "${CATEGORY}" +- waitForAnimationToEnd +- tapOn: "${SCENARIO_NAME}" +- waitForAnimationToEnd \ No newline at end of file diff --git a/example/.maestro/utils/sleep.js b/example/.maestro/utils/sleep.js new file mode 100644 index 0000000..6251b62 --- /dev/null +++ b/example/.maestro/utils/sleep.js @@ -0,0 +1,12 @@ +// Helper script to sleep for a specified duration +// Using busy-wait loop since setTimeout is not available in Maestro JS environment +// Reference: https://github.com/mobile-dev-inc/Maestro/issues/1542#issuecomment-2153036301 + +var ms = parseInt(output.sleepMs || "12000"); +var start = Date.now(); + +while (Date.now() - start < ms) { + // Busy wait +} + +console.log("Slept for " + ms + "ms"); \ No newline at end of file diff --git a/example/.maestro/utils/test-both-implementations.yaml b/example/.maestro/utils/test-both-implementations.yaml new file mode 100644 index 0000000..be3b978 --- /dev/null +++ b/example/.maestro/utils/test-both-implementations.yaml @@ -0,0 +1,25 @@ +appId: ${APP_ID} +env: + SCENARIO_NAME: ${SCENARIO_NAME} + TEST_FLOW: ${TEST_FLOW} +--- +# Shared flow to test both CoolPDF and react-native-pdf implementations +# Runs the same test flow for both implementations + +# Test CoolPDF implementation +- tapOn: "View in CoolPDF" +- waitForAnimationToEnd +- assertVisible: "CoolPDF Implementation" +- runFlow: ${TEST_FLOW} +- tapOn: + label: "Go back" +- waitForAnimationToEnd + +# Test react-native-pdf implementation +- tapOn: "View in react-native-pdf" +- waitForAnimationToEnd +- assertVisible: "react-native-pdf Implementation" +- runFlow: ${TEST_FLOW} +- tapOn: + label: "Go back" +- waitForAnimationToEnd \ No newline at end of file diff --git a/example/App.tsx b/example/App.tsx index 2eea759..b588eb0 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -221,11 +221,33 @@ type RootStackParamList = { const Stack = createNativeStackNavigator(); +const linking = { + prefixes: ['coolpdf://', 'expo.modules.coolpdf.example://'], + config: { + screens: { + ScenarioList: 'scenarios', + BasicNoCacheCoolPdf: 'basic-no-cache-cool', + BasicNoCacheReactNativePdf: 'basic-no-cache-rnpdf', + BasicWithCacheCoolPdf: 'basic-with-cache-cool', + BasicWithCacheReactNativePdf: 'basic-with-cache-rnpdf', + BasicCacheFileNameCoolPdf: 'basic-cache-filename-cool', + BasicCacheFileNameReactNativePdf: 'basic-cache-filename-rnpdf', + BasicCacheExpirationCoolPdf: 'basic-cache-expiration-cool', + BasicCacheExpirationReactNativePdf: 'basic-cache-expiration-rnpdf', + Base64PdfRenderingCoolPdf: 'basic-base64-cool', + Base64PdfRenderingReactNativePdf: 'basic-base64-rnpdf', + RequireLocalPdfCoolPdf: 'basic-require-local-cool', + RequireLocalPdfReactNativePdf: 'basic-require-local-rnpdf', + // Add more as needed + }, + }, +}; + export default function App() { return ( - - + + {/* Navigation scenarios */} {/* Zoom scenarios */} diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index c7efd74..c71faf3 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -23,6 +23,12 @@ + + + + + + diff --git a/example/app.config.js b/example/app.config.js index 4a33e9a..8592d95 100644 --- a/example/app.config.js +++ b/example/app.config.js @@ -2,6 +2,7 @@ export default { expo: { name: 'cool-pdf-example', slug: 'cool-pdf-example', + scheme: 'coolpdf', version: '1.0.0', orientation: 'portrait', icon: './assets/icon.png', diff --git a/example/app.json b/example/app.json index 656d6ee..29512b4 100644 --- a/example/app.json +++ b/example/app.json @@ -7,6 +7,7 @@ "icon": "./assets/icon.png", "userInterfaceStyle": "light", "newArchEnabled": true, + "scheme": "coolpdf", "splash": { "image": "./assets/splash-icon.png", "resizeMode": "contain", diff --git a/example/basic-no-cache-coolpdf.png b/example/basic-no-cache-coolpdf.png new file mode 100644 index 0000000..e933a7b Binary files /dev/null and b/example/basic-no-cache-coolpdf.png differ diff --git a/example/basic-no-cache-rnpdf.png b/example/basic-no-cache-rnpdf.png new file mode 100644 index 0000000..15a6026 Binary files /dev/null and b/example/basic-no-cache-rnpdf.png differ diff --git a/example/components/ScenarioEventLog.tsx b/example/components/ScenarioEventLog.tsx index 9fbaf41..611e657 100644 --- a/example/components/ScenarioEventLog.tsx +++ b/example/components/ScenarioEventLog.tsx @@ -1,3 +1,4 @@ +import { useState } from 'react'; import { Text, View, StyleSheet, ScrollView, TouchableOpacity, Alert } from 'react-native'; import * as Clipboard from 'expo-clipboard'; @@ -13,6 +14,8 @@ type Props = { }; export function ScenarioEventLog({ events, accentColor = '#5856d6' }: Props) { + const [isExpanded, setIsExpanded] = useState(false); + const copyEventLog = async () => { const logText = JSON.stringify(events, null, 2); @@ -22,26 +25,49 @@ export function ScenarioEventLog({ events, accentColor = '#5856d6' }: Props) { return ( - - Event Log - - Copy - - - - {events.length === 0 ? ( - No events yet - ) : ( - events.map((event, index) => ( - - {event.type} - - {JSON.stringify(event.data, null, 2)} - - - )) + setIsExpanded(!isExpanded)} + activeOpacity={0.8} + > + + {isExpanded ? '▼' : '▶'} + + Event Log {events.length > 0 && `(${events.length})`} + + + {isExpanded && ( + { + e.stopPropagation(); + copyEventLog(); + }} + style={[styles.copyButton, { backgroundColor: accentColor }]} + > + Copy + )} - + + + {isExpanded && ( + + {events.length === 0 ? ( + No events yet + ) : ( + events.map((event, index) => ( + + {event.type} + + {JSON.stringify(event.data, null, 2)} + + + )) + )} + + )} ); } @@ -51,15 +77,23 @@ const styles = StyleSheet.create({ backgroundColor: '#fff', borderTopWidth: 1, borderTopColor: '#ddd', - maxHeight: 300, }, eventLogHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', backgroundColor: '#f0f0f0', - paddingHorizontal: 8, - paddingVertical: 8, + paddingHorizontal: 12, + paddingVertical: 12, + }, + headerLeft: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + }, + expandIcon: { + fontSize: 12, + color: '#666', }, eventLogTitle: { fontSize: 14, @@ -98,4 +132,4 @@ const styles = StyleSheet.create({ fontFamily: 'monospace', color: '#666', }, -}); +}); \ No newline at end of file diff --git a/example/components/ScenarioHeader.tsx b/example/components/ScenarioHeader.tsx index d03f8b2..eb3fb8e 100644 --- a/example/components/ScenarioHeader.tsx +++ b/example/components/ScenarioHeader.tsx @@ -1,4 +1,5 @@ -import { Text, View, StyleSheet } from 'react-native'; +import { useState } from 'react'; +import { Text, View, StyleSheet, TouchableOpacity } from 'react-native'; type Props = { implementation: string; @@ -8,12 +9,28 @@ type Props = { }; export function ScenarioHeader({ implementation, name, description, backgroundColor }: Props) { + const [isExpanded, setIsExpanded] = useState(false); + return ( - - {implementation} - {name} - {description} - + setIsExpanded(!isExpanded)} + activeOpacity={0.8} + > + + + {isExpanded ? '▼' : '▶'} Tap to {isExpanded ? 'collapse' : 'expand'} details + + + + {isExpanded && ( + + {implementation} + {name} + {description} + + )} + ); } @@ -21,6 +38,21 @@ const styles = StyleSheet.create({ header: { padding: 16, }, + collapsedContent: { + alignItems: 'center', + }, + tapHint: { + fontSize: 12, + color: '#fff', + opacity: 0.8, + fontWeight: '600', + }, + expandedContent: { + marginTop: 12, + paddingTop: 12, + borderTopWidth: 1, + borderTopColor: 'rgba(255, 255, 255, 0.3)', + }, implementation: { fontSize: 16, fontWeight: 'bold', @@ -38,4 +70,4 @@ const styles = StyleSheet.create({ color: '#fff', opacity: 0.9, }, -}); +}); \ No newline at end of file diff --git a/example/package.json b/example/package.json index e00916f..0c12640 100644 --- a/example/package.json +++ b/example/package.json @@ -8,7 +8,16 @@ "ios": "expo run:ios", "web": "expo start --web", "test-server": "node test-server/server.js", - "postinstall": "patch-package" + "postinstall": "patch-package", + "test:maestro": "maestro test .maestro/", + "test:maestro:basic": "maestro test .maestro/flows/basic/", + "test:maestro:events": "maestro test .maestro/flows/events/", + "test:maestro:navigation": "maestro test .maestro/flows/navigation/", + "test:maestro:zoom": "maestro test .maestro/flows/zoom/", + "test:maestro:style": "maestro test .maestro/flows/style/", + "test:maestro:ios": "maestro test --platform ios .maestro/", + "test:maestro:android": "maestro test --platform android .maestro/", + "test:visual": "maestro test .maestro/ && node scripts/compare-screenshots.js" }, "dependencies": { "@config-plugins/react-native-blob-util": "^12.0.0", diff --git a/example/screens/scenarios/basic/Base64PdfRenderingCoolPdfScreen.tsx b/example/screens/scenarios/basic/Base64PdfRenderingCoolPdfScreen.tsx index 5653e6f..3e5530c 100644 --- a/example/screens/scenarios/basic/Base64PdfRenderingCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/Base64PdfRenderingCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function Base64PdfRenderingCoolPdfScreen() { implementation="CoolPDF Implementation" name={Base64PdfRenderingScenario.name} description={Base64PdfRenderingScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/Base64PdfRenderingReactNativePdfScreen.tsx b/example/screens/scenarios/basic/Base64PdfRenderingReactNativePdfScreen.tsx index 754afa7..d7d2568 100644 --- a/example/screens/scenarios/basic/Base64PdfRenderingReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/Base64PdfRenderingReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function Base64PdfRenderingReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={Base64PdfRenderingScenario.name} description={Base64PdfRenderingScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/BasicCacheExpirationCoolPdfScreen.tsx b/example/screens/scenarios/basic/BasicCacheExpirationCoolPdfScreen.tsx index 55075c0..679f055 100644 --- a/example/screens/scenarios/basic/BasicCacheExpirationCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/BasicCacheExpirationCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function BasicCacheExpirationCoolPdfScreen() { implementation="CoolPDF Implementation" name={BasicCacheExpirationScenario.name} description={BasicCacheExpirationScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> { + const { percent } = event.nativeEvent; + addEvent("loadProgress", { percent }); + }} style={styles.pdf} /> - + ); } diff --git a/example/screens/scenarios/basic/BasicCacheExpirationReactNativePdfScreen.tsx b/example/screens/scenarios/basic/BasicCacheExpirationReactNativePdfScreen.tsx index f0c8936..636cd3d 100644 --- a/example/screens/scenarios/basic/BasicCacheExpirationReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/BasicCacheExpirationReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function BasicCacheExpirationReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={BasicCacheExpirationScenario.name} description={BasicCacheExpirationScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> { + addEvent("loadProgress", { percent }); + }} style={styles.pdf} trustAllCerts={false} /> - + ); } diff --git a/example/screens/scenarios/basic/BasicCacheFileNameCoolPdfScreen.tsx b/example/screens/scenarios/basic/BasicCacheFileNameCoolPdfScreen.tsx index e29cd02..ef9e0db 100644 --- a/example/screens/scenarios/basic/BasicCacheFileNameCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/BasicCacheFileNameCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function BasicCacheFileNameCoolPdfScreen() { implementation="CoolPDF Implementation" name={BasicCacheFileNameScenario.name} description={BasicCacheFileNameScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/BasicCacheFileNameReactNativePdfScreen.tsx b/example/screens/scenarios/basic/BasicCacheFileNameReactNativePdfScreen.tsx index 19cecf8..80bb7bf 100644 --- a/example/screens/scenarios/basic/BasicCacheFileNameReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/BasicCacheFileNameReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function BasicCacheFileNameReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={BasicCacheFileNameScenario.name} description={BasicCacheFileNameScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/BasicNoCacheCoolPdfScreen.tsx b/example/screens/scenarios/basic/BasicNoCacheCoolPdfScreen.tsx index a6ad728..9a59c58 100644 --- a/example/screens/scenarios/basic/BasicNoCacheCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/BasicNoCacheCoolPdfScreen.tsx @@ -20,7 +20,7 @@ export default function BasicNoCacheCoolPdfScreen() { implementation="CoolPDF Implementation" name={BasicNoCacheScenario.name} description={BasicNoCacheScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/BasicNoCacheReactNativePdfScreen.tsx b/example/screens/scenarios/basic/BasicNoCacheReactNativePdfScreen.tsx index 9980350..ebcf07d 100644 --- a/example/screens/scenarios/basic/BasicNoCacheReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/BasicNoCacheReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function BasicNoCacheReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={BasicNoCacheScenario.name} description={BasicNoCacheScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/BasicPasswordCoolPdfScreen.tsx b/example/screens/scenarios/basic/BasicPasswordCoolPdfScreen.tsx index 3ead602..fe8ccf8 100644 --- a/example/screens/scenarios/basic/BasicPasswordCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/BasicPasswordCoolPdfScreen.tsx @@ -29,7 +29,7 @@ export default function BasicPasswordCoolPdfScreen() { implementation="CoolPDF Implementation" name={BasicPasswordScenario.name} description={BasicPasswordScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/BasicPasswordReactNativePdfScreen.tsx b/example/screens/scenarios/basic/BasicPasswordReactNativePdfScreen.tsx index 73f7d50..ee48c2d 100644 --- a/example/screens/scenarios/basic/BasicPasswordReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/BasicPasswordReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function BasicPasswordReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={BasicPasswordScenario.name} description={BasicPasswordScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/BasicWithCacheCoolPdfScreen.tsx b/example/screens/scenarios/basic/BasicWithCacheCoolPdfScreen.tsx index a3d6f84..cc318a5 100644 --- a/example/screens/scenarios/basic/BasicWithCacheCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/BasicWithCacheCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function BasicWithCacheCoolPdfScreen() { implementation="CoolPDF Implementation" name={BasicWithCacheScenario.name} description={BasicWithCacheScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/BasicWithCacheReactNativePdfScreen.tsx b/example/screens/scenarios/basic/BasicWithCacheReactNativePdfScreen.tsx index bdb25eb..79844ae 100644 --- a/example/screens/scenarios/basic/BasicWithCacheReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/BasicWithCacheReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function BasicWithCacheReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={BasicWithCacheScenario.name} description={BasicWithCacheScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/BundleAssetsPdfCoolPdfScreen.tsx b/example/screens/scenarios/basic/BundleAssetsPdfCoolPdfScreen.tsx index d8bb179..5ba7449 100644 --- a/example/screens/scenarios/basic/BundleAssetsPdfCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/BundleAssetsPdfCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function BundleAssetsPdfCoolPdfScreen() { implementation="CoolPDF Implementation" name={BundleAssetsPdfScenario.name} description={BundleAssetsPdfScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/BundleAssetsPdfReactNativePdfScreen.tsx b/example/screens/scenarios/basic/BundleAssetsPdfReactNativePdfScreen.tsx index c8cd873..b4a3b0c 100644 --- a/example/screens/scenarios/basic/BundleAssetsPdfReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/BundleAssetsPdfReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function BundleAssetsPdfReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={BundleAssetsPdfScenario.name} description={BundleAssetsPdfScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/CustomHeadersCoolPdfScreen.tsx b/example/screens/scenarios/basic/CustomHeadersCoolPdfScreen.tsx index f0c9249..bc0d47f 100644 --- a/example/screens/scenarios/basic/CustomHeadersCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/CustomHeadersCoolPdfScreen.tsx @@ -22,7 +22,7 @@ export default function CustomHeadersCoolPdfScreen() { implementation="CoolPDF Implementation" name={CustomHeadersScenario.name} description={CustomHeadersScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/CustomHeadersReactNativePdfScreen.tsx b/example/screens/scenarios/basic/CustomHeadersReactNativePdfScreen.tsx index c90862b..0a04fc5 100644 --- a/example/screens/scenarios/basic/CustomHeadersReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/CustomHeadersReactNativePdfScreen.tsx @@ -22,7 +22,7 @@ export default function CustomHeadersReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={CustomHeadersScenario.name} description={CustomHeadersScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/CustomHttpMethodCoolPdfScreen.tsx b/example/screens/scenarios/basic/CustomHttpMethodCoolPdfScreen.tsx index 2631e0a..5259fb3 100644 --- a/example/screens/scenarios/basic/CustomHttpMethodCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/CustomHttpMethodCoolPdfScreen.tsx @@ -22,7 +22,7 @@ export default function CustomHttpMethodCoolPdfScreen() { implementation="CoolPDF Implementation" name={CustomHttpMethodScenario.name} description={CustomHttpMethodScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/CustomHttpMethodReactNativePdfScreen.tsx b/example/screens/scenarios/basic/CustomHttpMethodReactNativePdfScreen.tsx index 936ec11..132467a 100644 --- a/example/screens/scenarios/basic/CustomHttpMethodReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/CustomHttpMethodReactNativePdfScreen.tsx @@ -22,7 +22,7 @@ export default function CustomHttpMethodReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={CustomHttpMethodScenario.name} description={CustomHttpMethodScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/FileUriLocalPdfCoolPdfScreen.tsx b/example/screens/scenarios/basic/FileUriLocalPdfCoolPdfScreen.tsx index 0ee8673..16aaf23 100644 --- a/example/screens/scenarios/basic/FileUriLocalPdfCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/FileUriLocalPdfCoolPdfScreen.tsx @@ -64,7 +64,7 @@ export default function FileUriLocalPdfCoolPdfScreen() { implementation="CoolPDF Implementation" name={FileUriLocalPdfScenario.name} description={FileUriLocalPdfScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> {loading ? ( @@ -93,7 +93,7 @@ export default function FileUriLocalPdfCoolPdfScreen() { /> ) : null} - + ); } diff --git a/example/screens/scenarios/basic/FileUriLocalPdfReactNativePdfScreen.tsx b/example/screens/scenarios/basic/FileUriLocalPdfReactNativePdfScreen.tsx index a4c1731..06ce7bb 100644 --- a/example/screens/scenarios/basic/FileUriLocalPdfReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/FileUriLocalPdfReactNativePdfScreen.tsx @@ -64,7 +64,7 @@ export default function FileUriLocalPdfReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={FileUriLocalPdfScenario.name} description={FileUriLocalPdfScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> {loading ? ( @@ -92,7 +92,7 @@ export default function FileUriLocalPdfReactNativePdfScreen() { /> ) : null} - + ); } diff --git a/example/screens/scenarios/basic/OnLoadCompleteCoolPdfScreen.tsx b/example/screens/scenarios/basic/OnLoadCompleteCoolPdfScreen.tsx index 38d0891..2c2fd92 100644 --- a/example/screens/scenarios/basic/OnLoadCompleteCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/OnLoadCompleteCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnLoadCompleteCoolPdfScreen() { implementation="CoolPDF Implementation" name={OnLoadCompleteScenario.name} description={OnLoadCompleteScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/OnLoadCompleteReactNativePdfScreen.tsx b/example/screens/scenarios/basic/OnLoadCompleteReactNativePdfScreen.tsx index b7c96f8..a58eb93 100644 --- a/example/screens/scenarios/basic/OnLoadCompleteReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/OnLoadCompleteReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnLoadCompleteReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={OnLoadCompleteScenario.name} description={OnLoadCompleteScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/PasswordCorrectCoolPdfScreen.tsx b/example/screens/scenarios/basic/PasswordCorrectCoolPdfScreen.tsx index 3328fa6..e2dca22 100644 --- a/example/screens/scenarios/basic/PasswordCorrectCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/PasswordCorrectCoolPdfScreen.tsx @@ -27,7 +27,7 @@ export default function PasswordCorrectCoolPdfScreen() { implementation="CoolPDF Implementation" name={PasswordCorrectScenario.name} description={PasswordCorrectScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/PasswordCorrectReactNativePdfScreen.tsx b/example/screens/scenarios/basic/PasswordCorrectReactNativePdfScreen.tsx index 2c9c1c0..85ff5eb 100644 --- a/example/screens/scenarios/basic/PasswordCorrectReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/PasswordCorrectReactNativePdfScreen.tsx @@ -27,7 +27,7 @@ export default function PasswordCorrectReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={PasswordCorrectScenario.name} description={PasswordCorrectScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/PasswordIncorrectCoolPdfScreen.tsx b/example/screens/scenarios/basic/PasswordIncorrectCoolPdfScreen.tsx index 724b2ab..f29f258 100644 --- a/example/screens/scenarios/basic/PasswordIncorrectCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/PasswordIncorrectCoolPdfScreen.tsx @@ -27,7 +27,7 @@ export default function PasswordIncorrectCoolPdfScreen() { implementation="CoolPDF Implementation" name={PasswordIncorrectScenario.name} description={PasswordIncorrectScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/PasswordIncorrectReactNativePdfScreen.tsx b/example/screens/scenarios/basic/PasswordIncorrectReactNativePdfScreen.tsx index 977d89a..5090ae4 100644 --- a/example/screens/scenarios/basic/PasswordIncorrectReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/PasswordIncorrectReactNativePdfScreen.tsx @@ -27,7 +27,7 @@ export default function PasswordIncorrectReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={PasswordIncorrectScenario.name} description={PasswordIncorrectScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/PasswordPropCoolPdfScreen.tsx b/example/screens/scenarios/basic/PasswordPropCoolPdfScreen.tsx index 62ccdd0..9446089 100644 --- a/example/screens/scenarios/basic/PasswordPropCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/PasswordPropCoolPdfScreen.tsx @@ -33,7 +33,7 @@ export default function PasswordPropCoolPdfScreen() { implementation="CoolPDF Implementation" name={PasswordPropScenario.name} description={PasswordPropScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> @@ -76,7 +76,7 @@ export default function PasswordPropCoolPdfScreen() { style={styles.pdf} /> - + ); } diff --git a/example/screens/scenarios/basic/PasswordPropReactNativePdfScreen.tsx b/example/screens/scenarios/basic/PasswordPropReactNativePdfScreen.tsx index e0790ba..6b44b37 100644 --- a/example/screens/scenarios/basic/PasswordPropReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/PasswordPropReactNativePdfScreen.tsx @@ -33,7 +33,7 @@ export default function PasswordPropReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={PasswordPropScenario.name} description={PasswordPropScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> @@ -75,7 +75,7 @@ export default function PasswordPropReactNativePdfScreen() { trustAllCerts={false} /> - + ); } diff --git a/example/screens/scenarios/basic/RequireLocalPdfCoolPdfScreen.tsx b/example/screens/scenarios/basic/RequireLocalPdfCoolPdfScreen.tsx index 02a7695..1c79059 100644 --- a/example/screens/scenarios/basic/RequireLocalPdfCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/RequireLocalPdfCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function RequireLocalPdfCoolPdfScreen() { implementation="CoolPDF Implementation" name={RequireLocalPdfScenario.name} description={RequireLocalPdfScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/RequireLocalPdfReactNativePdfScreen.tsx b/example/screens/scenarios/basic/RequireLocalPdfReactNativePdfScreen.tsx index 7f0db4e..4dda1ef 100644 --- a/example/screens/scenarios/basic/RequireLocalPdfReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/RequireLocalPdfReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function RequireLocalPdfReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={RequireLocalPdfScenario.name} description={RequireLocalPdfScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/ScrollEnabledCoolPdfScreen.tsx b/example/screens/scenarios/basic/ScrollEnabledCoolPdfScreen.tsx index 155e5ad..ebe21e6 100644 --- a/example/screens/scenarios/basic/ScrollEnabledCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/ScrollEnabledCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function ScrollEnabledCoolPdfScreen() { implementation="CoolPDF Implementation" name={ScrollEnabledScenario.name} description={ScrollEnabledScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/ScrollEnabledReactNativePdfScreen.tsx b/example/screens/scenarios/basic/ScrollEnabledReactNativePdfScreen.tsx index f4dc42c..5542d5e 100644 --- a/example/screens/scenarios/basic/ScrollEnabledReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/ScrollEnabledReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function ScrollEnabledReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={ScrollEnabledScenario.name} description={ScrollEnabledScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/ShowsHorizontalScrollIndicatorCoolPdfScreen.tsx b/example/screens/scenarios/basic/ShowsHorizontalScrollIndicatorCoolPdfScreen.tsx index 07da7eb..4d37446 100644 --- a/example/screens/scenarios/basic/ShowsHorizontalScrollIndicatorCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/ShowsHorizontalScrollIndicatorCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function ShowsHorizontalScrollIndicatorCoolPdfScreen() { implementation="CoolPDF Implementation" name={ShowsHorizontalScrollIndicatorScenario.name} description={ShowsHorizontalScrollIndicatorScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/ShowsHorizontalScrollIndicatorReactNativePdfScreen.tsx b/example/screens/scenarios/basic/ShowsHorizontalScrollIndicatorReactNativePdfScreen.tsx index a0c8d58..e61940a 100644 --- a/example/screens/scenarios/basic/ShowsHorizontalScrollIndicatorReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/ShowsHorizontalScrollIndicatorReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function ShowsHorizontalScrollIndicatorReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={ShowsHorizontalScrollIndicatorScenario.name} description={ShowsHorizontalScrollIndicatorScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/ShowsVerticalScrollIndicatorCoolPdfScreen.tsx b/example/screens/scenarios/basic/ShowsVerticalScrollIndicatorCoolPdfScreen.tsx index 490a6de..aebd9e7 100644 --- a/example/screens/scenarios/basic/ShowsVerticalScrollIndicatorCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/ShowsVerticalScrollIndicatorCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function ShowsVerticalScrollIndicatorCoolPdfScreen() { implementation="CoolPDF Implementation" name={ShowsVerticalScrollIndicatorScenario.name} description={ShowsVerticalScrollIndicatorScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/ShowsVerticalScrollIndicatorReactNativePdfScreen.tsx b/example/screens/scenarios/basic/ShowsVerticalScrollIndicatorReactNativePdfScreen.tsx index 7dc61ed..821e8e9 100644 --- a/example/screens/scenarios/basic/ShowsVerticalScrollIndicatorReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/ShowsVerticalScrollIndicatorReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function ShowsVerticalScrollIndicatorReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={ShowsVerticalScrollIndicatorScenario.name} description={ShowsVerticalScrollIndicatorScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/StylePropCoolPdfScreen.tsx b/example/screens/scenarios/basic/StylePropCoolPdfScreen.tsx index 3e28933..baa527b 100644 --- a/example/screens/scenarios/basic/StylePropCoolPdfScreen.tsx +++ b/example/screens/scenarios/basic/StylePropCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function StylePropCoolPdfScreen() { implementation="CoolPDF Implementation" name={StylePropScenario.name} description={StylePropScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/basic/StylePropReactNativePdfScreen.tsx b/example/screens/scenarios/basic/StylePropReactNativePdfScreen.tsx index 58a66ff..7c51cf8 100644 --- a/example/screens/scenarios/basic/StylePropReactNativePdfScreen.tsx +++ b/example/screens/scenarios/basic/StylePropReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function StylePropReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={StylePropScenario.name} description={StylePropScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnErrorCoolPdfScreen.tsx b/example/screens/scenarios/events/OnErrorCoolPdfScreen.tsx index 80e3476..764e7ea 100644 --- a/example/screens/scenarios/events/OnErrorCoolPdfScreen.tsx +++ b/example/screens/scenarios/events/OnErrorCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnErrorCoolPdfScreen() { implementation="CoolPDF Implementation" name={OnErrorScenario.name} description={OnErrorScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnErrorReactNativePdfScreen.tsx b/example/screens/scenarios/events/OnErrorReactNativePdfScreen.tsx index acf094d..cd885fd 100644 --- a/example/screens/scenarios/events/OnErrorReactNativePdfScreen.tsx +++ b/example/screens/scenarios/events/OnErrorReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnErrorReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={OnErrorScenario.name} description={OnErrorScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnLoadProgressCoolPdfScreen.tsx b/example/screens/scenarios/events/OnLoadProgressCoolPdfScreen.tsx index b145ed8..ba8d433 100644 --- a/example/screens/scenarios/events/OnLoadProgressCoolPdfScreen.tsx +++ b/example/screens/scenarios/events/OnLoadProgressCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnLoadProgressCoolPdfScreen() { implementation="CoolPDF Implementation" name={OnLoadProgressScenario.name} description={OnLoadProgressScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnLoadProgressReactNativePdfScreen.tsx b/example/screens/scenarios/events/OnLoadProgressReactNativePdfScreen.tsx index bb515d0..4256e70 100644 --- a/example/screens/scenarios/events/OnLoadProgressReactNativePdfScreen.tsx +++ b/example/screens/scenarios/events/OnLoadProgressReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnLoadProgressReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={OnLoadProgressScenario.name} description={OnLoadProgressScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnPageChangedCoolPdfScreen.tsx b/example/screens/scenarios/events/OnPageChangedCoolPdfScreen.tsx index 3fd0e10..7289ed1 100644 --- a/example/screens/scenarios/events/OnPageChangedCoolPdfScreen.tsx +++ b/example/screens/scenarios/events/OnPageChangedCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnPageChangedCoolPdfScreen() { implementation="CoolPDF Implementation" name={OnPageChangedScenario.name} description={OnPageChangedScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnPageChangedReactNativePdfScreen.tsx b/example/screens/scenarios/events/OnPageChangedReactNativePdfScreen.tsx index 8a0499d..0b74d6a 100644 --- a/example/screens/scenarios/events/OnPageChangedReactNativePdfScreen.tsx +++ b/example/screens/scenarios/events/OnPageChangedReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnPageChangedReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={OnPageChangedScenario.name} description={OnPageChangedScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnPageSingleTapCoolPdfScreen.tsx b/example/screens/scenarios/events/OnPageSingleTapCoolPdfScreen.tsx index d8a9f9d..2ec8305 100644 --- a/example/screens/scenarios/events/OnPageSingleTapCoolPdfScreen.tsx +++ b/example/screens/scenarios/events/OnPageSingleTapCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnPageSingleTapCoolPdfScreen() { implementation="CoolPDF Implementation" name={OnPageSingleTapScenario.name} description={OnPageSingleTapScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnPageSingleTapReactNativePdfScreen.tsx b/example/screens/scenarios/events/OnPageSingleTapReactNativePdfScreen.tsx index 7ccfe86..a70698a 100644 --- a/example/screens/scenarios/events/OnPageSingleTapReactNativePdfScreen.tsx +++ b/example/screens/scenarios/events/OnPageSingleTapReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnPageSingleTapReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={OnPageSingleTapScenario.name} description={OnPageSingleTapScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnPressLinkCoolPdfScreen.tsx b/example/screens/scenarios/events/OnPressLinkCoolPdfScreen.tsx index 845ff78..215d61c 100644 --- a/example/screens/scenarios/events/OnPressLinkCoolPdfScreen.tsx +++ b/example/screens/scenarios/events/OnPressLinkCoolPdfScreen.tsx @@ -22,7 +22,7 @@ export default function OnPressLinkCoolPdfScreen() { implementation="CoolPDF Implementation" name={OnPressLinkScenario.name} description={OnPressLinkScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnPressLinkReactNativePdfScreen.tsx b/example/screens/scenarios/events/OnPressLinkReactNativePdfScreen.tsx index 5d7c9f1..5929313 100644 --- a/example/screens/scenarios/events/OnPressLinkReactNativePdfScreen.tsx +++ b/example/screens/scenarios/events/OnPressLinkReactNativePdfScreen.tsx @@ -22,7 +22,7 @@ export default function OnPressLinkReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={OnPressLinkScenario.name} description={OnPressLinkScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnScaleChangedCoolPdfScreen.tsx b/example/screens/scenarios/events/OnScaleChangedCoolPdfScreen.tsx index ffb8b09..fd8e14b 100644 --- a/example/screens/scenarios/events/OnScaleChangedCoolPdfScreen.tsx +++ b/example/screens/scenarios/events/OnScaleChangedCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnScaleChangedCoolPdfScreen() { implementation="CoolPDF Implementation" name={OnScaleChangedScenario.name} description={OnScaleChangedScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/events/OnScaleChangedReactNativePdfScreen.tsx b/example/screens/scenarios/events/OnScaleChangedReactNativePdfScreen.tsx index ae74808..db8a8bb 100644 --- a/example/screens/scenarios/events/OnScaleChangedReactNativePdfScreen.tsx +++ b/example/screens/scenarios/events/OnScaleChangedReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function OnScaleChangedReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={OnScaleChangedScenario.name} description={OnScaleChangedScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/CustomSpacingCoolPdfScreen.tsx b/example/screens/scenarios/navigation/CustomSpacingCoolPdfScreen.tsx index d31bfe3..9a16a6c 100644 --- a/example/screens/scenarios/navigation/CustomSpacingCoolPdfScreen.tsx +++ b/example/screens/scenarios/navigation/CustomSpacingCoolPdfScreen.tsx @@ -28,7 +28,7 @@ export default function CustomSpacingCoolPdfScreen() { implementation="CoolPDF Implementation" name={CustomSpacingScenario.name} description={CustomSpacingScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/CustomSpacingReactNativePdfScreen.tsx b/example/screens/scenarios/navigation/CustomSpacingReactNativePdfScreen.tsx index 94c6a5f..2c8c33c 100644 --- a/example/screens/scenarios/navigation/CustomSpacingReactNativePdfScreen.tsx +++ b/example/screens/scenarios/navigation/CustomSpacingReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function CustomSpacingReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={CustomSpacingScenario.name} description={CustomSpacingScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/EnablePagingPropCoolPdfScreen.tsx b/example/screens/scenarios/navigation/EnablePagingPropCoolPdfScreen.tsx index 80462ff..5df79ef 100644 --- a/example/screens/scenarios/navigation/EnablePagingPropCoolPdfScreen.tsx +++ b/example/screens/scenarios/navigation/EnablePagingPropCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function EnablePagingPropCoolPdfScreen() { implementation="CoolPDF Implementation" name={EnablePagingPropScenario.name} description={EnablePagingPropScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/EnablePagingPropReactNativePdfScreen.tsx b/example/screens/scenarios/navigation/EnablePagingPropReactNativePdfScreen.tsx index 0d0d9d9..f8a57e3 100644 --- a/example/screens/scenarios/navigation/EnablePagingPropReactNativePdfScreen.tsx +++ b/example/screens/scenarios/navigation/EnablePagingPropReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function EnablePagingPropReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={EnablePagingPropScenario.name} description={EnablePagingPropScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/EnableRtlPropCoolPdfScreen.tsx b/example/screens/scenarios/navigation/EnableRtlPropCoolPdfScreen.tsx index 07afa50..e79bab1 100644 --- a/example/screens/scenarios/navigation/EnableRtlPropCoolPdfScreen.tsx +++ b/example/screens/scenarios/navigation/EnableRtlPropCoolPdfScreen.tsx @@ -22,7 +22,7 @@ export default function EnableRtlPropCoolPdfScreen() { implementation="CoolPDF Implementation" name={EnableRtlPropScenario.name} description={EnableRtlPropScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> @@ -58,7 +58,7 @@ export default function EnableRtlPropCoolPdfScreen() { style={styles.pdf} /> - + ); } diff --git a/example/screens/scenarios/navigation/EnableRtlPropReactNativePdfScreen.tsx b/example/screens/scenarios/navigation/EnableRtlPropReactNativePdfScreen.tsx index fd07477..ea2ee98 100644 --- a/example/screens/scenarios/navigation/EnableRtlPropReactNativePdfScreen.tsx +++ b/example/screens/scenarios/navigation/EnableRtlPropReactNativePdfScreen.tsx @@ -22,7 +22,7 @@ export default function EnableRtlPropReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={EnableRtlPropScenario.name} description={EnableRtlPropScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> @@ -57,7 +57,7 @@ export default function EnableRtlPropReactNativePdfScreen() { trustAllCerts={false} /> - + ); } diff --git a/example/screens/scenarios/navigation/HorizontalPropCoolPdfScreen.tsx b/example/screens/scenarios/navigation/HorizontalPropCoolPdfScreen.tsx index 3de4087..c50dde8 100644 --- a/example/screens/scenarios/navigation/HorizontalPropCoolPdfScreen.tsx +++ b/example/screens/scenarios/navigation/HorizontalPropCoolPdfScreen.tsx @@ -22,7 +22,7 @@ export default function HorizontalPropCoolPdfScreen() { implementation="CoolPDF Implementation" name={HorizontalPropScenario.name} description={HorizontalPropScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> @@ -62,7 +62,7 @@ export default function HorizontalPropCoolPdfScreen() { style={styles.pdf} /> - + ); } diff --git a/example/screens/scenarios/navigation/HorizontalPropReactNativePdfScreen.tsx b/example/screens/scenarios/navigation/HorizontalPropReactNativePdfScreen.tsx index cb65fee..cf1cf19 100644 --- a/example/screens/scenarios/navigation/HorizontalPropReactNativePdfScreen.tsx +++ b/example/screens/scenarios/navigation/HorizontalPropReactNativePdfScreen.tsx @@ -22,7 +22,7 @@ export default function HorizontalPropReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={HorizontalPropScenario.name} description={HorizontalPropScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> @@ -61,7 +61,7 @@ export default function HorizontalPropReactNativePdfScreen() { trustAllCerts={false} /> - + ); } diff --git a/example/screens/scenarios/navigation/HorizontalScrollingCoolPdfScreen.tsx b/example/screens/scenarios/navigation/HorizontalScrollingCoolPdfScreen.tsx index b04a043..082ba1b 100644 --- a/example/screens/scenarios/navigation/HorizontalScrollingCoolPdfScreen.tsx +++ b/example/screens/scenarios/navigation/HorizontalScrollingCoolPdfScreen.tsx @@ -28,7 +28,7 @@ export default function HorizontalScrollingCoolPdfScreen() { implementation="CoolPDF Implementation" name={HorizontalScrollingScenario.name} description={HorizontalScrollingScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/HorizontalScrollingReactNativePdfScreen.tsx b/example/screens/scenarios/navigation/HorizontalScrollingReactNativePdfScreen.tsx index 08d76ee..b091755 100644 --- a/example/screens/scenarios/navigation/HorizontalScrollingReactNativePdfScreen.tsx +++ b/example/screens/scenarios/navigation/HorizontalScrollingReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function HorizontalScrollingReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={HorizontalScrollingScenario.name} description={HorizontalScrollingScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/HorizontalWithPagingCoolPdfScreen.tsx b/example/screens/scenarios/navigation/HorizontalWithPagingCoolPdfScreen.tsx index 78a3fdb..a3cfb41 100644 --- a/example/screens/scenarios/navigation/HorizontalWithPagingCoolPdfScreen.tsx +++ b/example/screens/scenarios/navigation/HorizontalWithPagingCoolPdfScreen.tsx @@ -28,7 +28,7 @@ export default function HorizontalWithPagingCoolPdfScreen() { implementation="CoolPDF Implementation" name={HorizontalWithPagingScenario.name} description={HorizontalWithPagingScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/HorizontalWithPagingReactNativePdfScreen.tsx b/example/screens/scenarios/navigation/HorizontalWithPagingReactNativePdfScreen.tsx index a9446bd..d60780f 100644 --- a/example/screens/scenarios/navigation/HorizontalWithPagingReactNativePdfScreen.tsx +++ b/example/screens/scenarios/navigation/HorizontalWithPagingReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function HorizontalWithPagingReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={HorizontalWithPagingScenario.name} description={HorizontalWithPagingScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/PagePropCoolPdfScreen.tsx b/example/screens/scenarios/navigation/PagePropCoolPdfScreen.tsx index fd6b8ba..53ba929 100644 --- a/example/screens/scenarios/navigation/PagePropCoolPdfScreen.tsx +++ b/example/screens/scenarios/navigation/PagePropCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function PagePropCoolPdfScreen() { implementation="CoolPDF Implementation" name={PagePropScenario.name} description={PagePropScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/PagePropReactNativePdfScreen.tsx b/example/screens/scenarios/navigation/PagePropReactNativePdfScreen.tsx index 1009020..b7eaa58 100644 --- a/example/screens/scenarios/navigation/PagePropReactNativePdfScreen.tsx +++ b/example/screens/scenarios/navigation/PagePropReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function PagePropReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={PagePropScenario.name} description={PagePropScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/PageSnappingCoolPdfScreen.tsx b/example/screens/scenarios/navigation/PageSnappingCoolPdfScreen.tsx index 2d0c1a0..3e65bec 100644 --- a/example/screens/scenarios/navigation/PageSnappingCoolPdfScreen.tsx +++ b/example/screens/scenarios/navigation/PageSnappingCoolPdfScreen.tsx @@ -28,7 +28,7 @@ export default function PageSnappingCoolPdfScreen() { implementation="CoolPDF Implementation" name={PageSnappingScenario.name} description={PageSnappingScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/PageSnappingReactNativePdfScreen.tsx b/example/screens/scenarios/navigation/PageSnappingReactNativePdfScreen.tsx index 6c8bca0..06c7e7d 100644 --- a/example/screens/scenarios/navigation/PageSnappingReactNativePdfScreen.tsx +++ b/example/screens/scenarios/navigation/PageSnappingReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function PageSnappingReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={PageSnappingScenario.name} description={PageSnappingScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/SinglePageCoolPdfScreen.tsx b/example/screens/scenarios/navigation/SinglePageCoolPdfScreen.tsx index 77634f0..715f9d9 100644 --- a/example/screens/scenarios/navigation/SinglePageCoolPdfScreen.tsx +++ b/example/screens/scenarios/navigation/SinglePageCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function SinglePageCoolPdfScreen() { implementation="CoolPDF Implementation" name={SinglePageScenario.name} description={SinglePageScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/navigation/SinglePageReactNativePdfScreen.tsx b/example/screens/scenarios/navigation/SinglePageReactNativePdfScreen.tsx index 2d990f5..453fed2 100644 --- a/example/screens/scenarios/navigation/SinglePageReactNativePdfScreen.tsx +++ b/example/screens/scenarios/navigation/SinglePageReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function SinglePageReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={SinglePageScenario.name} description={SinglePageScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/style/DisableAnnotationsCoolPdfScreen.tsx b/example/screens/scenarios/style/DisableAnnotationsCoolPdfScreen.tsx index 66bbc62..f665274 100644 --- a/example/screens/scenarios/style/DisableAnnotationsCoolPdfScreen.tsx +++ b/example/screens/scenarios/style/DisableAnnotationsCoolPdfScreen.tsx @@ -22,7 +22,7 @@ export default function DisableAnnotationsCoolPdfScreen() { implementation="CoolPDF Implementation" name={DisableAnnotationsScenario.name} description={DisableAnnotationsScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/style/DisableAnnotationsReactNativePdfScreen.tsx b/example/screens/scenarios/style/DisableAnnotationsReactNativePdfScreen.tsx index 9f6ae23..8979099 100644 --- a/example/screens/scenarios/style/DisableAnnotationsReactNativePdfScreen.tsx +++ b/example/screens/scenarios/style/DisableAnnotationsReactNativePdfScreen.tsx @@ -22,7 +22,7 @@ export default function DisableAnnotationsReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={DisableAnnotationsScenario.name} description={DisableAnnotationsScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/style/EnableAnnotationsCoolPdfScreen.tsx b/example/screens/scenarios/style/EnableAnnotationsCoolPdfScreen.tsx index e8a4d54..56d484b 100644 --- a/example/screens/scenarios/style/EnableAnnotationsCoolPdfScreen.tsx +++ b/example/screens/scenarios/style/EnableAnnotationsCoolPdfScreen.tsx @@ -22,7 +22,7 @@ export default function EnableAnnotationsCoolPdfScreen() { implementation="CoolPDF Implementation" name={EnableAnnotationsScenario.name} description={EnableAnnotationsScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/style/EnableAnnotationsReactNativePdfScreen.tsx b/example/screens/scenarios/style/EnableAnnotationsReactNativePdfScreen.tsx index e95fc1e..c3bfec2 100644 --- a/example/screens/scenarios/style/EnableAnnotationsReactNativePdfScreen.tsx +++ b/example/screens/scenarios/style/EnableAnnotationsReactNativePdfScreen.tsx @@ -22,7 +22,7 @@ export default function EnableAnnotationsReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={EnableAnnotationsScenario.name} description={EnableAnnotationsScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/style/ProgressContainerStyleCoolPdfScreen.tsx b/example/screens/scenarios/style/ProgressContainerStyleCoolPdfScreen.tsx index 09f201e..1f02573 100644 --- a/example/screens/scenarios/style/ProgressContainerStyleCoolPdfScreen.tsx +++ b/example/screens/scenarios/style/ProgressContainerStyleCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function ProgressContainerStyleCoolPdfScreen() { implementation="CoolPDF Implementation" name={ProgressContainerStyleScenario.name} description={ProgressContainerStyleScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/style/ProgressContainerStyleReactNativePdfScreen.tsx b/example/screens/scenarios/style/ProgressContainerStyleReactNativePdfScreen.tsx index 6447f17..69a7368 100644 --- a/example/screens/scenarios/style/ProgressContainerStyleReactNativePdfScreen.tsx +++ b/example/screens/scenarios/style/ProgressContainerStyleReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function ProgressContainerStyleReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={ProgressContainerStyleScenario.name} description={ProgressContainerStyleScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/style/RenderActivityIndicatorCoolPdfScreen.tsx b/example/screens/scenarios/style/RenderActivityIndicatorCoolPdfScreen.tsx index c2a9e70..47a3ba1 100644 --- a/example/screens/scenarios/style/RenderActivityIndicatorCoolPdfScreen.tsx +++ b/example/screens/scenarios/style/RenderActivityIndicatorCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function RenderActivityIndicatorCoolPdfScreen() { implementation="CoolPDF Implementation" name={RenderActivityIndicatorScenario.name} description={RenderActivityIndicatorScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/style/RenderActivityIndicatorReactNativePdfScreen.tsx b/example/screens/scenarios/style/RenderActivityIndicatorReactNativePdfScreen.tsx index 80728f0..e0e97b9 100644 --- a/example/screens/scenarios/style/RenderActivityIndicatorReactNativePdfScreen.tsx +++ b/example/screens/scenarios/style/RenderActivityIndicatorReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function RenderActivityIndicatorReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={RenderActivityIndicatorScenario.name} description={RenderActivityIndicatorScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/CustomZoomRangeCoolPdfScreen.tsx b/example/screens/scenarios/zoom/CustomZoomRangeCoolPdfScreen.tsx index ad4e0e1..9f54072 100644 --- a/example/screens/scenarios/zoom/CustomZoomRangeCoolPdfScreen.tsx +++ b/example/screens/scenarios/zoom/CustomZoomRangeCoolPdfScreen.tsx @@ -28,7 +28,7 @@ export default function CustomZoomRangeCoolPdfScreen() { implementation="CoolPDF Implementation" name={CustomZoomRangeScenario.name} description={CustomZoomRangeScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/CustomZoomRangeReactNativePdfScreen.tsx b/example/screens/scenarios/zoom/CustomZoomRangeReactNativePdfScreen.tsx index a27b83b..a858ebe 100644 --- a/example/screens/scenarios/zoom/CustomZoomRangeReactNativePdfScreen.tsx +++ b/example/screens/scenarios/zoom/CustomZoomRangeReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function CustomZoomRangeReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={CustomZoomRangeScenario.name} description={CustomZoomRangeScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/EnableDoubleTapZoomPropCoolPdfScreen.tsx b/example/screens/scenarios/zoom/EnableDoubleTapZoomPropCoolPdfScreen.tsx index f99642f..6a6c331 100644 --- a/example/screens/scenarios/zoom/EnableDoubleTapZoomPropCoolPdfScreen.tsx +++ b/example/screens/scenarios/zoom/EnableDoubleTapZoomPropCoolPdfScreen.tsx @@ -22,7 +22,7 @@ export default function EnableDoubleTapZoomPropCoolPdfScreen() { implementation="CoolPDF Implementation" name={EnableDoubleTapZoomPropScenario.name} description={EnableDoubleTapZoomPropScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> @@ -57,7 +57,7 @@ export default function EnableDoubleTapZoomPropCoolPdfScreen() { style={styles.pdf} /> - + ); } diff --git a/example/screens/scenarios/zoom/EnableDoubleTapZoomPropReactNativePdfScreen.tsx b/example/screens/scenarios/zoom/EnableDoubleTapZoomPropReactNativePdfScreen.tsx index 560f617..137701a 100644 --- a/example/screens/scenarios/zoom/EnableDoubleTapZoomPropReactNativePdfScreen.tsx +++ b/example/screens/scenarios/zoom/EnableDoubleTapZoomPropReactNativePdfScreen.tsx @@ -22,7 +22,7 @@ export default function EnableDoubleTapZoomPropReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={EnableDoubleTapZoomPropScenario.name} description={EnableDoubleTapZoomPropScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> @@ -56,7 +56,7 @@ export default function EnableDoubleTapZoomPropReactNativePdfScreen() { trustAllCerts={false} /> - + ); } diff --git a/example/screens/scenarios/zoom/FitPolicyPropCoolPdfScreen.tsx b/example/screens/scenarios/zoom/FitPolicyPropCoolPdfScreen.tsx index ca42c63..3238614 100644 --- a/example/screens/scenarios/zoom/FitPolicyPropCoolPdfScreen.tsx +++ b/example/screens/scenarios/zoom/FitPolicyPropCoolPdfScreen.tsx @@ -30,7 +30,7 @@ export default function FitPolicyPropCoolPdfScreen() { implementation="CoolPDF Implementation" name={FitPolicyPropScenario.name} description={FitPolicyPropScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> @@ -76,7 +76,7 @@ export default function FitPolicyPropCoolPdfScreen() { style={styles.pdf} /> - + ); } diff --git a/example/screens/scenarios/zoom/FitPolicyPropReactNativePdfScreen.tsx b/example/screens/scenarios/zoom/FitPolicyPropReactNativePdfScreen.tsx index 6cc9782..978bf3e 100644 --- a/example/screens/scenarios/zoom/FitPolicyPropReactNativePdfScreen.tsx +++ b/example/screens/scenarios/zoom/FitPolicyPropReactNativePdfScreen.tsx @@ -30,7 +30,7 @@ export default function FitPolicyPropReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={FitPolicyPropScenario.name} description={FitPolicyPropScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> @@ -75,7 +75,7 @@ export default function FitPolicyPropReactNativePdfScreen() { trustAllCerts={false} /> - + ); } diff --git a/example/screens/scenarios/zoom/InitialZoomCoolPdfScreen.tsx b/example/screens/scenarios/zoom/InitialZoomCoolPdfScreen.tsx index 4ae6b0c..b823463 100644 --- a/example/screens/scenarios/zoom/InitialZoomCoolPdfScreen.tsx +++ b/example/screens/scenarios/zoom/InitialZoomCoolPdfScreen.tsx @@ -28,7 +28,7 @@ export default function InitialZoomCoolPdfScreen() { implementation="CoolPDF Implementation" name={InitialZoomScenario.name} description={InitialZoomScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/InitialZoomReactNativePdfScreen.tsx b/example/screens/scenarios/zoom/InitialZoomReactNativePdfScreen.tsx index cd47d13..d94d1d6 100644 --- a/example/screens/scenarios/zoom/InitialZoomReactNativePdfScreen.tsx +++ b/example/screens/scenarios/zoom/InitialZoomReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function InitialZoomReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={InitialZoomScenario.name} description={InitialZoomScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/MaxScalePropCoolPdfScreen.tsx b/example/screens/scenarios/zoom/MaxScalePropCoolPdfScreen.tsx index 259a151..cd5f1a3 100644 --- a/example/screens/scenarios/zoom/MaxScalePropCoolPdfScreen.tsx +++ b/example/screens/scenarios/zoom/MaxScalePropCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function MaxScalePropCoolPdfScreen() { implementation="CoolPDF Implementation" name={MaxScalePropScenario.name} description={MaxScalePropScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/MaxScalePropReactNativePdfScreen.tsx b/example/screens/scenarios/zoom/MaxScalePropReactNativePdfScreen.tsx index bff7c37..1c9d416 100644 --- a/example/screens/scenarios/zoom/MaxScalePropReactNativePdfScreen.tsx +++ b/example/screens/scenarios/zoom/MaxScalePropReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function MaxScalePropReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={MaxScalePropScenario.name} description={MaxScalePropScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/MinScalePropCoolPdfScreen.tsx b/example/screens/scenarios/zoom/MinScalePropCoolPdfScreen.tsx index ba425f9..78af0e9 100644 --- a/example/screens/scenarios/zoom/MinScalePropCoolPdfScreen.tsx +++ b/example/screens/scenarios/zoom/MinScalePropCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function MinScalePropCoolPdfScreen() { implementation="CoolPDF Implementation" name={MinScalePropScenario.name} description={MinScalePropScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/MinScalePropReactNativePdfScreen.tsx b/example/screens/scenarios/zoom/MinScalePropReactNativePdfScreen.tsx index a9c5f22..ac4e18b 100644 --- a/example/screens/scenarios/zoom/MinScalePropReactNativePdfScreen.tsx +++ b/example/screens/scenarios/zoom/MinScalePropReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function MinScalePropReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={MinScalePropScenario.name} description={MinScalePropScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/RestrictedZoomCoolPdfScreen.tsx b/example/screens/scenarios/zoom/RestrictedZoomCoolPdfScreen.tsx index e9fe3d6..b12ec11 100644 --- a/example/screens/scenarios/zoom/RestrictedZoomCoolPdfScreen.tsx +++ b/example/screens/scenarios/zoom/RestrictedZoomCoolPdfScreen.tsx @@ -28,7 +28,7 @@ export default function RestrictedZoomCoolPdfScreen() { implementation="CoolPDF Implementation" name={RestrictedZoomScenario.name} description={RestrictedZoomScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/RestrictedZoomReactNativePdfScreen.tsx b/example/screens/scenarios/zoom/RestrictedZoomReactNativePdfScreen.tsx index 87e9a3a..99a50ad 100644 --- a/example/screens/scenarios/zoom/RestrictedZoomReactNativePdfScreen.tsx +++ b/example/screens/scenarios/zoom/RestrictedZoomReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function RestrictedZoomReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={RestrictedZoomScenario.name} description={RestrictedZoomScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/ScalePropCoolPdfScreen.tsx b/example/screens/scenarios/zoom/ScalePropCoolPdfScreen.tsx index f856d1b..fcc2e94 100644 --- a/example/screens/scenarios/zoom/ScalePropCoolPdfScreen.tsx +++ b/example/screens/scenarios/zoom/ScalePropCoolPdfScreen.tsx @@ -21,7 +21,7 @@ export default function ScalePropCoolPdfScreen() { implementation="CoolPDF Implementation" name={ScalePropScenario.name} description={ScalePropScenario.description} - backgroundColor="#5856d6" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/screens/scenarios/zoom/ScalePropReactNativePdfScreen.tsx b/example/screens/scenarios/zoom/ScalePropReactNativePdfScreen.tsx index aac3c5a..868bc87 100644 --- a/example/screens/scenarios/zoom/ScalePropReactNativePdfScreen.tsx +++ b/example/screens/scenarios/zoom/ScalePropReactNativePdfScreen.tsx @@ -21,7 +21,7 @@ export default function ScalePropReactNativePdfScreen() { implementation="react-native-pdf Implementation" name={ScalePropScenario.name} description={ScalePropScenario.description} - backgroundColor="#34c759" + backgroundColor="#6b7280" /> - + ); } diff --git a/example/scripts/compare-screenshots.js b/example/scripts/compare-screenshots.js new file mode 100755 index 0000000..c5fe844 --- /dev/null +++ b/example/scripts/compare-screenshots.js @@ -0,0 +1,418 @@ +#!/usr/bin/env node + +/** + * Visual Comparison Script for Maestro Test Screenshots + * + * This script: + * 1. Finds all screenshot pairs (CoolPDF vs react-native-pdf) + * 2. Uses ImageMagick to generate visual diffs + * 3. Calculates difference metrics + * 4. Generates an HTML report with side-by-side comparisons + */ + +const { execSync } = require('child_process'); +const fs = require('fs'); +const path = require('path'); + +// Configuration +const SCREENSHOTS_DIR = '/tmp/maestro-screenshots'; +const OUTPUT_DIR = path.join(__dirname, '..', 'visual-diff-results'); +const REPORT_FILE = path.join(OUTPUT_DIR, 'visual-comparison-report.html'); + +// Ensure output directory exists +if (!fs.existsSync(OUTPUT_DIR)) { + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); +} + +/** + * Check if ImageMagick is installed + */ +function checkImageMagick() { + try { + execSync('which compare', { encoding: 'utf8' }); + console.log('✓ ImageMagick is installed'); + return true; + } catch (error) { + console.error('✗ ImageMagick is not installed'); + console.error(' Install with: brew install imagemagick'); + return false; + } +} + +/** + * Find screenshot pairs in the screenshots directory + */ +function findScreenshotPairs() { + if (!fs.existsSync(SCREENSHOTS_DIR)) { + throw new Error(`Screenshots directory not found: ${SCREENSHOTS_DIR}`); + } + + const files = fs.readdirSync(SCREENSHOTS_DIR); + const screenshots = files.filter(f => f.endsWith('.png')); + + const pairs = []; + const processed = new Set(); + + screenshots.forEach(file => { + if (processed.has(file)) return; + + if (file.includes('-coolpdf.png')) { + const baseName = file.replace('-coolpdf.png', ''); + const rnpdfFile = `${baseName}-rnpdf.png`; + + if (screenshots.includes(rnpdfFile)) { + pairs.push({ + name: baseName, + coolpdf: path.join(SCREENSHOTS_DIR, file), + rnpdf: path.join(SCREENSHOTS_DIR, rnpdfFile), + diffOutput: path.join(OUTPUT_DIR, `${baseName}-diff.png`) + }); + processed.add(file); + processed.add(rnpdfFile); + } + } + }); + + return pairs; +} + +/** + * Compare two images using ImageMagick + */ +function compareImages(pair) { + console.log(`Comparing: ${pair.name}`); + + try { + // Use ImageMagick compare command + // -metric AE counts the number of different pixels + // -compose src outputs the difference image + // Note: compare exits with code 1 when images differ, so we use try/catch to handle both cases + let result; + try { + result = execSync( + `compare -metric AE -compose src "${pair.coolpdf}" "${pair.rnpdf}" "${pair.diffOutput}" 2>&1`, + { encoding: 'utf8' } + ); + } catch (error) { + // ImageMagick exits with code 1 when images differ, but still outputs the metric + result = error.stdout || error.stderr || error.message; + } + + const differentPixels = parseInt(result.trim().split(' ')[0]) || 0; + + // Get image dimensions to calculate percentage + const identify = execSync(`identify -format "%w %h" "${pair.coolpdf}"`, { encoding: 'utf8' }); + const [width, height] = identify.trim().split(' ').map(Number); + const totalPixels = width * height; + const diffPercentage = ((differentPixels / totalPixels) * 100).toFixed(2); + + return { + ...pair, + differentPixels, + totalPixels, + diffPercentage: parseFloat(diffPercentage), + status: differentPixels === 0 ? 'identical' : diffPercentage < 1 ? 'minor-diff' : 'significant-diff' + }; + } catch (error) { + console.error(`Error comparing ${pair.name}:`, error.message); + return { + ...pair, + error: error.message, + status: 'error' + }; + } +} + +/** + * Generate HTML report + */ +function generateHTMLReport(comparisons) { + const html = ` + + + + + + Visual Comparison Report - CoolPDF vs react-native-pdf + + + + + 📊 Visual Comparison Report + Generated: ${new Date().toLocaleString()} + + + Summary + + + ${comparisons.length} + Total Tests + + + ${comparisons.filter(c => c.status === 'identical').length} + Identical + + + ${comparisons.filter(c => c.status === 'minor-diff').length} + Minor Differences + + + ${comparisons.filter(c => c.status === 'significant-diff').length} + Significant Differences + + + + + ${comparisons.map(comp => ` + + + ${comp.name} + + ${comp.status === 'identical' ? '✓ Identical' : + comp.status === 'minor-diff' ? '⚠ Minor Difference' : + comp.status === 'significant-diff' ? '✗ Significant Difference' : + '✗ Error'} + + + + ${comp.error ? ` + Error: ${comp.error} + ` : ` + + + Different Pixels: ${comp.differentPixels.toLocaleString()} + + + Difference: ${comp.diffPercentage}% + + + Total Pixels: ${comp.totalPixels.toLocaleString()} + + + + + + CoolPDF + + + + react-native-pdf + + + + Difference + + + + `} + + `).join('')} + + + + `; + + fs.writeFileSync(REPORT_FILE, html); + console.log(`\n✓ Report generated: ${REPORT_FILE}`); +} + +/** + * Main execution + */ +function main() { + console.log('🔍 Visual Comparison Tool for CoolPDF vs react-native-pdf\n'); + + // Check dependencies + if (!checkImageMagick()) { + process.exit(1); + } + + // Find screenshot pairs + const pairs = findScreenshotPairs(); + console.log(`✓ Found ${pairs.length} screenshot pair(s)\n`); + + if (pairs.length === 0) { + console.log('No screenshot pairs found. Make sure your tests use takeScreenshot with -coolpdf and -rnpdf suffixes.'); + process.exit(0); + } + + // Compare each pair + const comparisons = pairs.map(compareImages); + + // Generate report + generateHTMLReport(comparisons); + + // Print summary + console.log('\n📊 Comparison Summary:'); + console.log(` Identical: ${comparisons.filter(c => c.status === 'identical').length}`); + console.log(` Minor differences: ${comparisons.filter(c => c.status === 'minor-diff').length}`); + console.log(` Significant differences: ${comparisons.filter(c => c.status === 'significant-diff').length}`); + console.log(` Errors: ${comparisons.filter(c => c.status === 'error').length}`); + + // Open report + console.log(`\n🌐 Opening report in browser...`); + execSync(`open "${REPORT_FILE}"`); +} + +// Run if called directly +if (require.main === module) { + main(); +} + +module.exports = { findScreenshotPairs, compareImages, generateHTMLReport }; \ No newline at end of file diff --git a/example/visual-diff-results/basic-base64-diff.png b/example/visual-diff-results/basic-base64-diff.png new file mode 100644 index 0000000..2cff6c9 Binary files /dev/null and b/example/visual-diff-results/basic-base64-diff.png differ diff --git a/example/visual-diff-results/basic-cache-filename-diff.png b/example/visual-diff-results/basic-cache-filename-diff.png new file mode 100644 index 0000000..624591a Binary files /dev/null and b/example/visual-diff-results/basic-cache-filename-diff.png differ diff --git a/example/visual-diff-results/basic-no-cache-diff.png b/example/visual-diff-results/basic-no-cache-diff.png new file mode 100644 index 0000000..cd84b44 Binary files /dev/null and b/example/visual-diff-results/basic-no-cache-diff.png differ diff --git a/example/visual-diff-results/basic-require-local-diff.png b/example/visual-diff-results/basic-require-local-diff.png new file mode 100644 index 0000000..a9e7834 Binary files /dev/null and b/example/visual-diff-results/basic-require-local-diff.png differ diff --git a/example/visual-diff-results/basic-with-cache-diff.png b/example/visual-diff-results/basic-with-cache-diff.png new file mode 100644 index 0000000..467827e Binary files /dev/null and b/example/visual-diff-results/basic-with-cache-diff.png differ diff --git a/example/visual-diff-results/visual-comparison-report.html b/example/visual-diff-results/visual-comparison-report.html new file mode 100644 index 0000000..921eba3 --- /dev/null +++ b/example/visual-diff-results/visual-comparison-report.html @@ -0,0 +1,387 @@ + + + + + + + Visual Comparison Report - CoolPDF vs react-native-pdf + + + + + 📊 Visual Comparison Report + Generated: 10/20/2025, 8:57:14 PM + + + Summary + + + 5 + Total Tests + + + 0 + Identical + + + 5 + Minor Differences + + + 0 + Significant Differences + + + + + + + + basic-base64 + + ⚠ Minor Difference + + + + + + + Different Pixels: 1,954 + + + Difference: 0.08% + + + Total Pixels: 2,592,000 + + + + + + CoolPDF + + + + react-native-pdf + + + + Difference + + + + + + + + + basic-cache-filename + + ⚠ Minor Difference + + + + + + + Different Pixels: 14,167 + + + Difference: 0.55% + + + Total Pixels: 2,592,000 + + + + + + CoolPDF + + + + react-native-pdf + + + + Difference + + + + + + + + + basic-no-cache + + ⚠ Minor Difference + + + + + + + Different Pixels: 14,167 + + + Difference: 0.55% + + + Total Pixels: 2,592,000 + + + + + + CoolPDF + + + + react-native-pdf + + + + Difference + + + + + + + + + basic-require-local + + ⚠ Minor Difference + + + + + + + Different Pixels: 3,977 + + + Difference: 0.15% + + + Total Pixels: 2,592,000 + + + + + + CoolPDF + + + + react-native-pdf + + + + Difference + + + + + + + + + basic-with-cache + + ⚠ Minor Difference + + + + + + + Different Pixels: 14,167 + + + Difference: 0.55% + + + Total Pixels: 2,592,000 + + + + + + CoolPDF + + + + react-native-pdf + + + + Difference + + + + + + + + + + \ No newline at end of file
Generated: ${new Date().toLocaleString()}
Error: ${comp.error}
Generated: 10/20/2025, 8:57:14 PM