Socket
Socket
Sign inDemoInstall

puppeteer-interceptor

Package Overview
Dependencies
4
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.0 to 2.0.0

15

dist/src/index.d.ts
import Protocol from 'devtools-protocol';
import { Page } from 'puppeteer/lib/Page';
import { Page, CDPSession } from 'puppeteer';
export * from './types';

@@ -28,2 +28,13 @@ export * from './request-patterns';

}
export declare function intercept(page: Page, patterns?: Protocol.Fetch.RequestPattern[], eventHandlers?: Interceptor.EventHandlers): Promise<void>;
export declare class InterceptionHandler {
page: Page;
patterns: Protocol.Fetch.RequestPattern[];
eventHandlers: Interceptor.EventHandlers;
client?: CDPSession;
disabled: boolean;
constructor(page: Page, patterns?: Protocol.Fetch.RequestPattern[], eventHandlers?: Interceptor.EventHandlers);
disable(): void;
enable(): void;
initialize(): Promise<void>;
}
export declare function intercept(page: Page, patterns?: Protocol.Fetch.RequestPattern[], eventHandlers?: Interceptor.EventHandlers): Promise<InterceptionHandler>;

129

dist/src/index.js

@@ -16,3 +16,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.intercept = void 0;
exports.intercept = exports.InterceptionHandler = void 0;
const atob_1 = __importDefault(require("atob"));

@@ -24,59 +24,86 @@ const btoa_1 = __importDefault(require("btoa"));

