fix public example IPs for mirror prep
Use 10.255.255.1 (private, non-homelab) instead of invalid 10.0.10.x.
This commit is contained in:
+1
-1
@@ -6,7 +6,7 @@ PLAYKIT_ENV=dev
|
|||||||
PLAYKIT_LOG_LEVEL=info
|
PLAYKIT_LOG_LEVEL=info
|
||||||
PLAYKIT_FORBID_PRIVATE_HOSTS=true
|
PLAYKIT_FORBID_PRIVATE_HOSTS=true
|
||||||
# PLAYKIT_METRICS_ENABLED=true
|
# PLAYKIT_METRICS_ENABLED=true
|
||||||
# PLAYKIT_PUSHGATEWAY_URL=http://10.0.10.x:9091
|
# PLAYKIT_PUSHGATEWAY_URL=http://10.255.255.1:9091
|
||||||
|
|
||||||
# Mailtrap Email Testing (Sandbox) — emails only appear if app SMTP → sandbox.smtp.mailtrap.io
|
# Mailtrap Email Testing (Sandbox) — emails only appear if app SMTP → sandbox.smtp.mailtrap.io
|
||||||
# PLAYKIT_MAILTRAP_API_TOKEN=
|
# PLAYKIT_MAILTRAP_API_TOKEN=
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ test('sign-out stays on public host', async ({ page, playkitConfig, timings }) =
|
|||||||
| `PLAYKIT_PROJECT` | no | Metric / log label |
|
| `PLAYKIT_PROJECT` | no | Metric / log label |
|
||||||
| `PLAYKIT_ENV` | no | Metric / log label (`dev`/`qa`/`prod`) |
|
| `PLAYKIT_ENV` | no | Metric / log label (`dev`/`qa`/`prod`) |
|
||||||
| `PLAYKIT_METRICS_ENABLED` | no | Push timings to Pushgateway |
|
| `PLAYKIT_METRICS_ENABLED` | no | Push timings to Pushgateway |
|
||||||
| `PLAYKIT_PUSHGATEWAY_URL` | if metrics | e.g. `http://10.0.10.x:9091` |
|
| `PLAYKIT_PUSHGATEWAY_URL` | if metrics | e.g. `http://10.255.255.1:9091` |
|
||||||
| `PLAYKIT_LOG_LEVEL` | no | `debug` \| `info` \| `warn` \| `error` |
|
| `PLAYKIT_LOG_LEVEL` | no | `debug` \| `info` \| `warn` \| `error` |
|
||||||
|
|
||||||
**Secrets:** put test credentials and pushgateway tokens in Infisical (`LevkinOps`) and sync into Gitea Actions — see ansible `docs/hardening/SECRETS.md`. Never commit passwords.
|
**Secrets:** put test credentials and pushgateway tokens in Infisical (`LevkinOps`) and sync into Gitea Actions — see ansible `docs/hardening/SECRETS.md`. Never commit passwords.
|
||||||
@@ -166,7 +166,7 @@ await runPersistentSession({
|
|||||||
|
|
||||||
`createMailInbox()` picks the provider from `PLAYKIT_MAIL_PROVIDER` (default
|
`createMailInbox()` picks the provider from `PLAYKIT_MAIL_PROVIDER` (default
|
||||||
`mailpit`) so specs don't need to know which backend is behind it. Prefer
|
`mailpit`) so specs don't need to know which backend is behind it. Prefer
|
||||||
**Mailpit** — it's our homelab SMTP trap (`10.0.10.x`, no external
|
**Mailpit** — it's our homelab SMTP trap (`10.255.255.1`, no external
|
||||||
dependency); use Mailtrap only if you specifically want the SaaS sandbox.
|
dependency); use Mailtrap only if you specifically want the SaaS sandbox.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
@@ -184,7 +184,7 @@ assertPublicHost(link!);
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Important:** the mail client only sees mail if the app's SMTP actually
|
**Important:** the mail client only sees mail if the app's SMTP actually
|
||||||
points at that trap (Mailpit `10.0.10.x:1025` in DEV, or Mailtrap's
|
points at that trap (Mailpit `10.255.255.1:1025` in DEV, or Mailtrap's
|
||||||
`sandbox.smtp.mailtrap.io` + inbox credentials for SaaS). Sending via Gmail to
|
`sandbox.smtp.mailtrap.io` + inbox credentials for SaaS). Sending via Gmail to
|
||||||
a real address will not appear in either. See ansible `docs/hardening/SECRETS.md`
|
a real address will not appear in either. See ansible `docs/hardening/SECRETS.md`
|
||||||
(`## Playkit / punimtag e2e secrets`).
|
(`## Playkit / punimtag e2e secrets`).
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ Store in Infisical `LevkinOps` / `Development` (path e.g. `/playkit/punimtag`):
|
|||||||
|
|
||||||
- `PLAYKIT_BASE_URL=https://punimtagdev.levkin.ca`
|
- `PLAYKIT_BASE_URL=https://punimtagdev.levkin.ca`
|
||||||
- `E2E_ADMIN_EMAIL` / `E2E_ADMIN_PASSWORD` (dedicated test user — not a human’s password)
|
- `E2E_ADMIN_EMAIL` / `E2E_ADMIN_PASSWORD` (dedicated test user — not a human’s password)
|
||||||
- optional `PLAYKIT_PUSHGATEWAY_URL=http://10.0.10.x:9091`
|
- optional `PLAYKIT_PUSHGATEWAY_URL=http://10.255.255.1:9091`
|
||||||
- optional `PLAYKIT_RETRY_PRESET=strictCi|flakyNetwork|default`
|
- optional `PLAYKIT_RETRY_PRESET=strictCi|flakyNetwork|default`
|
||||||
- for mail specs: `PLAYKIT_MAIL_PROVIDER=mailpit` (default) + `MAILPIT_*`, or `MAILTRAP_*`
|
- for mail specs: `PLAYKIT_MAIL_PROVIDER=mailpit` (default) + `MAILPIT_*`, or `MAILTRAP_*`
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ Living ops/status after releases. Update when an item closes.
|
|||||||
|
|
||||||
| Item | Status |
|
| Item | Status |
|
||||||
|------|--------|
|
|------|--------|
|
||||||
| Pushgateway + `live-playkit` Grafana board | Applied (`10.0.10.x:9091`) |
|
| Pushgateway + `live-playkit` Grafana board | Applied (`10.255.255.1:9091`) |
|
||||||
| Tag release workflow + `RELEASE_TOKEN` | Working (`v0.3.1`, `v0.4.0` Gitea releases) |
|
| Tag release workflow + `RELEASE_TOKEN` | Working (`v0.3.1`, `v0.4.0` Gitea releases) |
|
||||||
| Selftest CI | Green (Playwright image pinned to package version) |
|
| Selftest CI | Green (Playwright image pinned to package version) |
|
||||||
| Outline **QA & Dev → Playkit** @ v0.4.0 | Synced via API 2026-07-15 → https://notes.levkin.ca/doc/playkit-CrPJq5x2qQ |
|
| Outline **QA & Dev → Playkit** @ v0.4.0 | Synced via API 2026-07-15 → https://notes.levkin.ca/doc/playkit-CrPJq5x2qQ |
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Example UI pattern (not executed in kit CI — consumers own Playwright projects).
|
* Example UI pattern (not executed in kit CI — consumers own Playwright projects).
|
||||||
*
|
*
|
||||||
* Critical assert: after sign-out, URL host must remain the public host.
|
* Critical assert: after sign-out, URL host must remain the public host.
|
||||||
* This is the failure mode from punimtag #57 (redirect to 10.0.10.x:3001).
|
* This is the failure mode from punimtag #57 (redirect to 10.255.255.1:3001).
|
||||||
*/
|
*/
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import { loadConfig, waitForUrlHost, assertPublicHost, TimingCollector } from '../../src/index.js';
|
import { loadConfig, waitForUrlHost, assertPublicHost, TimingCollector } from '../../src/index.js';
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ def playkit_markdown(version: str) -> str:
|
|||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
|
||||||
- Pushgateway: `http://10.0.10.x:9091` (LAN)
|
- Pushgateway: `http://10.255.255.1:9091` (LAN)
|
||||||
- Grafana: `dash.levkin.ca` → **Live — Playkit e2e** (`live-playkit`)
|
- Grafana: `dash.levkin.ca` → **Live — Playkit e2e** (`live-playkit`)
|
||||||
- Enable in CI with `PLAYKIT_METRICS_ENABLED=true` + `PLAYKIT_PUSHGATEWAY_URL`
|
- Enable in CI with `PLAYKIT_METRICS_ENABLED=true` + `PLAYKIT_PUSHGATEWAY_URL`
|
||||||
|
|
||||||
|
|||||||
@@ -101,10 +101,10 @@ describe('waitForUrlHost', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('throws a descriptive error naming both hosts when the host never matches', async () => {
|
it('throws a descriptive error naming both hosts when the host never matches', async () => {
|
||||||
const page = { url: () => 'http://10.0.10.x:3000/dashboard' } as unknown as Page;
|
const page = { url: () => 'http://10.255.255.1:3000/dashboard' } as unknown as Page;
|
||||||
await expect(
|
await expect(
|
||||||
waitForUrlHost(page, 'app.levkin.ca', { timeout: 0, logger: silentLogger }),
|
waitForUrlHost(page, 'app.levkin.ca', { timeout: 0, logger: silentLogger }),
|
||||||
).rejects.toThrow(/Expected URL host "app\.levkin\.ca" but got "10\.0\.10\.45"/);
|
).rejects.toThrow(/Expected URL host "app\.levkin\.ca" but got "10\.255\.255\.1"/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ describe('assertPublicHost', () => {
|
|||||||
expect(() => assertPublicHost('punimtagdev.levkin.ca')).not.toThrow();
|
expect(() => assertPublicHost('punimtagdev.levkin.ca')).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each(['https://10.0.10.x:3000', 'http://localhost:3000', 'https://192.168.1.10', '127.0.0.1'])(
|
it.each(['https://10.255.255.1:3000', 'http://localhost:3000', 'https://192.168.1.10', '127.0.0.1'])(
|
||||||
'rejects private host %s',
|
'rejects private host %s',
|
||||||
(input) => {
|
(input) => {
|
||||||
expect(() => assertPublicHost(input)).toThrow(/Refusing private host/);
|
expect(() => assertPublicHost(input)).toThrow(/Refusing private host/);
|
||||||
@@ -122,7 +122,7 @@ describe('assertPublicHost', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
it('allows private hosts when forbidPrivate is false (intentional LAN runs)', () => {
|
it('allows private hosts when forbidPrivate is false (intentional LAN runs)', () => {
|
||||||
expect(() => assertPublicHost('http://10.0.10.x:3000', false)).not.toThrow();
|
expect(() => assertPublicHost('http://10.255.255.1:3000', false)).not.toThrow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { TimingCollector } from '../metrics/index.js';
|
|||||||
|
|
||||||
describe('isPrivateHost', () => {
|
describe('isPrivateHost', () => {
|
||||||
it('detects LAN and localhost', () => {
|
it('detects LAN and localhost', () => {
|
||||||
expect(isPrivateHost('10.0.10.x')).toBe(true);
|
expect(isPrivateHost('10.255.255.1')).toBe(true);
|
||||||
expect(isPrivateHost('192.168.1.1')).toBe(true);
|
expect(isPrivateHost('192.168.1.1')).toBe(true);
|
||||||
expect(isPrivateHost('172.16.0.2')).toBe(true);
|
expect(isPrivateHost('172.16.0.2')).toBe(true);
|
||||||
expect(isPrivateHost('localhost')).toBe(true);
|
expect(isPrivateHost('localhost')).toBe(true);
|
||||||
@@ -21,7 +21,7 @@ describe('loadConfig', () => {
|
|||||||
it('rejects private expected host by default', () => {
|
it('rejects private expected host by default', () => {
|
||||||
expect(() =>
|
expect(() =>
|
||||||
loadConfig({
|
loadConfig({
|
||||||
PLAYKIT_BASE_URL: 'http://10.0.10.x:3001',
|
PLAYKIT_BASE_URL: 'http://10.255.255.1:3001',
|
||||||
}),
|
}),
|
||||||
).toThrow(/private/);
|
).toThrow(/private/);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ describe('loadMailpitConfig', () => {
|
|||||||
it('loads base url and auth', () => {
|
it('loads base url and auth', () => {
|
||||||
expect(
|
expect(
|
||||||
loadMailpitConfig({
|
loadMailpitConfig({
|
||||||
MAILPIT_BASE_URL: 'http://10.0.10.x:8025',
|
MAILPIT_BASE_URL: 'http://10.255.255.1:8025',
|
||||||
MAILPIT_USER: 'u',
|
MAILPIT_USER: 'u',
|
||||||
MAILPIT_PASSWORD: 'p',
|
MAILPIT_PASSWORD: 'p',
|
||||||
}),
|
}),
|
||||||
).toEqual({
|
).toEqual({
|
||||||
baseUrl: 'http://10.0.10.x:8025',
|
baseUrl: 'http://10.255.255.1:8025',
|
||||||
user: 'u',
|
user: 'u',
|
||||||
password: 'p',
|
password: 'p',
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-1
@@ -49,7 +49,7 @@ function matchesSubject(subject: string, want?: string | RegExp): boolean {
|
|||||||
* Load Mailpit config from env. Returns null if MAILPIT_BASE_URL unset.
|
* Load Mailpit config from env. Returns null if MAILPIT_BASE_URL unset.
|
||||||
*
|
*
|
||||||
* Env:
|
* Env:
|
||||||
* - PLAYKIT_MAILPIT_BASE_URL / MAILPIT_BASE_URL (e.g. http://10.0.10.x:8025)
|
* - PLAYKIT_MAILPIT_BASE_URL / MAILPIT_BASE_URL (e.g. http://10.255.255.1:8025)
|
||||||
* - MAILPIT_USER / MAILPIT_PASSWORD (basic auth)
|
* - MAILPIT_USER / MAILPIT_PASSWORD (basic auth)
|
||||||
*/
|
*/
|
||||||
export function loadMailpitConfig(env: NodeJS.ProcessEnv = process.env): MailpitConfig | null {
|
export function loadMailpitConfig(env: NodeJS.ProcessEnv = process.env): MailpitConfig | null {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export interface MetricsPushOptions {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Push metrics to a Prometheus Pushgateway.
|
* Push metrics to a Prometheus Pushgateway.
|
||||||
* Example URL: http://10.0.10.x:9091
|
* Example URL: http://10.255.255.1:9091
|
||||||
*/
|
*/
|
||||||
export async function pushPrometheusMetrics(
|
export async function pushPrometheusMetrics(
|
||||||
collector: TimingCollector,
|
collector: TimingCollector,
|
||||||
|
|||||||
Reference in New Issue
Block a user