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
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 Testsjobs: 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.