VALIDATION LABIMAGE HANDLING LAB

Date & Files

Image Handling Lab

Validate working, broken, slow, unauthorized, and corrupted image states with fallbacks, loading indicators, retry actions, and layout stability checks.

Intermediate

Scenario

Real products rely on remote avatars, CDN assets, private documents, and uploaded media. QA needs to prove broken images do not collapse layout, hide alt text, or trap users in infinite loading states.

Image Handling Lab

Broken image QA scenarios

Validate loading, error handling, fallback copy, layout stability, and retry behavior across realistic image states.

Failed images: 0
Loading images: 5
Layout: risk of shift
Loading image...
Decorative dashboard image

Working image

Expected: 200 OK

loading
Loading image...
Decorative dashboard image

Broken image

Expected: 404 Not Found

loading
Loading image...

Slow loading image

Expected: Delayed 200 OK

loading
Loading image...
Decorative dashboard image

Unauthorized image

Expected: 403 Forbidden

loading
Loading image...
Decorative dashboard image

Corrupted image

Expected: Corrupted binary

loading

Live widget · interact freely

Manual test checklist

  • 1Identify which images fail to load and compare them with the failed count
  • 2Verify `image-error-{n}` fallback UI appears for every failed image
  • 3Check that failed image cards keep a stable layout height
  • 4Confirm the slow image eventually leaves `image-loading-3` unless the infinite-spinner bug is enabled
  • 5Use Retry load on failed images and verify loading/error states are observable

Expected result

Successful images render, failing images stop loading and show useful fallback UI with truthful alt text, and slow images do not spin forever.

Automation challenge

Assert the working image loads, the broken image exposes `image-error-2` when the missing-fallback bug is disabled, and the slow image does not keep `image-loading-3` visible forever.

Stable selectors

  • Image lab[data-testid="image-handling-lab"]
  • Working image[data-testid="image-1"]
  • Broken image[data-testid="image-2"]
  • Slow image loading[data-testid="image-loading-3"]
  • Unauthorized image error[data-testid="image-error-4"]
  • Corrupted image error[data-testid="image-error-5"]
  • Failed count[data-testid="image-lab-failed-count"]
  • Retry broken image[data-testid="image-retry-2"]
  • Bug controls[data-testid="image-bug-controls"]

Locator strategy

Three levels from simple IDs to scoped Playwright locators. IDs and names are easy to learn but are not always the best long-term choice when labels change or components repeat.

Use simple IDs and names to understand how locating elements works. Image labs expose predictable ids for each image, spinner, error panel, and retry button.

1
2
3
4
await page.goto('https://lab.hakdogan.com/practice/broken-images');

await expect(page.locator('[data-testid="image-1"]')).toBeVisible();
await expect(page.locator('[data-testid="image-loading-3"]')).toBeVisible();

Avoid as primary strategies

XPath (unless there is no alternative), long CSS chains, Tailwind-style utility class selectors, generated or unstable IDs, and volatile framework internals break when layout, styling, or DOM structure shifts.

1
2
await page.locator('.w-full.rounded-xl.border.bg-blue-500').fill('demo@example.com');
await page.locator('//div[2]/form/div[1]/input').fill('demo@example.com');

Reference Playwright spec

broken-images.spec.ts
ts
1
2
3
4
5
6
7
8
9
10
11
12
13
import { test, expect } from '@playwright/test';

test('image handling lab shows fallbacks for failed images', async ({ page }) => {
  await page.goto('https://lab.hakdogan.com/practice/broken-images');

  await page.getByTestId('image-bug-missingFallback').uncheck();
  await page.getByTestId('image-bug-infiniteSpinner').uncheck();

  await expect(page.getByTestId('image-1')).toBeVisible();
  await expect(page.getByTestId('image-error-2')).toBeVisible();
  await expect(page.getByTestId('image-error-4')).toBeVisible();
  await expect(page.getByTestId('image-loading-3')).toBeHidden({ timeout: 3000 });
});

Headed Test Playback

Simulated headed-browser flow — no real browser is launched.

Automation-style playback (Playwright-shaped logs). No real browser; no commands run on your machine.

Idlebroken-images.spec.ts
Failure demos
https://lab.hakdogan.com/practice/broken-images
playwright · headed · chromium0.00s
# awaiting Run Test · terminal scrolls automatically
Steps
  1. Interacting with image handling lab widget
  2. Awaiting deterministic render
  3. Asserting expected state
  4. Cleaning up context
  5. Pass
StatusIdle
BrowserChromium
FrameworkPlaywright + TypeScript
Elapsed (live)--
Specbroken-images.spec.ts