Juyalens — Documentation

Visual testing tool for uploading screenshots and running pixel-based comparisons

Overview

This is an application for visual testing. Upload screenshots via the API. Once screenshots are generated you will see runs on your dashboard. When you're ready, click the Compare button on a build page to run a pixel-based comparison between a base run and a test run.

🎯 Why Pixel Matching Outperforms DOM Matching in Visual Testing

When it comes to visual validation, not all comparison methods are created equal. Traditional DOM matching checks code structure — not what users actually see. Pixel matching, on the other hand, compares the rendered image of your application exactly as it appears in the browser. That means every pixel counts — ensuring a flawless, user-perfect interface.

🌈 1. Tests What Users Really See

Pixel matching captures the final, rendered UI — the same view your users interact with. Unlike DOM matching, which only compares markup, pixel matching verifies the real visual experience.

🪟 2. Seamlessly Covers Iframes and Embedded Content

DOM comparison can't access cross-origin iframes. Pixel matching easily includes every visible element on the screen — no matter where it comes from.

🖱️ 3. Validates Interactive States (Hover, Focus, Active)

Your UI isn't static — it changes with interaction. Pixel matching confirms hover styles, focus outlines, button presses, and disabled states — things the DOM can't "see."

🎨 4. Detects Even the Smallest Visual Changes

Color shifts, spacing tweaks, missing shadows — pixel matching spots every tiny deviation with pixel-level accuracy.

📐 5. Catches Layout Shifts Instantly

DOM trees might look identical while layouts have moved. Pixel matching exposes spacing and alignment issues before your users do.

💻 6. Works Across All Browsers and Devices

Pixel matching ensures consistent rendering everywhere — from Chrome to Safari, desktop to mobile.

🔍 7. Finds Hidden Visual Bugs

Elements covered, clipped, transparent, or off-screen? Pixel matching sees what the browser renders — not just what the DOM intends to show.

🧩 8. Framework-Agnostic

React, Angular, Vue, or plain HTML — pixel matching doesn't care how your app is built. It focuses purely on the final output, not the underlying code.

🔠 9. Ensures Fonts and Assets Render Correctly

Missing fonts, broken icons, blurry images — pixel matching detects it all with precision.

🎞️ 10. Verifies Animation and Transition End States

Animations might finish in unexpected visual states. Pixel matching confirms the final rendered frame looks exactly as designed.

💡 Comparison Summary
Feature Pixel Matching DOM Matching
Validates what users see ✅ Yes ❌ No
Detects style & layout changes ✅ Yes ⚠️ Partial
Works with iframes ✅ Yes ❌ No
Captures hover/focus states ✅ Yes ❌ No
Framework independent ✅ Yes ❌ No
Visual accuracy 🎯 Pixel-perfect ⚙️ Code-only
🚀 Conclusion

Pixel Matching delivers true visual confidence — ensuring your UI looks perfect, everywhere, every time. While DOM matching checks structure, Pixel Matching checks experience — and that's what your users truly care about.

Workflow

  1. Create an account and sign in.
  2. Generate an API token from the API Token page.
  3. Upload screenshots using the API and the generated token.
  4. Open the Dashboard (Builds) to see your runs.
  5. When you have matching base and test screenshots for a scenario, click Compare to perform the pixel comparison.
  6. View comparison results in the UI.

Upload API

Endpoint expects a multipart/form-data POST with an Authorization header containing your API token.

Endpoint
POST http://api.juyalens.com/api/upload
Required Parameters
  • Authorization (header): string — Your API token
  • release (query): string — The release name the screenshot belongs to
  • device (query): string — Device identifier - desktop, tablet, mobile
  • browser (query): string — Browser - chrome, firefox, edge, safari
  • scenarioId (query): string — Scenario identifier
  • width (query): string — Viewport width
  • type (query): string — Either base or test
  • stepName (query): string — Step name for the screenshot
Request Body

multipart/form-data with a single file field named file (binary image file).

Example
POST http://api.juyalens.com/api/screenshots/upload?release=release-123&device=desktop&browser=chrome&scenarioId=login&width=1920&type=base&stepName=on-load
Authorization: Bearer your-api-token-here
Content-Type: multipart/form-data

file: (binary)

How Screenshots are Matched

Screenshots are matched by the tuple: device, browser, scenarioId, width, type, stepName. Comparisons are only run when the UI detects matching identifiers between base and test sets.

To build a valid comparison you must upload a complete base run (for example: scenario 1) with the required parameters, then upload the corresponding test run (same scenarioId, device, browser, width, stepName). Once both sets are present, use the Compare action on the Builds page to run the pixel-based comparison.

Client Integration — Example Request

Perform a multipart/form-data POST with the file and query parameters. Include your API token in the Authorization header.

cURL Example
curl -X POST "https://your-domain.com/api/screenshots/upload?release=v1.0&device=desktop&browser=chrome&scenarioId=login&width=1920&type=base&stepName=homepage" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "file=@/path/to/screenshot.png"
Node.js Example
const FormData = require('form-data');
const fs = require('fs');
const axios = require('axios');

const form = new FormData();
form.append('file', fs.createReadStream('screenshot.png'));

axios.post('https://your-domain.com/api/screenshots/upload', form, {
  params: {
    release: 'v1.0',
    device: 'desktop',
    browser: 'chrome',
    scenarioId: 'login',
    width: '1920',
    type: 'base',
    stepName: 'homepage'
  },
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    ...form.getHeaders()
  }
});

Troubleshooting

  • If screenshots don't appear in the Dashboard, verify the Authorization header and the release query value.
  • Make sure the same identifying parameters (device/browser/scenarioId/width/stepName) are used between base and test uploads.
  • Check API token validity on the API Token page by regenerating if needed.
  • Ensure image files are in a supported format (PNG, JPG, JPEG).
  • Check that your API token has not expired or been revoked.