__exportStar(require("./request-patterns"), exports);
async function intercept(page, patterns = [], eventHandlers = {}) {
debug(`Registering interceptors for ${patterns.length} patterns`);
const client = await page.target().createCDPSession();
await client.send('Fetch.enable', { patterns });
client.on('Fetch.requestPaused', async (event) => {
const { requestId, request } = event;
debug(`Request ${event.request.url} (${requestId}) paused.`);
if (eventHandlers.onInterception) {
let errorReason = 'Aborted';
let shouldContinue = true;
const control = {
abort: (msg) => {
shouldContinue = false;
errorReason = msg;
},
};
await eventHandlers.onInterception(event, control);
if (!shouldContinue) {
debug(`Aborting request ${requestId} with reason "${errorReason}"`);
await client.send('Fetch.failRequest', { requestId, errorReason });
class InterceptionHandler {
constructor(page, patterns = [], eventHandlers = {}) {
this.patterns = [];
this.eventHandlers = {};
this.disabled = false;
this.page = page;
this.patterns = patterns;
this.eventHandlers = eventHandlers;
}
disable() {
this.disabled = true;
}
enable() {
this.disabled = false;
}
async initialize() {
this.client = await this.page.target().createCDPSession();
await this.client.send('Fetch.enable', { patterns: this.patterns });
this.client.on('Fetch.requestPaused', async (event) => {
const { requestId, request } = event;
if (this.disabled) {
debug(`Interception handler disabled, continuing request.`);
await this.client.send('Fetch.continueRequest', { requestId });
return;
}
}
let newResponse = null;
if (eventHandlers.onResponseReceived) {
if (!event.responseStatusCode) {
debug(`Warning: onResponseReceived handler passed but ${requestId} intercepted at Request stage. Handler can not be called.`);
debug(`Request ${event.request.url} (${requestId}) paused.`);
if (this.eventHandlers.onInterception) {
let errorReason = 'Aborted';
let shouldContinue = true;
const control = {
abort: (msg) => {
shouldContinue = false;
errorReason = msg;
},
};
await this.eventHandlers.onInterception(event, control);
if (!shouldContinue) {
debug(`Aborting request ${requestId} with reason "${errorReason}"`);
await this.client.send('Fetch.failRequest', { requestId, errorReason });
return;
}
}
else {
const responseCdp = (await client.send('Fetch.getResponseBody', {
let newResponse = null;
if (this.eventHandlers.onResponseReceived) {
if (!event.responseStatusCode) {
debug(`Warning: onResponseReceived handler passed but ${requestId} intercepted at Request stage. Handler can not be called.`);
}
else {
const responseCdp = (await this.client.send('Fetch.getResponseBody', {
requestId,
}));
const response = {
body: responseCdp.base64Encoded ? atob_1.default(responseCdp.body) : responseCdp.body,
headers: event.responseHeaders,
errorReason: event.responseErrorReason,
statusCode: event.responseStatusCode,
};
newResponse = await this.eventHandlers.onResponseReceived({ response, request });
}
}
if (newResponse) {
debug(`Fulfilling request ${requestId} with response returned from onResponseReceived`);
await this.client.send('Fetch.fulfillRequest', {
requestId,
}));
const response = {
body: responseCdp.base64Encoded ? atob_1.default(responseCdp.body) : responseCdp.body,
headers: event.responseHeaders,
errorReason: event.responseErrorReason,
statusCode: event.responseStatusCode,
};
newResponse = await eventHandlers.onResponseReceived({ response, request });
responseCode: newResponse.statusCode,
responseHeaders: newResponse.headers,
body: newResponse.base64Body ? newResponse.base64Body : btoa_1.default(newResponse.body),
responsePhrase: newResponse.statusMessage,
});
}
}
if (newResponse) {
debug(`Fulfilling request ${requestId} with response returned from onResponseReceived`);
await client.send('Fetch.fulfillRequest', {
requestId,
responseCode: newResponse.statusCode,
responseHeaders: newResponse.headers,
body: newResponse.base64Body ? newResponse.base64Body : btoa_1.default(newResponse.body),
responsePhrase: newResponse.statusMessage,
});
}
else {
await client.send('Fetch.continueRequest', { requestId });
}
});
else {
await this.client.send('Fetch.continueRequest', { requestId });
}
});
}
}
exports.InterceptionHandler = InterceptionHandler;
async function intercept(page, patterns = [], eventHandlers = {}) {
debug(`Registering interceptors for ${patterns.length} patterns`);
const interceptionHandler = new InterceptionHandler(page, patterns, eventHandlers);
await interceptionHandler.initialize();
return interceptionHandler;
}
exports.intercept = intercept;
//# sourceMappingURL=index.js.map

@@ -6,15 +6,12 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const puppeteer_1 = __importDefault(require("puppeteer"));
const src_1 = require("../src");
const assert_1 = __importDefault(require("assert"));
const puppeteer_1 = __importDefault(require("puppeteer"));
const server_1 = require("./server");
const test_server_1 = require("@jsoverson/test-server");
describe('interceptor', function () {
let browser, context, page;
const port = 5599;
let baseUrl = `http://127.0.0.1:${port}/`;
before((done) => {
puppeteer_1.default.launch().then((b) => {
browser = b;
server_1.start(port, done);
});
let server;
before(async () => {
browser = await puppeteer_1.default.launch({ headless: true });
server = await test_server_1.start(__dirname, 'server_root');
});

@@ -28,7 +25,8 @@ beforeEach(async () => {

});
after((done) => {
browser.close().then((_) => server_1.stop(done));
after(async () => {
await browser.close();
await server.stop();
});
it('should not cause problems on the page', async function () {
await page.goto(baseUrl, {});
await page.goto(server.url('index.html'), {});
src_1.intercept(page, src_1.patterns.All('*'));

@@ -50,5 +48,39 @@ const title = await page.title();

});
await page.goto(baseUrl, {});
await page.goto(server.url('index.html'), {});
return promise;
});
it('should support adding multiple, unique interceptors', async function () {
let dynamicIntercepted = 0;
let consoleIntercepted = 0;
src_1.intercept(page, src_1.patterns.Script('*dynamic.js'), {
onResponseReceived: () => {
dynamicIntercepted++;
},
});
src_1.intercept(page, src_1.patterns.Script('*console.js'), {
onResponseReceived: () => {
consoleIntercepted++;
},
});
await page.setCacheEnabled(false);
await page.goto(server.url('index.html'), {});
assert_1.default.equal(dynamicIntercepted, 1);
assert_1.default.equal(consoleIntercepted, 1);
});
it('should support removing interceptions', async function () {
let timesCalled = 0;
const pattern = src_1.patterns.Script('*dynamic.js');
const handlers = {
onResponseReceived: () => {
timesCalled++;
},
};
const handler = await src_1.intercept(page, pattern, handlers);
await page.setCacheEnabled(false);
await page.goto(server.url('index.html'), {});
assert_1.default.equal(timesCalled, 1);
handler.disable();
await page.goto(server.url('index.html'), {});
assert_1.default.equal(timesCalled, 1);
});
it('should pass response to onResponseReceived', async function () {

@@ -63,3 +95,3 @@ const promise = new Promise((resolve, reject) => {

});
await page.goto(baseUrl, {});
await page.goto(server.url('index.html'), {});
return promise;

@@ -74,3 +106,3 @@ });

});
await page.goto(baseUrl, {});
await page.goto(server.url('index.html'), {});
const dynamicHeader = await page.$('#dynamic');

@@ -83,3 +115,5 @@ const dynamicContents = await page.evaluate((header) => header.innerHTML, dynamicHeader);

onResponseReceived: async (event) => {
const value = await new Promise((resolve) => { setTimeout(() => resolve('Delayed'), 100); });
const value = await new Promise((resolve) => {
setTimeout(() => resolve('Delayed'), 100);
});
event.response.body = event.response.body.replace('Dynamic', value);

@@ -89,3 +123,3 @@ return event.response;

});
await page.goto(baseUrl, {});
await page.goto(server.url('index.html'), {});
const dynamicHeader = await page.$('#dynamic');

@@ -102,3 +136,3 @@ const dynamicContents = await page.evaluate((header) => header.innerHTML, dynamicHeader);

});
await page.goto(baseUrl, {});
await page.goto(server.url('index.html'), {});
const dynamicHeader = await page.$('#dynamic');

@@ -105,0 +139,0 @@ const dynamicContents = await page.evaluate((header) => header.innerHTML, dynamicHeader);

{
"name": "puppeteer-interceptor",
"version": "1.1.0",
"version": "2.0.0",
"description": "Makes intercepting and modifying traffic from Puppeteer easier",

@@ -8,6 +8,5 @@ "main": "dist/src/index.js",

"scripts": {
"build": "tsc",
"compile": "npm run clean && tsc --declaration",
"build": "npm run clean && tsc --declaration",
"clean": "rm -rf dist",
"prepublishOnly": "npm run compile",
"prepublishOnly": "npm run build",
"format": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",

@@ -38,2 +37,3 @@ "watch": "tsc -w",

"devDependencies": {
"@jsoverson/test-server": "^1.1.1",
"@types/atob": "^2.1.2",

@@ -47,3 +47,3 @@ "@types/btoa": "^1.2.3",

"prettier": "^2.0.5",
"puppeteer": "^4.0.0",
"puppeteer": "^5.1.0",
"serve": "^11.3.0",

@@ -50,0 +50,0 @@ "serve-handler": "^6.1.2",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc