Skip to content

Commit

Permalink
feat(runner/settings): enable logging switch configuration (#8194)
Browse files Browse the repository at this point in the history
* feat: enable configuration for turning on/off logging

* fix: lint error

* test: add a smoke test

* fix: smoke test

* fix: smoke test

* fix: smoke tests

* fix: make runtime as optional arg with default value

* chore: enable log

* chore: turn off flag

* fix: turn off restriction

* fix: failed to run smoke tests

* fix: remove unnecessary changes

* fix: unnecessary changes
  • Loading branch information
ihexxa authored Jan 7, 2025
1 parent 142d559 commit 37ef377
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 32 deletions.
5 changes: 5 additions & 0 deletions packages/insomnia-sdk/src/objects/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,9 @@ export class Console {
.map(row => JSON.stringify(row) + '\n')
.join('\n');
};

dumpLogsAsArray = () => {
return this.rows
.map(row => JSON.stringify(row) + '\n');
};
}
1 change: 1 addition & 0 deletions packages/insomnia-sdk/src/objects/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ export interface RequestContext {
requestTestResults?: RequestTestResult[];
requestInfo: RequestInfoOption;
execution: ExecutionOption;
logs: string[];
transientVariables?: Omit<IEnvironment, 'id'>;
}
28 changes: 28 additions & 0 deletions packages/insomnia-smoke-test/fixtures/runner-collection.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,34 @@ resources:
settingRebuildPath: true
settingFollowRedirects: global
_type: request
- _id: req_76bf52b201cf47269f5845795a721001
parentId: wrk_418cad89191c418395abfeb2277fd26f
modified: 1636707449232
created: 1636141014552
url: http://127.0.0.1:4010/echo
name: printLogs
description: ""
method: POST
body: {}
parameters: []
headers: []
authentication: {}
preRequestScript: |-
console.log("it won't print");
afterResponseScript: |-
console.log("it won't print");
insomnia.test('happy tests', () => {
insomnia.expect(200).to.eql(200);
});
metaSortKey: 164
isPrivate: false
settingStoreCookies: true
settingSendCookies: true
settingDisableRenderRequestBody: false
settingEncodeUrl: true
settingRebuildPath: true
settingFollowRedirects: global
_type: request
- _id: req_76bf52b201cf47269f5845795a711002
parentId: wrk_418cad89191c418395abfeb2277fd26f
modified: 1636707449232
Expand Down
29 changes: 29 additions & 0 deletions packages/insomnia-smoke-test/tests/smoke/runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,33 @@ test.describe('runner features tests', async () => {

await verifyResultRows(page, 0, 0, 4, expectedTestOrder, 1);
});

