Playwright Zoo Setup for Multi-Domain Testing
This document describes how the Zoo environment is configured to support Playwright testing across multiple domains, specifically for use by both Volpe and Criceto projects.
Overview​
The Zoo environment now provides a shared Playwright infrastructure that allows any project (Volpe, Criceto, etc.) to run browser tests against all platform domains using a sidecar architecture.
Architecture​
Sidecar Mode​
- Playwright Server: Runs in dedicated container (
playwright) - Test Clients: Connect via WebSocket (
ws://playwright:3000) - Browser Execution: Happens in Playwright container with full domain access
- DNS Resolution: All platform domains configured in Playwright container
Container Setup​
# Global environment variables automatically added to ALL services
x-default-environment: &default-environment
- ZOO_ENV=true
playwright:
image: mcr.microsoft.com/playwright:v1.53.2-jammy
container_name: playwright
ports: ['3000:3000']
environment:
- ZOO_ENV=true # Automatically added to all services
- PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
- NODE_TLS_REJECT_UNAUTHORIZED=0
criceto:
environment:
- ZOO_ENV=true # Automatically added to all services
- PW_TEST_CONNECT_WS_ENDPOINT=ws://playwright:3000
depends_on: [playwright]
Available Domains for Testing​
All platform services are accessible via HTTPS through nginx reverse proxy:
| Domain | IP | Service |
|---|---|---|
volpe.localhost | 172.31.0.20 | Digital reader application |
farfalla.localhost | 172.31.0.20 | Core platform backend |
castoro.localhost | 172.31.0.20 | PDF processing service |
coniglio.localhost | 172.31.0.20 | Event tracking and analytics |
medusa.localhost | 172.31.0.20 | Content intake automation |
farfalla-integrations.localhost | 172.31.0.20 | Integration adapters |
farfalla-https-guard.localhost | 172.31.0.20 | HTTPS guard service |
minio.localhost | 172.31.0.19 | Object storage UI |
micelio.localhost | 172.31.0.21 | Smart CDN proxy |
felini.localhost | 172.31.0.21 | Legacy proxy |
criceto.localhost | 172.31.0.21 | Testing toolkit |
Usage for Criceto Team​
Prerequisites​
-
Start Zoo Environment:
./zoo/zoo.sh up -
Ensure Required Containers Are Running:
- ✅
nginx(reverse proxy for HTTPS domains) - ✅
playwright(browser execution server) - ✅ Target service containers (farfalla, volpe, etc.)
- ✅
Install Playwright in Criceto​
Already configured! Criceto package.json includes:
{
"devDependencies": {
"@playwright/test": "^1.53.2"
}
}
Create Playwright Configuration​
Create playwright.config.js in Criceto project:
import { defineConfig, devices } from '@playwright/test';
// Environment detection
const isCI = !!process.env.CI;
const isSidecar = !!process.env.PW_TEST_CONNECT_WS_ENDPOINT;
const isZoo = !!process.env.ZOO_ENV || isSidecar;
export default defineConfig({
testDir: './tests/playwright',
forbidOnly: isCI,
retries: isCI ? 2 : 0,
timeout: 30 * 1000,
reporter: [
['list'],
['html', { outputFolder: 'tests/playwright/reports/html' }],
['json', { outputFile: 'tests/playwright/reports/results.json' }],
['junit', { outputFile: 'tests/playwright/reports/results.xml' }],
],
use: {
// Auto-detects base URL based on environment
baseURL: isSidecar ? 'https://farfalla.localhost' : 'http://localhost:8000',
ignoreHTTPSErrors: isZoo,
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'retain-on-failure',
},
projects: [
{
name: 'chromium-desktop',
use: {
...devices['Desktop Chrome'],
viewport: { width: 1280, height: 720 },
// Zoo-specific browser args (applied automatically in Zoo)
...(isZoo && {
launchOptions: {
args: ['--host-resolver-rules=MAP *.localhost 172.31.0.20'],
},
}),
},
},
{
name: 'mobile-chrome',
use: {
...devices['Pixel 5'],
viewport: { width: 375, height: 812 },
...(isZoo && {
launchOptions: {
args: ['--host-resolver-rules=MAP *.localhost 172.31.0.20'],
},
}),
},
},
],
// Only start web server when running locally (not in Zoo sidecar mode)
...(isSidecar || isCI
? {}
: {
webServer: {
command: 'php artisan serve',
url: 'http://localhost:8000',
reuseExistingServer: true,
timeout: 120 * 1000,
},
}),
});
Example Test Files​
Testing Farfalla Platform​
// tests/playwright/farfalla.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Farfalla Platform', () => {
test('should load login page', async ({ page }) => {
await page.goto('https://farfalla.localhost/login');
await expect(page.locator('h1')).toContainText('Login');
});
test('should handle authentication', async ({ page }) => {
await page.goto('https://farfalla.localhost/login');
await page.fill('[name="email"]', 'test@example.com');
await page.fill('[name="password"]', 'password');
await page.click('button[type="submit"]');
// Assert successful login...
});
});
Testing Multiple Domains​
// tests/playwright/cross-domain.spec.ts
import { test, expect } from '@playwright/test';
const domains = [
{ name: 'Farfalla', url: 'https://farfalla.localhost' },
{ name: 'Volpe', url: 'https://volpe.localhost' },
{ name: 'Minio', url: 'https://minio.localhost' },
];
domains.forEach(({ name, url }) => {
test(`${name} should be accessible`, async ({ page }) => {
await page.goto(url);
await expect(page).toHaveTitle(/.+/); // Should have some title
});
});
Page Object Model Example​
// tests/playwright/pages/FarfallaLoginPage.ts
import { Page, expect } from '@playwright/test';
export class FarfallaLoginPage {
constructor(private page: Page) {}
async goto() {
await this.page.goto('https://farfalla.localhost/login');
}
async login(email: string, password: string) {
await this.page.fill('[name="email"]', email);
await this.page.fill('[name="password"]', password);
await this.page.click('button[type="submit"]');
}
async expectLoginSuccess() {
await expect(this.page).toHaveURL(/dashboard/);
}
}
// Usage in test
test('user login flow', async ({ page }) => {
const loginPage = new FarfallaLoginPage(page);
await loginPage.goto();
await loginPage.login('test@example.com', 'password');
await loginPage.expectLoginSuccess();
});
Running Tests​
From Criceto Directory​
# Run all Playwright tests
zet
# Run Playwright tests specifically
zex npx playwright test
# Run with UI mode for debugging
zex npx playwright test --ui
# Run specific test file
zex npx playwright test tests/playwright/farfalla.spec.ts
# Run with debug mode
zex npx playwright test --debug
Test Organization​
criceto/
├── tests/
│ └── playwright/
│ ├── specs/
│ │ ├── farfalla/
│ │ │ ├── auth.spec.ts
│ │ │ ├── storefront.spec.ts
│ │ │ └── admin.spec.ts
│ │ ├── volpe/
│ │ │ ├── reader.spec.ts
│ │ │ └── annotations.spec.ts
│ │ └── cross-platform/
│ │ ├── integration.spec.ts
│ │ └── workflows.spec.ts
│ ├── pages/
│ │ ├── FarfallaLoginPage.ts
│ │ ├── StorefrontPage.ts
│ │ └── ReaderPage.ts
│ ├── utils/
│ │ ├── test-data.ts
│ │ └── helpers.ts
│ └── reports/
│ ├── html/
│ ├── results.json
│ └── results.xml
└── playwright.config.js
Troubleshooting​
Common Issues​
-
Tests fail with "net::ERR_CONNECTION_REFUSED"
- ✅ Ensure nginx container is running:
./zoo/zoo.sh status - ✅ Check target service is running (farfalla, volpe, etc.)
- ✅ Ensure nginx container is running:
-
Tests fail with "net::ERR_ADDRESS_UNREACHABLE"
- ✅ Ensure Playwright container is running
- ✅ Restart containers:
./zoo/zoo.sh restart playwright criceto
-
Version mismatch errors
- ✅ All components should use Playwright v1.53.2
- ✅ Update package.json and run
zex npm install
-
DNS resolution issues
- ✅ Playwright container auto-configures all domain mappings
- ✅ Restart if needed:
./zoo/zoo.sh restart playwright
Debug Commands​
# Check Zoo container status
./zoo/zoo.sh status
# View Playwright container logs
docker logs playwright
# Test basic connectivity
zex npx playwright test --reporter=verbose
# Check if domains are accessible
curl -k -I https://farfalla.localhost
Environment Variables​
When running in Zoo, these are automatically set for all containers:
ZOO_ENV=true- Automatically set for ALL services - Identifies Zoo environment
For services that use Playwright (Volpe, Criceto):
PW_TEST_CONNECT_WS_ENDPOINT=ws://playwright:3000- Enables sidecar modeNODE_TLS_REJECT_UNAUTHORIZED=0- Allows self-signed certificates (Playwright container)
Integration with CI/CD​
The same Playwright configuration works in:
- ✅ Local Zoo Environment: Uses sidecar mode
- ✅ GitLab CI: Uses direct container execution
- ✅ Development: Can fallback to local server mode
No code changes needed - environment detection is automatic!
Next Steps for Criceto Team​
- Create
playwright.config.jswith the configuration above - Set up test directory structure (
tests/playwright/) - Write first test targeting a specific platform domain
- Run tests:
cd criceto && zet - Iterate and expand test coverage across domains
Support​
For issues or questions about the Playwright Zoo setup:
- Check container status:
./zoo/zoo.sh status - View logs:
docker logs playwright - Restart if needed:
./zoo/zoo.sh restart playwright criceto nginx
Ready to test all platform domains! 🚀