Skip to content

Commit e6d0201

Browse files
committed
add gzip parsing
1 parent e3b0a76 commit e6d0201

File tree

3 files changed

+97
-19
lines changed

3 files changed

+97
-19
lines changed

src/__smoke-test__/dataplane-integ.spec.ts

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { test, expect } from '@playwright/test';
22
import {
33
getEventsByType,
44
getUrl,
5-
isDataPlaneRequest
5+
isCompressedRequest,
6+
isDataPlaneRequest,
7+
parseRequestBody
68
} from 'test-utils/smoke-test-utils';
79
import {
810
PERFORMANCE_NAVIGATION_EVENT_TYPE,
@@ -50,8 +52,8 @@ test('when web client calls PutRumEvents then the payload contains all events',
5052
isDataPlaneRequest(response, TARGET_URL)
5153
);
5254

53-
// Parse payload to verify event count
54-
const requestBody = JSON.parse(response.request().postData());
55+
// Parse payload (handles gzip decompression automatically)
56+
const requestBody = await parseRequestBody(response.request());
5557

5658
const session = getEventsByType(requestBody, SESSION_START_EVENT_TYPE);
5759
const navigation = getEventsByType(
@@ -70,3 +72,48 @@ test('when web client calls PutRumEvents then the payload contains all events',
7072
expect(navigation.length).toEqual(NAVIGATION_COUNT);
7173
expect(resource.length).toEqual(RESOURCE_EVENT_COUNT);
7274
});
75+
76+
test('when compression is enabled then PutRumEvents request is gzip encoded', async ({
77+
page
78+
}) => {
79+
// Open page
80+
await page.goto(TEST_URL);
81+
82+
// Test will timeout if no successful dataplane request is found
83+
const response = await page.waitForResponse(async (response) =>
84+
isDataPlaneRequest(response, TARGET_URL)
85+
);
86+
87+
// Verify request is gzip compressed
88+
expect(isCompressedRequest(response.request())).toBe(true);
89+
expect(response.request().headers()['content-encoding']).toBe('gzip');
90+
});
91+
92+
test('when compression is enabled then decompressed payload contains valid events', async ({
93+
page
94+
}) => {
95+
// Open page
96+
await page.goto(TEST_URL);
97+
98+
// Test will timeout if no successful dataplane request is found
99+
const response = await page.waitForResponse(async (response) =>
100+
isDataPlaneRequest(response, TARGET_URL)
101+
);
102+
103+
// Verify compression is used
104+
expect(isCompressedRequest(response.request())).toBe(true);
105+
106+
// Parse and verify decompressed payload
107+
const requestBody = await parseRequestBody(response.request());
108+
109+
// Verify payload structure
110+
expect(requestBody).toHaveProperty('RumEvents');
111+
expect(Array.isArray(requestBody.RumEvents)).toBe(true);
112+
expect(requestBody.RumEvents.length).toBeGreaterThan(0);
113+
114+
// Verify events have required fields
115+
const firstEvent = requestBody.RumEvents[0];
116+
expect(firstEvent).toHaveProperty('id');
117+
expect(firstEvent).toHaveProperty('type');
118+
expect(firstEvent).toHaveProperty('timestamp');
119+
});

src/__smoke-test__/ingestion-integ.spec.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
getEventsByType,
2020
getUrl,
2121
isDataPlaneRequest,
22+
parseRequestBody,
2223
verifyIngestionWithRetry
2324
} from 'test-utils/smoke-test-utils';
2425

