Cypress E2E Tests with Stable Placeholder Image URLs
Replace flaky remote images in Cypress E2E tests with stable cypress image testing strategies using deterministic placeholder URLs that never return 404 or time out.
Remote image URLs in Cypress E2E tests introduce flakiness. A CDN outage, a 404 from a staging environment, or a slow image load can cause assertions to fail for reasons unrelated to the feature under test. Replacing remote image src values with deterministic placeholder URLs from fallback.pics eliminates the entire class of image-related test failures.
This guide covers three approaches: intercepting image requests with cy.intercept(), injecting placeholder URLs via test fixtures, and configuring Cypress to globally stub external image domains during E2E runs.
Problem
Why remote images break Cypress tests
Cypress tests run against real network conditions unless you stub requests. A test that clicks through a product catalog depends on every product image loading without a 404. If one image CDN request times out, the test either hangs waiting for the image or fails an assertion about image visibility.
Snapshot-based visual tests are even more sensitive. A slightly different image (new compression artifact, updated content) can cause pixel-diff failures that have nothing to do with the component under test.
Placeholder URLs from fallback.pics are deterministic: the same URL always returns the same pixel output. They cache for a year and never return 404. This makes them ideal replacements for real image URLs in test environments.
cy.intercept
Stubbing image requests with cy.intercept in Cypress
cy.intercept() can match image requests by URL pattern and return a fixture or redirect to a deterministic placeholder URL. Use this approach when image URLs are generated at runtime and can't be replaced in fixtures.
Returning a redirect (statusCode 302, Location header pointing to fallback.pics) is simpler than returning binary fixture data. Cypress follows redirects, the browser fetches the placeholder, and your test assertions see a loaded image.
// cypress/support/commands.ts
Cypress.Commands.add('stubImages', () => {
// Stub any image from your CDN with a deterministic placeholder
cy.intercept('GET', 'https://cdn.yourapp.com/**', (req) => {
// Parse dimensions from URL if available, else use default
req.reply({
statusCode: 302,
headers: {
Location: 'https://fallback.pics/api/v1/400x300/7C3AED/FFFFFF?text=Test+Image',
},
});
}).as('stubImages');
});
// In tests
describe('Product catalog', () => {
beforeEach(() => {
cy.stubImages();
cy.visit('/products');
});
it('displays product cards with images', () => {
cy.get('[data-cy="product-image"]')
.should('be.visible')
.and('have.attr', 'src')
.and('not.be.empty');
});
}); Fixtures
Injecting placeholder URLs via Cypress fixtures
When your app fetches product or article data from an API, use cy.intercept() to return a fixture file where image URLs are already replaced with fallback.pics URLs. This approach is clean: all test data is in fixture files, and there is no regex logic in test files.
Keep fixture image URLs dimensional and labeled so they are easy to distinguish in test screenshots: 400x300 for product images, avatar/80 for user thumbnails.
// cypress/fixtures/products.json
{
"data": [
{
"id": "1",
"name": "Test Product",
"imageUrl": "https://fallback.pics/api/v1/400x400/7C3AED/FFFFFF?text=Product+1",
"price": 29.99
},
{
"id": "2",
"name": "Another Product",
"imageUrl": "https://fallback.pics/api/v1/400x400/3B82F6/FFFFFF?text=Product+2",
"price": 49.99
}
]
}
// cypress/e2e/products.cy.ts
it('renders product grid', () => {
cy.intercept('GET', '/api/products', { fixture: 'products.json' }).as('products');
cy.visit('/shop');
cy.wait('@products');
cy.get('[data-cy="product-card"]').should('have.length', 2);
}); Global config
Globally blocking image domains in cypress.config.ts
For test suites where you never want real CDN images, configure a Cypress intercept in the setupNodeEvents hook to block all external image domains and return placeholder redirects. This runs before every test without needing a cy.stubImages() call.
Be specific about which domains to stub. Blocking * can interfere with auth flows, OAuth redirects, and other requests your tests depend on.
// cypress.config.ts
import { defineConfig } from 'cypress';
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// No node-level image stubbing available, use support file
},
baseUrl: 'http://localhost:3000',
},
});
// cypress/support/e2e.ts
before(() => {
cy.intercept(
{ method: 'GET', hostname: 'images.yourdomain.com' },
{
statusCode: 302,
headers: {
Location: 'https://fallback.pics/api/v1/400x300/E5E7EB/71717A?text=Stubbed',
},
}
);
}); Visual testing
Using placeholder URLs for visual regression baselines
Visual regression tools like Percy and Chromatic compare screenshots pixel-by-pixel. Real images introduce noise: compression differs between CDN regions, content changes, and image crops vary. Replacing real images with deterministic placeholders produces stable baselines that only change when your UI changes.
Label placeholders with the content they represent (text=Hero+Image, text=Avatar) so screenshots are readable without context. Use different colors for different content types to catch layout errors visually.
// Meaningful placeholder URLs for visual tests
// Hero image — full width banner
https://fallback.pics/api/v1/1200x400/7C3AED/FFFFFF?text=Hero+Image
// Avatar in header
https://fallback.pics/api/v1/avatar/40?text=JD
// Sidebar thumbnail
https://fallback.pics/api/v1/120x80/3B82F6/FFFFFF?text=Thumb Key takeaways
What to standardize before shipping
- Replace remote CDN image URLs in Cypress tests with deterministic fallback.pics URLs to eliminate an entire class of network-related test flakiness.
- Use cy.intercept() to redirect image requests to placeholder URLs at runtime, or preload fixture JSON files where image URLs are already substituted.
- Configure global intercepts in cypress/support/e2e.ts to stub all requests from your image CDN domain without repeating setup in every test file.
- Label placeholder URLs with descriptive text parameters so visual regression screenshots are readable without additional context.
- For visual regression baselines, deterministic placeholders eliminate pixel noise from CDN compression differences and content updates.
Production fallback layer
Use fallback.pics anywhere an image URL is accepted.
Start with one deterministic URL and standardize fallback behavior across your design system.