Proxies for Cypress Testing
Cypress is a popular E2E testing framework that runs in the browser. Unlike Playwright and Puppeteer, Cypress does not have built-in proxy configuration at the browser level. Instead, you configure proxies through environment variables and custom commands for network-level proxy routing.
Environment Variable Configuration
Cypress respects HTTP_PROXY and HTTPS_PROXY environment variables:
HTTP_PROXY=http://YOUR_USER:YOUR_PASS@gate.hexproxies.com:8080 \
HTTPS_PROXY=http://YOUR_USER:YOUR_PASS@gate.hexproxies.com:8080 \
npx cypress runcypress.config.ts Setup
import { defineConfig } from 'cypress';export default defineConfig({
e2e: {
baseUrl: 'https://yoursite.com',
env: {
PROXY_USER: process.env.PROXY_USER || '',
PROXY_PASS: process.env.PROXY_PASS || '',
},
setupNodeEvents(on, config) {
on('task', {
async fetchThroughProxy({ url, country }) {
const proxyUser = country
? ${config.env.PROXY_USER}-country-${country.toLowerCase()}
: config.env.PROXY_USER;
const proxyUrl = http://${proxyUser}:${config.env.PROXY_PASS}@gate.hexproxies.com:8080;
const { HttpsProxyAgent } = await import('https-proxy-agent'); const agent = new HttpsProxyAgent(proxyUrl);
const response = await fetch(url, { agent }); const body = await response.text(); return { status: response.status, body, url: response.url }; }, }); }, }, }); ```
Custom Command for Geo-Testing
// cypress/support/commands.ts
Cypress.Commands.add('geoFetch', (url: string, country: string) => {
return cy.task('fetchThroughProxy', { url, country });
});declare global { namespace Cypress { interface Chainable { geoFetch(url: string, country: string): Chainable<{ status: number; body: string; url: string; }>; } } } ```
Test Examples
describe('Geo-targeted pricing', () => {
const countries = [
{ code: 'US', currency: 'USD' },
{ code: 'GB', currency: 'GBP' },
{ code: 'DE', currency: 'EUR' },
{ code: 'JP', currency: 'JPY' },
];countries.forEach(({ code, currency }) => {
it(shows ${currency} for visitors from ${code}, () => {
cy.geoFetch('https://yoursite.com/pricing', code).then((result) => {
expect(result.status).to.equal(200);
expect(result.body).to.contain(currency);
});
});
});
it('does not redirect US visitors', () => { cy.geoFetch('https://yoursite.com', 'US').then((result) => { expect(result.url).to.equal('https://yoursite.com/'); }); });
it('redirects DE visitors to /de/', () => { cy.geoFetch('https://yoursite.com', 'DE').then((result) => { expect(result.url).to.contain('/de/'); }); }); }); ```
CI/CD Integration
# GitHub Actions
name: Cypress Geo Tests
on: [push]jobs: cypress: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: cypress-io/github-action@v6 env: PROXY_USER: ${{ secrets.HEX_PROXY_USER }} PROXY_PASS: ${{ secrets.HEX_PROXY_PASS }} HTTP_PROXY: http://${{ secrets.HEX_PROXY_USER }}:${{ secrets.HEX_PROXY_PASS }}@gate.hexproxies.com:8080 HTTPS_PROXY: http://${{ secrets.HEX_PROXY_USER }}:${{ secrets.HEX_PROXY_PASS }}@gate.hexproxies.com:8080 ```
Limitations and Workarounds
Cypress intercepts network requests at the application level, not the browser network stack. For full proxy routing, use the cy.task approach shown above, which runs Node.js code server-side where proxy agents work reliably. For browser-level proxy routing in Cypress, set environment variables before launching.
Hex Proxies ISP infrastructure adds minimal latency (sub-50ms), keeping your Cypress test suite fast even with proxy routing.