test('settings: can turn off logs', async ({ page }) => {

await page.getByTestId('run-collection-btn-quick').click();

await page.locator('.runner-request-list-printLogs').click();

const expectToHaveLogs = [false, true];

for (const expectToHaveLog of expectToHaveLogs) {
// configure
await page.getByRole('tab', { name: 'advanced' }).click();
await page.locator('input[name="enable-log"]').click();

// send
await page.getByRole('button', { name: 'Run', exact: true }).click();

// verify there's no log
await page.getByText('1 / 1').first().click();
await page.getByRole('tab', { name: 'Console' }).click();

const consoleTabContent = page.locator('.pane-two');
if (expectToHaveLog) {
expect(consoleTabContent).toContainText("it won't print");
} else {
expect(consoleTabContent).not.toContainText("it won't print");
}
}
});
});
2 changes: 2 additions & 0 deletions packages/insomnia/src/common/send-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
tryToExecutePreRequestScript,
tryToInterpolateRequest,
} from '../network/network';
import { defaultSendActionRuntime } from '../ui/routes/request';
import { invariant } from '../utils/invariant';
import { database } from './database';
import { generateId } from './misc';
Expand Down Expand Up @@ -156,6 +157,7 @@ export async function getSendRequestCallbackMemDb(environmentId: string, memDB:
const postMutatedContext = await tryToExecuteAfterResponseScript({
...requestData,
...mutatedContext,
runtime: defaultSendActionRuntime,
transientVariables: mutatedContext.transientVariables || transientVariables,
response,
});
Expand Down
3 changes: 1 addition & 2 deletions packages/insomnia/src/hidden-window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ const runScript = async (
const updatedCertificates = mergeClientCertificates(context.clientCertificates, mutatedContextObject.request);
const updatedCookieJar = mergeCookieJar(context.cookieJar, mutatedContextObject.cookieJar);

await window.bridge.appendFile(context.timelinePath, scriptConsole.dumpLogs());

return {
...context,
environment: {
Expand Down Expand Up @@ -121,6 +119,7 @@ const runScript = async (
cookieJar: updatedCookieJar,
globals: mutatedContextObject.globals,
requestTestResults: mutatedContextObject.requestTestResults,
logs: scriptConsole.dumpLogsAsArray(),
};
};

Expand Down
3 changes: 2 additions & 1 deletion packages/insomnia/src/network/__tests__/network.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,8 @@ describe('sendCurlAndWriteTimeline()', () => {
preferredHttpVersion: HttpVersions.V1_0,
},
'/tmp/res_id',
'res_id');
'res_id'
);
expect(JSON.parse(String(models.response.getBodyBuffer(responseV1))).options.HTTP_VERSION).toBe('V1_0');
expect(getHttpVersion(HttpVersions.V1_0).curlHttpVersion).toBe(CurlHttpVersion.V1_0);
expect(getHttpVersion(HttpVersions.V1_1).curlHttpVersion).toBe(CurlHttpVersion.V1_1);
Expand Down
24 changes: 22 additions & 2 deletions packages/insomnia/src/network/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import type { WebSocketRequest } from '../models/websocket-request';
import { isWorkspace, type Workspace } from '../models/workspace';
import * as pluginContexts from '../plugins/context/index';
import * as plugins from '../plugins/index';
import { defaultSendActionRuntime, type SendActionRuntime } from '../ui/routes/request';
import { invariant } from '../utils/invariant';
import { serializeNDJSON } from '../utils/ndjson';
import {
Expand Down Expand Up @@ -184,6 +185,7 @@ export const tryToExecutePreRequestScript = async (
userUploadEnvironment?: UserUploadEnvironment,
iteration?: number,
iterationCount?: number,
runtime?: SendActionRuntime,
) => {

const requestGroups = ancestors.filter(doc => isRequest(doc) || isRequestGroup(doc)) as RequestGroup[];
Expand All @@ -206,6 +208,7 @@ export const tryToExecutePreRequestScript = async (
userUploadEnvironment,
requestTestResults: new Array<RequestTestResult>(),
transientVariables,
logs: '',
};
}
const joinedScript = [...folderScripts].join('\n');
Expand All @@ -227,6 +230,7 @@ export const tryToExecutePreRequestScript = async (
eventName: 'prerequest',
settings,
transientVariables,
runtime,
});
if (!mutatedContext || 'error' in mutatedContext) {
return {
Expand All @@ -242,6 +246,7 @@ export const tryToExecutePreRequestScript = async (
};
}
await savePatchesMadeByScript(mutatedContext, environment, baseEnvironment, activeGlobalEnvironment);

return {
request: mutatedContext.request,
environment: mutatedContext.environment,
Expand Down Expand Up @@ -332,6 +337,7 @@ export const tryToExecuteScript = async (context: RequestAndContextAndOptionalRe
eventName,
execution,
transientVariables,
runtime,
} = context;
invariant(script, 'script must be provided');

Expand Down Expand Up @@ -381,6 +387,7 @@ export const tryToExecuteScript = async (context: RequestAndContextAndOptionalRe
location: requestLocation,
},
transientVariables,
logs: [],
},
});
if ('error' in originalOutput) {
Expand Down Expand Up @@ -423,6 +430,9 @@ export const tryToExecuteScript = async (context: RequestAndContextAndOptionalRe
userUploadEnvironment.data = output?.iterationData?.data || [];
userUploadEnvironment.dataPropertyOrder = userUploadEnvPropertyOrder.map;
}
if (runtime) {
await runtime.appendTimeline(timelinePath, output.logs);
}

if (output?.transientVariables !== undefined) {
const variablesPropertyOrder = orderedJSON.parse(
Expand Down Expand Up @@ -489,6 +499,7 @@ type RequestAndContextAndResponse = RequestContextForScript & {
response: sendCurlAndWriteTimelineError | sendCurlAndWriteTimelineResponse;
iteration?: number;
iterationCount?: number;
runtime: SendActionRuntime;
};

type RequestAndContextAndOptionalResponse = RequestContextForScript & {
Expand All @@ -498,6 +509,7 @@ type RequestAndContextAndOptionalResponse = RequestContextForScript & {
iteration?: number;
iterationCount?: number;
eventName?: RequestContext['requestInfo']['eventName'];
runtime?: SendActionRuntime;
};

export async function tryToExecuteAfterResponseScript(context: RequestAndContextAndResponse) {
Expand Down Expand Up @@ -602,6 +614,7 @@ export interface sendCurlAndWriteTimelineResponse extends ResponsePatch {
timelinePath: string;
statusMessage: string;
cookies: Cookie[];
timeline: string[];
}

export async function sendCurlAndWriteTimeline(
Expand All @@ -611,6 +624,7 @@ export async function sendCurlAndWriteTimeline(
settings: Settings,
timelinePath: string,
responseId: string,
runtime: SendActionRuntime = defaultSendActionRuntime,
): Promise<sendCurlAndWriteTimelineError | sendCurlAndWriteTimelineResponse> {
const requestId = renderedRequest._id;
const timeline: ResponseTimelineEntry[] = [];
Expand Down Expand Up @@ -643,7 +657,9 @@ export async function sendCurlAndWriteTimeline(
const output = await nodejsCurlRequest(requestOptions);

if ('error' in output) {
await fs.promises.appendFile(timelinePath, serializeNDJSON(timeline));
if (runtime) {
await runtime.appendTimeline(timelinePath, serializeNDJSON(timeline).split('\n'));
}

return {
_id: responseId,
Expand All @@ -654,6 +670,7 @@ export async function sendCurlAndWriteTimeline(
bytesRead: 0,
statusMessage: output.statusMessage,
timelinePath,
timeline: serializeNDJSON(timeline).split('\n'),
};
}
const { patch, debugTimeline, headerResults, responseBodyPath } = output;
Expand All @@ -668,7 +685,9 @@ export async function sendCurlAndWriteTimeline(
}
const lastRedirect = headerResults[headerResults.length - 1];

await fs.promises.appendFile(timelinePath, serializeNDJSON(timeline));
if (runtime) {
await runtime.appendTimeline(timelinePath, serializeNDJSON(timeline).split('\n'));
}

return {
_id: responseId,
Expand All @@ -681,6 +700,7 @@ export async function sendCurlAndWriteTimeline(
statusCode: lastRedirect.code,
statusMessage: lastRedirect.reason,
cookies,
timeline: serializeNDJSON(timeline).split('\n'),
...patch,
};
}
Expand Down
59 changes: 38 additions & 21 deletions packages/insomnia/src/ui/routes/request.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createWriteStream } from 'node:fs';
import path from 'node:path';

import * as contentDisposition from 'content-disposition';
import fs from 'fs';
import { GRAPHQL_TRANSPORT_WS_PROTOCOL, MessageType } from 'graphql-ws';
import type { RequestTestResult } from 'insomnia-sdk';
import { extension as mimeExtension } from 'mime-types';
Expand Down Expand Up @@ -64,6 +65,12 @@ export interface RequestLoaderData {
mockServerAndRoutes: (MockServer & { routes: MockRoute[] })[];
}

export const defaultSendActionRuntime = {
appendTimeline: async (timelinePath: string, logs: string[]) => {
await fs.promises.appendFile(timelinePath, logs.join('\n'));
},
};

export const loader: LoaderFunction = async ({ params }): Promise<RequestLoaderData | WebSocketRequestLoaderData | GrpcRequestLoaderData> => {
const { organizationId, projectId, requestId, workspaceId } = params;
invariant(requestId, 'Request ID is required');
Expand Down Expand Up @@ -407,6 +414,10 @@ export interface SendActionParams {
ignoreUndefinedEnvVariable?: boolean;
}

export interface SendActionRuntime {
appendTimeline: (timelinePath: string, logs: string[]) => Promise<void>;
}

export const sendAction: ActionFunction = async ({ request, params }) => {
const { requestId, workspaceId } = params;
invariant(typeof requestId === 'string', 'Request ID is required');
Expand Down Expand Up @@ -473,29 +484,33 @@ export interface RunnerContextForRequest {
responseId: string;
}

export const sendActionImplementation = async ({
requestId,
userUploadEnvironment,
shouldPromptForPathAfterResponse,
ignoreUndefinedEnvVariable,
testResultCollector,
iteration,
iterationCount,
transientVariables,
}: {
requestId: string;
shouldPromptForPathAfterResponse: boolean | undefined;
ignoreUndefinedEnvVariable: boolean | undefined;
testResultCollector?: RunnerContextForRequest;
iteration?: number;
iterationCount?: number;
userUploadEnvironment?: UserUploadEnvironment;
transientVariables?: Environment;
export const sendActionImplementation = async (options: {
requestId: string;
shouldPromptForPathAfterResponse: boolean | undefined;
ignoreUndefinedEnvVariable: boolean | undefined;
testResultCollector?: RunnerContextForRequest;
iteration?: number;
iterationCount?: number;
userUploadEnvironment?: UserUploadEnvironment;
transientVariables?: Environment;
runtime?: SendActionRuntime;
}) => {
const {
requestId,
userUploadEnvironment,
shouldPromptForPathAfterResponse,
ignoreUndefinedEnvVariable,
testResultCollector,
iteration,
iterationCount,
transientVariables: nullableTransientVariables,
runtime = defaultSendActionRuntime,
} = options;

window.main.startExecution({ requestId });
const requestData = await fetchRequestData(requestId);
const requestMeta = await models.requestMeta.getByParentId(requestId);
transientVariables = transientVariables || {
const transientVariables = nullableTransientVariables || {
...models.environment.init(),
_id: uuidv4(),
type: models.environment.type,
Expand All @@ -507,7 +522,7 @@ export const sendActionImplementation = async ({
};

window.main.addExecutionStep({ requestId, stepName: 'Executing pre-request script' });
const mutatedContext = await tryToExecutePreRequestScript(requestData, transientVariables, userUploadEnvironment, iteration, iterationCount);
const mutatedContext = await tryToExecutePreRequestScript(requestData, transientVariables, userUploadEnvironment, iteration, iterationCount, runtime);
if ('error' in mutatedContext) {
throw {
// create response with error info, so that we can store response in db and show it in response viewer
Expand Down Expand Up @@ -573,7 +588,8 @@ export const sendActionImplementation = async ({
requestData.caCert,
mutatedContext.settings,
requestData.timelinePath,
requestData.responseId
requestData.responseId,
runtime,
);
window.main.completeExecutionStep({ requestId });
if ('error' in response) {
Expand All @@ -598,6 +614,7 @@ export const sendActionImplementation = async ({
response,
iteration,
iterationCount,
runtime,
});
if ('error' in postMutatedContext) {
throw {
Expand Down
Loading

0 comments on commit 37ef377

Please sign in to comment.