Developer testing guide

Image testing guide for web applications

Image features fail at file selection, validation, optimization, layout, and decoding. TestFiles generates repeatable PNG, JPEG, WebP, and SVG inputs in the browser without publishing or uploading them.

Verified . Generated in current Chrome, Safari, and Firefox-compatible browser APIs, then inspected by the local magic-byte tool.

Practical checklist

  • Validate magic bytes and MIME independently from the extension.
  • Cover landscape, portrait, square, transparent, and one-pixel cases.
  • Reserve intrinsic dimensions before rendering.
  • Record the generated file size used by each boundary test.

Validate before rendering

Check the signature, declared MIME, byte size, and decoded dimensions independently. A renamed extension must not bypass server validation; browser checks are user guidance, not a security boundary.

Exercise responsive layouts

Use contrasting aspect ratios to test object-fit, fixed containers, srcset selection, lazy loading, and layout stability. Reserve dimensions or an aspect ratio before the image finishes decoding.

Test conversion and caching

Run one generated source through thumbnail and conversion pipelines. Verify output headers, cache keys, invalidation, orientation, transparency, and failure behavior for unsupported formats.

Expected results

  • Valid generated images decode with the expected dimensions and MIME.
  • Renamed or truncated inputs fail without reaching image processing.
  • Responsive containers retain their dimensions while the image loads.

Common failure modes

  • Trusting only the extension or browser-provided MIME.
  • Removing transparency during thumbnail conversion.
  • Creating layout shifts because width and height are unknown.

Check the fixture with curl

Download the representative file and print the response status, MIME type, and transferred byte count.

Shell
curl --fail --location --silent --show-error \
  --output landscape-1920x1080.avif \
  --write-out 'status=%{http_code}\ncontent_type=%{content_type}\nbytes=%{size_download}\n' \
  'https://assets.testfiles.dev/image/landscape-1920x1080.avif'

Fetch and upload the image fixture with Playwright

Fetch the published fixture as a buffer, assign it to a real file input, and verify the browser receives the registered name, MIME type, and byte size.

TypeScript
import { test, expect } from "@playwright/test";

test("uploads a verified image fixture", async ({ page, request }) => {
  const response = await request.get("https://assets.testfiles.dev/image/landscape-1920x1080.avif");
  expect(response.ok()).toBeTruthy();
  expect(response.headers()["content-type"] ?? "").toContain("image/avif");

  const buffer = await response.body();
  expect(buffer).toHaveLength(78931);

  await page.setContent('<input id="fixture" type="file">');
  await page.locator("#fixture").setInputFiles({
    name: "landscape-1920x1080.avif",
    mimeType: "image/avif",
    buffer,
  });

  const selected = await page.locator("#fixture").evaluate((input: HTMLInputElement) => ({
    name: input.files?.[0]?.name,
    type: input.files?.[0]?.type,
    size: input.files?.[0]?.size,
  }));
  expect(selected).toEqual({
    name: "landscape-1920x1080.avif",
    type: "image/avif",
    size: 78931,
  });
});

Use stable sample files

These fixtures have stable URLs, recorded MIME types, byte sizes, SHA-256 values, and dedicated detail pages.

Format references

Copied