Skip to content

Commit

Permalink
fix: attach requestBody, add error listener & export types (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
bardius authored Feb 10, 2024
1 parent 6bb0aa8 commit d051525
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 9 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
lib/
.idea
.history
.history
.DS_Store
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "1.0.0-beta.7",
"description": "Appium 2.0 plugin to mock api calls for android apps",
"main": "./lib/index.js",
"types": "./lib/types/index.d.ts",
"scripts": {
"build": "npx tsc",
"test": "mocha --require ts-node/register -p test/plugin.spec.js --exit --timeout 260000",
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { AppiumInterceptorPlugin } from './plugin';
export default AppiumInterceptorPlugin;
export { AppiumInterceptorPlugin };

export { type MockConfig, type SniffConfig, type RequestInfo } from './types';
12 changes: 11 additions & 1 deletion src/interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,19 @@ function RequestInterceptor(requestCompletionCallback: (value: any) => void) {
return function (ctx: IContext, callback: ErrorCallback) {
ctx.use(responseDecoder);
const requestData = {} as any;
const requestBodyDataChunks: Buffer[] = [];

// Get request body from http-mitm-proxy
// more info: https://github.com/joeferner/node-http-mitm-proxy/blob/master/README.md#proxyonrequestendfn-or-ctxonrequestendfn
ctx.onRequestData(function (ctx, chunk, callback) {
requestBodyDataChunks.push(chunk);
return callback(null, chunk);
});

ctx.onRequestEnd((ctx, callback) => {
readBodyFromStream(ctx.proxyToServerRequest, (requestBody) => {
requestData['requestBody'] = requestBody;
const requestBodyString = Buffer.concat(requestBodyDataChunks).toString('utf8');
requestData['requestBody'] = requestBody ? requestBody : requestBodyString;
requestData['requestHeaders'] = ctx.proxyToServerRequest?.getHeaders();
});
callback();
Expand Down
6 changes: 3 additions & 3 deletions src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BasePlugin } from 'appium/plugin';
import http from 'http';
import { Application } from 'express';
import { CliArg, ISessionCapability, MockConfig, SniffConfig } from './types';
import { CliArg, ISessionCapability, MockConfig, RequestInfo, SniffConfig } from './types';
import _ from 'lodash';
import { configureWifiProxy, isRealDevice } from './utils/adb';
import { cleanUpProxyServer, sanitizeMockConfig, setupProxyServer } from './utils/proxy';
Expand Down Expand Up @@ -139,7 +139,7 @@ export class AppiumInterceptorPlugin extends BasePlugin {
proxy.enableMock(id);
}

async startListening(next: any, driver: any, config: SniffConfig) {
async startListening(next: any, driver: any, config: SniffConfig): Promise<string> {
const proxy = proxyCache.get(driver.sessionId);
if (!proxy) {
logger.error('Proxy is not running');
Expand All @@ -150,7 +150,7 @@ export class AppiumInterceptorPlugin extends BasePlugin {
return proxy?.addSniffer(config);
}

async stopListening(next: any, driver: any, id: any) {
async stopListening(next: any, driver: any, id: any): Promise<RequestInfo[]> {
const proxy = proxyCache.get(driver.sessionId);
if (!proxy) {
logger.error('Proxy is not running');
Expand Down
9 changes: 7 additions & 2 deletions src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Mock } from './mock';
import { RequestInterceptor } from './interceptor';
import { ApiSniffer } from './api-sniffer';
import _ from 'lodash';
import logger from './logger';

export interface ProxyOptions {
deviceUDID: string;
Expand Down Expand Up @@ -79,6 +80,10 @@ export class Proxy {
);
this.httpProxy.onRequest(this.handleMockApiRequest.bind(this));

this.httpProxy.onError((context, error, errorType) => {
logger.error(`${errorType}: ${error}`);
});

await new Promise((resolve) => {
this.httpProxy.listen(proxyOptions, () => {
this._started = true;
Expand Down Expand Up @@ -111,9 +116,9 @@ export class Proxy {
this.mocks.get(id)?.setEnableStatus(false);
}

public addSniffer(sniffConfg: SniffConfig): string {
public addSniffer(sniffConfig: SniffConfig): string {
const id = uuid();
const parsedConfig = !sniffConfg ? {} : parseJson(sniffConfg);
const parsedConfig = !sniffConfig ? {} : parseJson(sniffConfig);
this.sniffers.set(id, new ApiSniffer(id, parsedConfig));
return id;
}
Expand Down
5 changes: 3 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
"allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
"declaration": true, /* Generates corresponding '.d.ts' file. */
"declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
"declarationDir": "./lib/types", /* Redirect declarations output structure to the directory. */
"sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./lib", /* Redirect output structure to the directory. */
Expand Down

0 comments on commit d051525

Please sign in to comment.