@@ -60,7 +61,7 @@ test('when session start event is sent then event is ingested', async ({
6061
);
6162

6263
// Parse payload to verify event count
63-
const requestBody = JSON.parse(response.request().postData());
64+
const requestBody = await parseRequestBody(response.request());
6465

6566
const session = getEventsByType(requestBody, SESSION_START_EVENT_TYPE);
6667
const eventIds = getEventIds(session);
@@ -87,7 +88,7 @@ test('when resource event is sent then event is ingested', async ({ page }) => {
8788
);
8889

8990
// Parse payload to verify event count
90-
const requestBody = JSON.parse(response.request().postData());
91+
const requestBody = await parseRequestBody(response.request());
9192

9293
const resource = getEventsByType(
9394
requestBody,
@@ -119,7 +120,7 @@ test('when LCP event is sent then event is ingested', async ({ page }) => {
119120
);
120121

121122
// Parse payload to verify event count
122-
const requestBody = JSON.parse(response.request().postData());
123+
const requestBody = await parseRequestBody(response.request());
123124

124125
const lcp = getEventsByType(requestBody, LCP_EVENT_TYPE);
125126
const eventIds = getEventIds(lcp);
@@ -149,7 +150,7 @@ test('when FID event is sent then event is ingested', async ({ page }) => {
149150
);
150151

151152
// Parse payload to verify event count
152-
const requestBody = JSON.parse(response.request().postData());
153+
const requestBody = await parseRequestBody(response.request());
153154

154155
const fid = getEventsByType(requestBody, FID_EVENT_TYPE);
155156
const eventIds = getEventIds(fid);
@@ -181,7 +182,7 @@ test('when navigation events are sent then events are ingested', async ({
181182
);
182183

183184
// Parse payload to verify event count
184-
const requestBody = JSON.parse(response.request().postData());
185+
const requestBody = await parseRequestBody(response.request());
185186

186187
const navigation = getEventsByType(
187188
requestBody,
@@ -217,7 +218,7 @@ test('when page view event is sent then the event is ingested', async ({
217218
);
218219

219220
// Parse payload to verify event count
220-
const requestBody = JSON.parse(response.request().postData());
221+
const requestBody = await parseRequestBody(response.request());
221222

222223
const pageViews = getEventsByType(requestBody, PAGE_VIEW_EVENT_TYPE);
223224
const eventIds = getEventIds(pageViews);
@@ -254,7 +255,7 @@ test('when error events are sent then the events are ingested', async ({
254255
);
255256

256257
// Parse payload to verify event count
257-
const requestBody = JSON.parse(response.request().postData());
258+
const requestBody = await parseRequestBody(response.request());
258259

259260
const errors = getEventsByType(requestBody, JS_ERROR_EVENT_TYPE);
260261
const eventIds = getEventIds(errors);
@@ -289,7 +290,7 @@ test('when http events are sent then the events are ingested', async ({
289290
);
290291

291292
// Parse payload to verify event count
292-
const requestBody = JSON.parse(response.request().postData());
293+
const requestBody = await parseRequestBody(response.request());
293294

294295
const httpEvents = getEventsByType(requestBody, HTTP_EVENT_TYPE);
295296
const eventIds = getEventIds(httpEvents);
@@ -325,7 +326,7 @@ test('when CLS event is sent then the event is ingested', async ({ page }) => {
325326
);
326327

327328
// Parse payload to verify event count
328-
const requestBody = JSON.parse(response.request().postData());
329+
const requestBody = await parseRequestBody(response.request());
329330

330331
const clsEvents = getEventsByType(requestBody, CLS_EVENT_TYPE);
331332
const eventIds = getEventIds(clsEvents);
@@ -358,7 +359,7 @@ test('when dom event is sent then the event is ingested', async ({ page }) => {
358359
);
359360

360361
// Parse payload to verify event count
361-
const requestBody = JSON.parse(response.request().postData());
362+
const requestBody = await parseRequestBody(response.request());
362363

363364
const domEvent = getEventsByType(requestBody, DOM_EVENT_TYPE);
364365
const eventIds = getEventIds(domEvent);
@@ -389,7 +390,7 @@ test('when xray event is sent then the event is ingested', async ({ page }) => {
389390
);
390391

391392
// Parse payload to verify event count
392-
const requestBody = JSON.parse(response.request().postData());
393+
const requestBody = await parseRequestBody(response.request());
393394

394395
const xrayEvent = getEventsByType(requestBody, XRAY_TRACE_EVENT_TYPE);
395396
const eventIds = getEventIds(xrayEvent);
@@ -422,7 +423,7 @@ test('when xray event is sent with w3c trace id then the event is ingested', asy
422423
);
423424

424425
// Parse payload to verify event count
425-
const requestBody = JSON.parse(response.request().postData());
426+
const requestBody = await parseRequestBody(response.request());
426427

427428
const xrayEvent = getEventsByType(requestBody, XRAY_TRACE_EVENT_TYPE);
428429
const eventIds = getEventIds(xrayEvent);
@@ -458,7 +459,7 @@ test('when event with custom attributes is sent then the event is ingested', asy
458459
);
459460

460461
// Parse payload to verify event count
461-
const requestBody = JSON.parse(response.request().postData());
462+
const requestBody = await parseRequestBody(response.request());
462463

463464
const pageViews = getEventsByType(requestBody, PAGE_VIEW_EVENT_TYPE);
464465
const eventIds = getEventIds(pageViews);
@@ -513,7 +514,7 @@ test('when INP event is sent then event is ingested', async ({ page }) => {
513514
);
514515

515516
// Parse payload to verify event count
516-
const requestBody = JSON.parse(response.request().postData());
517+
const requestBody = await parseRequestBody(response.request());
517518

518519
const inp = getEventsByType(requestBody, INP_EVENT_TYPE);
519520
const eventIds = getEventIds(inp);
@@ -549,7 +550,7 @@ test('when http events are sent with w3c format enabled then the events are inge
549550
);
550551

551552
// Parse payload to verify event count
552-
const requestBody = JSON.parse(response.request().postData());
553+
const requestBody = await parseRequestBody(response.request());
553554

554555
const httpEvents = getEventsByType(requestBody, HTTP_EVENT_TYPE);
555556
const eventIds = getEventIds(httpEvents);

src/test-utils/smoke-test-utils.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {
33
GetAppMonitorDataCommandInput,
44
RUMClient
55
} from '@aws-sdk/client-rum';
6-
import { expect, Response } from '@playwright/test';
6+
import { expect, Response, Request } from '@playwright/test';
7+
import * as zlib from 'zlib';
78

89
const builtInAttributes = [
910
'version',
@@ -84,6 +85,35 @@ export const isDataPlaneRequest = (response: Response, targetUrl: string) => {
8485
);
8586
};
8687

88+
/**
89+
* Returns true if the request has gzip content-encoding
90+
*/
91+
export const isCompressedRequest = (request: Request): boolean => {
92+
const contentEncoding = request.headers()['content-encoding'];
93+
return contentEncoding === 'gzip';
94+
};
95+
96+
/**
97+
* Parses request body, decompressing if gzip-encoded
98+
*/
99+
export const parseRequestBody = async (
100+
request: Request
101+
): Promise<{ RumEvents: any[] }> => {
102+
const isGzip = isCompressedRequest(request);
103+
const postData = request.postDataBuffer();
104+
105+
if (!postData) {
106+
throw new Error('No post data found');
107+
}
108+
109+
if (isGzip) {
110+
const decompressed = zlib.gunzipSync(postData);
111+
return JSON.parse(decompressed.toString('utf-8'));
112+
}
113+
114+
return JSON.parse(postData.toString('utf-8'));
115+
};
116+
87117
/** Returns true when all events were ingested */
88118
export const verifyIngestionWithRetry = async (
89119
rumClient: RUMClient,

0 commit comments

Comments
 (0)