mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-01 14:34:42 +01:00
test(browse): daemon-state and refusal e2e for the explicit direct opt-out; headed env and BROWSER.md contract checks (#3440 item 8)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
cadf2bcb92
commit
c08c586bbd
4 files changed
+60
-2
No files matched your search
@@ -146,7 +146,7 @@ jobs:
|
||||
resolved="$(realpath "$tmp")"
|
||||
echo "temp root: $tmp -> $resolved"
|
||||
test "$resolved" != "${tmp%/}"
|
||||
files=(test/gstack-design-detect.test.ts browse/test/chromium-profile-isolation.test.ts test/cso-git-hardening.test.ts test/plan-count-file-permission.test.ts test/spec-quality-gate-secret-sink.test.ts test/gstack-memory-ingest.test.ts test/regression-issue3024-zsh-sourced-helpers.test.ts test/codex-probe-subcommands.test.ts)
|
||||
files=(test/gstack-design-detect.test.ts browse/test/chromium-profile-isolation.test.ts test/cso-git-hardening.test.ts test/plan-count-file-permission.test.ts test/spec-quality-gate-secret-sink.test.ts test/gstack-memory-ingest.test.ts test/regression-issue3024-zsh-sourced-helpers.test.ts test/codex-probe-subcommands.test.ts browse/test/proxy-env-daemon.test.ts)
|
||||
for file in "${files[@]}"; do test -f "$file"; done
|
||||
bun test "${files[@]}"
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
- `browse/test/proxy-direct-launch-paths.test.ts` (Linux, real Chromium under Xvfb): the `BROWSE_EXTENSIONS_DIR` persistent context, `launchHeaded()` and the `handoff()` relaunch each ignore an inherited `HTTPS_PROXY` (no CONNECT, `ERR_NAME_NOT_RESOLVED`), and a headed control with a configured proxy still sends the CONNECT to it.
|
||||
- `browse/test/proxy-config.test.ts`: `forcesDirect` per platform, and `directProxyLogLine` for the Linux variable list, the explicit-direct line on macOS/Windows, and the system-proxy line.
|
||||
- `browse/test/proxy-env.test.ts`, `browse/test/restart-env.test.ts`: the config hash separates an explicit direct from no proxy on macOS and Windows and not on Linux (`extractGlobalFlags` takes the platform); the mismatch refusal for both directions (explicit session against a system-proxy daemon, default session against an explicit-direct daemon); `buildRestartEnv` re-emits `BROWSE_PROXY_URL=direct` from the invocation or the persisted state, and a proxied invocation wins over it.
|
||||
- `browse/test/proxy-env-daemon.test.ts`: through the real CLI and daemon, `BROWSE_PROXY_URL=direct` is written to the daemon state as `proxyDirect` where it bypasses the system proxy and a default session is then refused with the `BROWSE_PROXY_URL differs` lines; on Linux the daemon is reused. The file joins the macOS named-regressions CI job so the refusal arm runs there. `buildHeadedServerEnv` carries the opt-out to the headed server, and BROWSER.md's section is checked against the real switch and log literals.
|
||||
- `browse/test/proxy-direct-launch-args.test.ts`: reads the real command line of the headless Chromium `BrowserManager` launched (from the pid it records) and asserts the switch is present on Linux and absent elsewhere without an opt-out, and present on every platform with `BROWSE_PROXY_URL=direct`; the per-platform expectations are written out, not read back from `forcesDirect`. Skipped on Windows, where no command line reader exists.
|
||||
|
||||
## [1.91.226.0] - 2026-10-26
|
||||
|
||||
@@ -134,4 +134,35 @@ describe.skipIf(process.platform === 'win32')('#915 proxy from the environment,
|
||||
expect(proxiedHosts.length).toBe(before);
|
||||
expect(JSON.parse(fs.readFileSync(stateFile, 'utf8')).proxy).toBeUndefined();
|
||||
}, 120_000);
|
||||
|
||||
// Added by: /ship test coverage audit (Capy), 2026-10-25, for #3440 item 8.
|
||||
// Value: protects=the daemon state records BROWSE_PROXY_URL=direct where it bypasses the system proxy settings, and a default session there is refused, not handed the opt-out;
|
||||
// fails_when=server.ts drops proxyDirect from the state, the CLI hash stops carrying the opt-out, or Linux starts refusing a reused daemon over it;
|
||||
// why_new=proxy-env.test.ts drives proxyMismatchLines with a hand-built state; nothing reads the state the daemon wrote or runs the refusal through the CLI;
|
||||
// seam=none; no_claim=Chromium's proxy behaviour (loopback page only); the proxyDirect=true write and the refusal arm run on the macOS named-regressions CI job and on a Windows checkout, the Linux lanes run the reuse arm
|
||||
test('BROWSE_PROXY_URL=direct is daemon state where it bypasses the system proxy, and a default session is refused there (#3440)', async () => {
|
||||
expect((await browse(['stop'], {})).code).toBe(0);
|
||||
const r = await browse(['goto', `http://127.0.0.1:${direct.port}/`], { BROWSE_PROXY_URL: 'direct' });
|
||||
expect(r.code, r.out).toBe(0);
|
||||
expect(r.stderr).toContain('Starting server...');
|
||||
const pid = daemonPid();
|
||||
const bypassesSystemProxy = process.platform !== 'linux';
|
||||
const state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
|
||||
expect(state.proxy).toBeUndefined();
|
||||
if (bypassesSystemProxy) expect(state.proxyDirect).toBe(true);
|
||||
else expect(state.proxyDirect).toBeUndefined();
|
||||
const plain = await browse(['text'], {});
|
||||
if (bypassesSystemProxy) {
|
||||
expect(plain.code).toBe(1);
|
||||
expect(plain.stderr).toContain('different proxy settings (BROWSE_PROXY_URL differs)');
|
||||
expect(plain.stderr).toContain('daemon: no proxy (BROWSE_PROXY_URL=direct)');
|
||||
expect(plain.stderr).toContain('session: no proxy');
|
||||
expect(plain.stderr).toContain('or set BROWSE_PROXY_URL=direct to use the running daemon without a proxy');
|
||||
} else {
|
||||
expect(plain.code, plain.out).toBe(0);
|
||||
expect(plain.stderr).not.toContain('Starting server');
|
||||
expect(plain.stdout).toContain('direct loopback page');
|
||||
}
|
||||
expect(daemonPid()).toBe(pid);
|
||||
}, 120_000);
|
||||
});
|
||||
@@ -3,7 +3,7 @@
|
||||
* mismatch refusal. The daemon round trip is in proxy-env-daemon.test.ts.
|
||||
*/
|
||||
import { describe, expect, test } from 'bun:test';
|
||||
import { computeConfigHash, noProxyToChromiumRules, parseProxyConfig, resolveProxy, serverProxyEnv, withLoopbackBypass } from '../src/proxy-config';
|
||||
import { DIRECT_PROXY_ARG, computeConfigHash, directProxyLogLine, noProxyToChromiumRules, parseProxyConfig, resolveProxy, serverProxyEnv, withLoopbackBypass } from '../src/proxy-config';
|
||||
import { buildHeadedServerEnv, buildRestartEnv, extractGlobalFlags, proxyMismatchLines, withLoopbackNoProxy } from '../src/cli';
|
||||
|
||||
describe('resolveProxy precedence', () => {
|
||||
@@ -148,6 +148,17 @@ describe('server env carries the proxy source and bypass', () => {
|
||||
expect(buildHeadedServerEnv(flags)).toMatchObject(expected);
|
||||
expect(buildRestartEnv(extractGlobalFlags(['text'], {}), null).BROWSE_PROXY_URL).toBeUndefined();
|
||||
});
|
||||
|
||||
// Added by: /ship test coverage audit (Capy), 2026-10-25, for #3440 item 8.
|
||||
// Value: protects=a headed connect with BROWSE_PROXY_URL=direct on macOS/Windows hands its daemon the opt-out, so the headed daemon hashes and launches direct;
|
||||
// fails_when=buildHeadedServerEnv spreads only proxyUrl/source/bypass and drops explicitDirect, or proxyServerEnv stops re-emitting it;
|
||||
// why_new=restart-env.test.ts covers buildRestartEnv only and the headed case above is a proxied session; seam=none;
|
||||
// no_claim=the headed daemon's launch itself (unit: only the env it is handed; on Linux the opt-out hashes like no proxy, so the env is empty by design)
|
||||
test('a headed launch keeps BROWSE_PROXY_URL=direct where it bypasses the system proxy settings, and a --proxy still wins (#3440)', () => {
|
||||
expect(buildHeadedServerEnv(extractGlobalFlags(['connect'], { BROWSE_PROXY_URL: 'direct' }, 'darwin')).BROWSE_PROXY_URL).toBe('direct');
|
||||
expect(buildHeadedServerEnv(extractGlobalFlags(['connect'], { BROWSE_PROXY_URL: 'direct' }, 'linux')).BROWSE_PROXY_URL).toBeUndefined();
|
||||
expect(buildHeadedServerEnv(extractGlobalFlags(['connect', '--proxy', 'http://p:1'], { BROWSE_PROXY_URL: 'direct' }, 'darwin')).BROWSE_PROXY_URL).toBe('http://p:1/');
|
||||
});
|
||||
});
|
||||
|
||||
describe('serverProxyEnv (the daemon side)', () => {
|
||||
@@ -218,4 +229,19 @@ describe('BROWSER.md documents the proxy messages', () => {
|
||||
expect(section).toContain(needle);
|
||||
}
|
||||
});
|
||||
|
||||
// Added by: /ship test coverage audit (Capy), 2026-10-25, for #3440 item 8.
|
||||
// Value: protects=the section names the Chromium switch and the daemon-log line a user greps for, as the code emits them;
|
||||
// fails_when=DIRECT_PROXY_ARG or the '[proxy] none:' log prefix is renamed without BROWSER.md, or the direct-mode paragraph is dropped;
|
||||
// why_new=the #915 needles above predate the switch and the log line; seam=none;
|
||||
// no_claim=prose accuracy beyond those two literals (doc-contract check only)
|
||||
test('the direct-mode paragraph names the switch Chromium gets and the daemon-log line that records it (#3440)', async () => {
|
||||
const doc = await Bun.file(new URL('../../BROWSER.md', import.meta.url)).text();
|
||||
const section = doc.slice(doc.indexOf('\n### Proxy from environment\n'));
|
||||
expect(section).toContain(DIRECT_PROXY_ARG);
|
||||
for (const needle of ['browse-daemon.log', '[proxy] using <url> from', '[proxy] none: direct connection (', '[proxy] none: system proxy settings']) {
|
||||
expect(section).toContain(needle);
|
||||
}
|
||||
expect(directProxyLogLine({ HTTPS_PROXY: 'http://b:2' }, 'linux')).toContain('[proxy] none: direct connection (' + DIRECT_PROXY_ARG + '; ignoring HTTPS_PROXY)');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user