fix(network): reset page network emulation before applying URL restrictions (#3312)

Call emulateNetworkConditions(null) in McpPage.clearNetworkConditions()
and await it before browser.restrictNetwork() in
McpContext.syncNetworkRestrictions() so emulated offline/throttled state
(such as navigator.onLine) is cleared when URL restrictions are
hot-reloaded.

---

<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
This commit is contained in:
Nikolay Vitkov authored and GitHub committed 2026-10-22 12:12:48 +00:00
1 parent 47db2b836f
commit f25f3df2ab
4 files changed
+25 -10

No files matched your search

+5 -5
View File
@@ -251,17 +251,17 @@ export class McpContext implements Context, BrowserlessContext {
*/
async syncNetworkRestrictions(): Promise<void> {
const {blockedUrlPattern, allowedUrlPattern} = this.#config.resolved;
if (blockedUrlPattern || allowedUrlPattern) {
for (const mcpPage of this.#allMcpPages()) {
await mcpPage.clearNetworkConditions();
}
}
if (this.#browser) {
await this.#browser.restrictNetwork({
blocklist: blockedUrlPattern,
allowlist: allowedUrlPattern,
});
}
if (blockedUrlPattern || allowedUrlPattern) {
for (const mcpPage of this.#allMcpPages()) {
mcpPage.clearNetworkConditions();
}
}
}
/**
+2 -1
View File
@@ -1337,10 +1337,11 @@ export class McpPage implements ContextPage {
}
}
clearNetworkConditions(): void {
async clearNetworkConditions(): Promise<void> {
if (!this.emulationSettings.networkConditions) {
return;
}
await this.#pptrPage?.emulateNetworkConditions(null);
delete this.emulationSettings.networkConditions;
this.updateTimeouts();
}
+10 -2
View File
@@ -1747,11 +1747,15 @@ describe('McpContext', () => {
await updateConfig(config, context, {
blockedUrlPattern: ['https://blocked.example.com/*'],
});
sinon.assert.calledOnceWithExactly(clearNetworkConditionsSpy);
sinon.assert.calledOnceWithExactly(browser.restrictNetwork, {
blocklist: ['https://blocked.example.com/*'],
allowlist: undefined,
});
sinon.assert.calledOnceWithExactly(clearNetworkConditionsSpy);
sinon.assert.callOrder(
clearNetworkConditionsSpy,
browser.restrictNetwork,
);
browser.restrictNetwork.resetHistory();
clearNetworkConditionsSpy.resetHistory();
@@ -1765,11 +1769,15 @@ describe('McpContext', () => {
blockedUrlPattern: undefined,
allowedUrlPattern: ['https://allowed.example.com/*'],
});
sinon.assert.calledOnceWithExactly(clearNetworkConditionsSpy);
sinon.assert.calledOnceWithExactly(browser.restrictNetwork, {
blocklist: undefined,
allowlist: ['https://allowed.example.com/*'],
});
sinon.assert.calledOnceWithExactly(clearNetworkConditionsSpy);
sinon.assert.callOrder(
clearNetworkConditionsSpy,
browser.restrictNetwork,
);
browser.restrictNetwork.resetHistory();
clearNetworkConditionsSpy.resetHistory();
+8 -2
View File
@@ -1015,6 +1015,7 @@ describe('McpPage', () => {
networkConditions: 'Slow 3G',
cpuThrottlingRate: 2,
});
pptrPage.emulateNetworkConditions.resetHistory();
pptrPage.setDefaultTimeout.resetHistory();
pptrPage.setDefaultNavigationTimeout.resetHistory();
config.commit(
@@ -1023,10 +1024,14 @@ describe('McpPage', () => {
}),
);
mcpPage.clearNetworkConditions();
await mcpPage.clearNetworkConditions();
assert.strictEqual(mcpPage.networkConditions, null);
assert.strictEqual(mcpPage.cpuThrottlingRate, 2);
sinon.assert.calledOnceWithExactly(
pptrPage.emulateNetworkConditions,
null,
);
sinon.assert.calledOnceWithExactly(pptrPage.setDefaultTimeout, 10_000);
sinon.assert.calledOnceWithExactly(
pptrPage.setDefaultNavigationTimeout,
@@ -1040,8 +1045,9 @@ describe('McpPage', () => {
pptrPage.setDefaultTimeout.resetHistory();
pptrPage.setDefaultNavigationTimeout.resetHistory();
mcpPage.clearNetworkConditions();
await mcpPage.clearNetworkConditions();
sinon.assert.notCalled(pptrPage.emulateNetworkConditions);
sinon.assert.notCalled(pptrPage.setDefaultTimeout);
sinon.assert.notCalled(pptrPage.setDefaultNavigationTimeout);
});