@jitsu/js 1.9.18-canary.1288.20250415191203 → 1.9.18-canary.1288.20250415193648

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/package.json +8 -3
  2. package/.turbo/turbo-build.log +0 -67
  3. package/.turbo/turbo-clean.log +0 -5
  4. package/.turbo/turbo-test.log +0 -2884
  5. package/__tests__/node/method-queue.test.ts +0 -66
  6. package/__tests__/node/nodejs.test.ts +0 -306
  7. package/__tests__/playwright/cases/anonymous-id-bug.html +0 -26
  8. package/__tests__/playwright/cases/basic.html +0 -32
  9. package/__tests__/playwright/cases/callbacks.html +0 -21
  10. package/__tests__/playwright/cases/cookie-names.html +0 -22
  11. package/__tests__/playwright/cases/disable-user-ids.html +0 -23
  12. package/__tests__/playwright/cases/dont-send.html +0 -22
  13. package/__tests__/playwright/cases/ip-policy.html +0 -22
  14. package/__tests__/playwright/cases/reset.html +0 -32
  15. package/__tests__/playwright/cases/segment-reference.html +0 -64
  16. package/__tests__/playwright/cases/url-bug.html +0 -20
  17. package/__tests__/playwright/integration.test.ts +0 -640
  18. package/__tests__/simple-syrup.ts +0 -136
  19. package/jest.config.js +0 -13
  20. package/package/README.md +0 -9
  21. package/package/dist/analytics-plugin.d.ts +0 -28
  22. package/package/dist/browser.d.ts +0 -10
  23. package/package/dist/index.d.ts +0 -28
  24. package/package/dist/jitsu.cjs.js +0 -2100
  25. package/package/dist/jitsu.d.ts +0 -78
  26. package/package/dist/jitsu.es.js +0 -2090
  27. package/package/dist/method-queue.d.ts +0 -19
  28. package/package/dist/script-loader.d.ts +0 -8
  29. package/package/dist/tlds.d.ts +0 -3
  30. package/package/dist/version.d.ts +0 -3
  31. package/package/dist/web/p.js.txt +0 -2219
  32. package/package/package.json +0 -56
  33. package/playwrite.config.ts +0 -91
  34. package/rollup.config.js +0 -32
  35. package/src/analytics-plugin.ts +0 -989
  36. package/src/browser.ts +0 -163
  37. package/src/destination-plugins/ga4.ts +0 -138
  38. package/src/destination-plugins/gtm.ts +0 -142
  39. package/src/destination-plugins/index.ts +0 -61
  40. package/src/destination-plugins/logrocket.ts +0 -85
  41. package/src/destination-plugins/tag.ts +0 -85
  42. package/src/index.ts +0 -255
  43. package/src/method-queue.ts +0 -70
  44. package/src/script-loader.ts +0 -76
  45. package/src/tlds.ts +0 -27
  46. package/src/version.ts +0 -6
  47. package/tsconfig.json +0 -23
  48. package/tsconfig.test.json +0 -15
@@ -1,640 +0,0 @@
1
- import { BrowserContext, expect, Page, test } from "@playwright/test";
2
- import { createServer, SimpleSyrup } from "../simple-syrup";
3
- import * as fs from "fs";
4
- import * as path from "path";
5
- import ejs from "ejs";
6
- // import chalk from "chalk";
7
- import * as process from "process";
8
- import { AnalyticsClientEvent, AnalyticsInterface } from "@jitsu/protocols/analytics.d";
9
-
10
- test.use({
11
- ignoreHTTPSErrors: true,
12
- });
13
-
14
- const chalk = {
15
- cyan: (str: string) => str,
16
- bold: (str: string) => str,
17
- };
18
-
19
- const express = require("express");
20
- const cookieParser = require("cookie-parser");
21
- const app = express();
22
- //const forge = require("node-forge");
23
-
24
- let server: SimpleSyrup;
25
-
26
- let requestLog: { type: string; body: AnalyticsClientEvent; headers: any }[] = [];
27
-
28
- test.beforeAll(async () => {
29
- const testCasesHandlers = fs.readdirSync(path.join(__dirname, "cases")).reduce((res, file) => {
30
- console.log("Processing file", file);
31
- return {
32
- ...res,
33
- [`/${file}`]: (req, res) => {
34
- res.setHeader("Content-Type", "text/html");
35
- res.send(
36
- ejs.compile(
37
- fs.readFileSync(path.join(__dirname, "cases", file)).toString(),
38
- {}
39
- )({
40
- trackingBase: server.baseUrl,
41
- })
42
- );
43
- },
44
- };
45
- }, {});
46
- server = await createServer({
47
- port: 3088,
48
- https: process.env.DISABLE_HTTPS !== "1" && process.env.DISABLE_HTTPS !== "true",
49
- handlers: {
50
- "/p.js": (req, res) => {
51
- res.setHeader("Content-Type", "text/javascript");
52
- res.send(fs.readFileSync(path.join(__dirname, "../../dist/web/p.js.txt")).toString());
53
- },
54
- "/api/s/:type": async (req, res) => {
55
- //sleep for 30ms to simulate network latency. It helps catch bugs with async processing
56
- await new Promise(resolve => setTimeout(resolve, 50));
57
-
58
- res.setHeader("Content-Type", "text/javascript");
59
- res.send({ ok: true });
60
- requestLog.push({
61
- type: req.params.type,
62
- headers: req.headers,
63
- body: req.body,
64
- });
65
- },
66
- ...testCasesHandlers,
67
- },
68
- });
69
- console.log("Running on " + server.baseUrl);
70
- });
71
-
72
- test.afterAll(async () => {
73
- await server?.close();
74
- });
75
-
76
- function sortKeysRecursively(obj: any): any {
77
- if (typeof obj === "object" && obj !== null && !Array.isArray(obj)) {
78
- return Object.keys(obj)
79
- .sort()
80
- .reduce((res, key) => {
81
- res[key] = sortKeysRecursively(obj[key]);
82
- return res;
83
- }, {});
84
- }
85
- return obj;
86
- }
87
-
88
- function shouldKeepBrowserOpen() {
89
- return process.env.KEEP_BROWSER_OPEN === "true" || process.env.KEEP_BROWSER_OPEN === "1";
90
- }
91
-
92
- async function createLoggingPage(browserContext: BrowserContext): Promise<{ page: Page; uncaughtErrors: Error[] }> {
93
- const page = await browserContext.newPage();
94
- const errors: Error[] = [];
95
-
96
- page.on("pageerror", error => {
97
- errors.push(error);
98
- const border = chalk.cyan("│");
99
- console.log();
100
- console.log(`${border} ${chalk.cyan(`Browser Console UNCAUGHT ERROR:`)}`);
101
- console.log(`${border} ` + error.stack.split("\n").join(`\n${border} `));
102
- });
103
-
104
- page.on("console", msg => {
105
- const border = chalk.cyan("│");
106
- console.log();
107
- console.log(`${border} ${chalk.cyan(`Browser Console ${msg.type().toUpperCase()}`)}`);
108
- console.log(`${border} ` + msg.text().split("\n").join(`\n${border} `));
109
- });
110
- return { page, uncaughtErrors: errors };
111
- }
112
-
113
- const generateTestEvents = async () => {
114
- const implName = `${window["analytics"] ? "segment" : "jitsu"}`;
115
- const analytics = (window["analytics"] || window["jitsu"]) as AnalyticsInterface;
116
- console.log(`Generating test events. Implementation ${implName}: ${Object.keys(analytics)}`);
117
- await analytics.identify("userId2", { email: "john.doe2@gmail.com", caseName: "basic-identify" });
118
- await analytics.page("test-page-right-after-identify", { caseName: "test-page-right-after-identify" });
119
- // jitsu must extract traits even from 'id' object
120
- await analytics.identify({ email: "john.doe3@gmail.com", caseName: "identify-without-user-id" });
121
- await analytics.group("group1", { name: "Group 1", caseName: "basic-group" });
122
- await analytics.page({ caseName: "page-without-name", context: { page: { title: "Synthetic Title" } } });
123
- await analytics.page("test-page", { caseName: "page-with-name" });
124
- await analytics.track("testEvent", { caseName: "track-with-name" });
125
- await analytics.identify(9292649175 as any, { caseName: "identify-with-numeric-id-1" });
126
- console.log(`Test events for ${implName} has been generated`);
127
- };
128
-
129
- /**
130
- * This test isn't really testing anything. It generates reference segment events
131
- */
132
- test("segment-reference", async ({ browser }) => {
133
- if (!process.env.SEGMENT_WRITE_KEY) {
134
- console.log("Skipping segment reference generation, no SEGMENT_WRITE_KEY provided");
135
- return;
136
- }
137
- // Using the browser fixture, you can get access to the BrowserContext
138
- const browserContext = await browser.newContext();
139
- const { page } = await createLoggingPage(browserContext);
140
- const requests: Record<string, { payload: any }[]> = {};
141
- page.on("response", async response => {
142
- const request = response.request();
143
- const apiPrefix = "https://api.segment.io/v1/";
144
- if (request.url().startsWith(apiPrefix) && request.method() === "POST") {
145
- const type = request.url().substring(apiPrefix.length);
146
- requests[type] = requests[type] || [];
147
- requests[type].push({
148
- payload: await request.postDataJSON(),
149
- });
150
- }
151
- console.log(`Request ${request.method()} ${request.url()} → ${response.status()}`);
152
- });
153
-
154
- await page.goto(`${server.baseUrl}/segment-reference.html?utm_source=source&utm_medium=medium&utm_campaign=campaign`);
155
-
156
- await page.waitForFunction(() => window["__analyticsReady"] === true, undefined, {
157
- timeout: 5000,
158
- polling: 100,
159
- });
160
- console.log("Segment has been page loaded. Sending events");
161
- await page.evaluate(generateTestEvents);
162
- const cookies = (await browserContext.cookies()).reduce(
163
- (res, cookie) => ({
164
- ...res,
165
- [cookie.name]: cookie.value,
166
- }),
167
- {}
168
- );
169
- console.log("🍪 Segment Cookies", cookies);
170
- let counter = 1;
171
- for (const type of Object.keys(requests)) {
172
- for (const { payload } of requests[type]) {
173
- const dir = path.join(__dirname, "artifacts", "segment-reference");
174
- fs.mkdirSync(dir, { recursive: true });
175
- const file = path.join(
176
- dir,
177
- `${counter++} - ${payload.traits?.caseName || payload.properties?.caseName || payload.context?.caseName}.json`
178
- );
179
- fs.writeFileSync(file, JSON.stringify(sortKeysRecursively(payload), null, 2));
180
- }
181
- }
182
- });
183
-
184
- function describeEvent(type: string, body: any) {
185
- const params = [
186
- body.userId ? "userId=" + body.userId : undefined,
187
- body.anonymousId ? "anonId=" + body.anonymousId : undefined,
188
- body.traits ? ["traits=" + JSON.stringify(body.traits)] : [],
189
- ]
190
- .filter(x => !!x)
191
- .join(", ");
192
- return `${type}${type === "track" ? `(${body.event})` : ""}[${params}]`;
193
- }
194
-
195
- function clearRequestLog() {
196
- requestLog.length = 0;
197
- }
198
-
199
- test("jitsu-queue-callbacks", async ({ browser }) => {
200
- clearRequestLog();
201
- const browserContext = await browser.newContext();
202
- const { page, uncaughtErrors } = await createLoggingPage(browserContext);
203
- const [pageResult] = await Promise.all([page.goto(`${server.baseUrl}/callbacks.html`)]);
204
- await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
205
- timeout: 1000,
206
- polling: 100,
207
- });
208
- //wait for some time since the server has an artificial latency of 30ms
209
- await new Promise(resolve => setTimeout(resolve, 1000));
210
- console.log(
211
- `📝 Request log size of ${requestLog.length}`,
212
- requestLog.map(x => describeEvent(x.type, x.body))
213
- );
214
- expect(requestLog.length).toBe(3);
215
- });
216
-
217
- // Skip this test because jitsu-js no longer relies on canonical URL
218
- test.skip("url-bug", async ({ browser, context }) => {
219
- //tests a bug in getanalytics.io where the url without slash provided by
220
- //<link rel="canonical" ../> causes incorrect page path
221
- const browserContext = await browser.newContext();
222
- const { page, uncaughtErrors } = await createLoggingPage(browserContext);
223
- const [pageResult] = await Promise.all([page.goto(`${server.baseUrl}/url-bug.html`)]);
224
-
225
- await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
226
- timeout: 1000,
227
- polling: 100,
228
- });
229
- expect(pageResult.status()).toBe(200);
230
- //wait for some time since the server has an artificial latency of 30ms
231
- await new Promise(resolve => setTimeout(resolve, 1000));
232
- expect(uncaughtErrors.length).toEqual(0);
233
- expect(requestLog.length).toBe(2);
234
- console.log(
235
- `📝 Request log size of ${requestLog.length}`,
236
- requestLog.map(x => describeEvent(x.type, x.body))
237
- );
238
- //a track contains a valid URL, probably because analytics can't grab the canonical URL yet
239
- const trackEvent = requestLog.find(x => x.type === "page");
240
- expect(trackEvent).toBeDefined();
241
- const pagePath = trackEvent.body.context.page.path;
242
- expect(pagePath).toBeDefined();
243
- //it's "//localhost:3088" when the bug is present
244
- expect(pagePath).toEqual("/");
245
- });
246
-
247
- test("reset", async ({ browser }) => {
248
- clearRequestLog();
249
- const browserContext = await browser.newContext();
250
- const { page, uncaughtErrors } = await createLoggingPage(browserContext);
251
- const [pageResult] = await Promise.all([page.goto(`${server.baseUrl}/reset.html`)]);
252
- await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
253
- timeout: 1000,
254
- polling: 100,
255
- });
256
- expect(pageResult.status()).toBe(200);
257
- //wait for some time since the server has an artificial latency of 30ms
258
- await new Promise(resolve => setTimeout(resolve, 1000));
259
- expect(uncaughtErrors.length).toEqual(0);
260
- expect(requestLog.length).toBe(3);
261
- console.log(
262
- `📝 Request log size of ${requestLog.length}`,
263
- requestLog.map(x => describeEvent(x.type, x.body))
264
- );
265
- const [identifyEvent, firstTrack, secondTrack] = requestLog;
266
- expect(firstTrack.body.anonymousId).toEqual("john-doe-id-1");
267
-
268
- const cookies = await browserContext.cookies();
269
- // all cookies should be cleared by .reset()
270
- // but new cookie for new anonymousId should be set
271
- expect(cookies.length).toBe(1);
272
- expect(cookies[0].name).toEqual("__eventn_id");
273
- const newAnonymousId = cookies[0].value;
274
- console.log(`🍪Cookies`, cookies);
275
-
276
- //second identify call should not reach the server, but it should change the traits
277
- expect(firstTrack.body.context.traits?.email).toEqual("john2@example.com");
278
-
279
- expect(secondTrack.body.anonymousId).not.toBeNull();
280
- expect(secondTrack.body.anonymousId).toBeDefined();
281
- expect(secondTrack.body.anonymousId).toEqual(newAnonymousId);
282
- expect(secondTrack.body.anonymousId).not.toEqual("john-doe-id-1");
283
- });
284
-
285
- const generateEventsForConsentTests = async () => {
286
- const analytics = window["jitsu"] as AnalyticsInterface;
287
- await analytics.identify("myUserId", { email: "myUserId@example.com" });
288
- await analytics.group("myGroupId", { name: "myGroupId" });
289
- await analytics.page("myPage");
290
- };
291
-
292
- test("ip-policy", async ({ browser }) => {
293
- clearRequestLog();
294
- const browserContext = await browser.newContext();
295
- const { page, uncaughtErrors } = await createLoggingPage(browserContext);
296
- const [pageResult] = await Promise.all([page.goto(`${server.baseUrl}/ip-policy.html`)]);
297
- await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
298
- timeout: 1000,
299
- polling: 100,
300
- });
301
- expect(pageResult?.status()).toBe(200);
302
- //wait for some time since the server has an artificial latency of 30ms
303
- await new Promise(resolve => setTimeout(resolve, 1000));
304
- expect(uncaughtErrors.length).toEqual(0);
305
- expect(requestLog.length).toBe(1);
306
- const p = requestLog[0];
307
- expect(p.headers?.["x-ip-policy"]).toEqual("stripLastOctet");
308
- });
309
-
310
- test("dont-send", async ({ browser }) => {
311
- clearRequestLog();
312
- const browserContext = await browser.newContext();
313
- const { page, uncaughtErrors } = await createLoggingPage(browserContext);
314
- const [pageResult] = await Promise.all([page.goto(`${server.baseUrl}/dont-send.html`)]);
315
- await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
316
- timeout: 1000,
317
- polling: 100,
318
- });
319
- expect(pageResult?.status()).toBe(200);
320
- //wait for some time since the server has an artificial latency of 30ms
321
- await new Promise(resolve => setTimeout(resolve, 1000));
322
- expect(uncaughtErrors.length).toEqual(0);
323
- expect(requestLog.length).toBe(0);
324
- await page.evaluate(generateEventsForConsentTests);
325
-
326
- const cookies = await browserContext.cookies();
327
-
328
- expect(uncaughtErrors.length).toEqual(0);
329
- expect(requestLog.length).toBe(0);
330
- expect(cookies.length).toBe(0);
331
- });
332
-
333
- test("dont-send-then-consent", async ({ browser }) => {
334
- clearRequestLog();
335
- const browserContext = await browser.newContext();
336
- const { page, uncaughtErrors } = await createLoggingPage(browserContext);
337
- const [pageResult] = await Promise.all([page.goto(`${server.baseUrl}/dont-send.html`)]);
338
- await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
339
- timeout: 1000,
340
- polling: 100,
341
- });
342
- expect(pageResult?.status()).toBe(200);
343
- //wait for some time since the server has an artificial latency of 30ms
344
- await new Promise(resolve => setTimeout(resolve, 1000));
345
- expect(uncaughtErrors.length).toEqual(0);
346
- expect(requestLog.length).toBe(0);
347
-
348
- await page.evaluate(async () => {
349
- const analytics = window["jitsu"] as AnalyticsInterface;
350
- analytics.configure({
351
- privacy: {
352
- dontSend: false,
353
- consentCategories: {
354
- analytics: true,
355
- },
356
- },
357
- });
358
- });
359
- await page.evaluate(generateEventsForConsentTests);
360
- await new Promise(resolve => setTimeout(resolve, 1000));
361
-
362
- const cookies = await browserContext.cookies();
363
- expect(uncaughtErrors.length).toEqual(0);
364
- expect(requestLog.length).toBe(3);
365
- expect(cookies.length).toBe(5);
366
- const p = requestLog[2];
367
- expect(p.type).toEqual("page");
368
- expect(p.body.userId).toEqual("myUserId");
369
- expect(p.body.groupId).toEqual("myGroupId");
370
- expect(p.body.context?.traits?.email).toEqual("myUserId@example.com");
371
- expect(p.body.context?.consent?.categoryPreferences).toEqual({ analytics: true });
372
- expect((p.body.anonymousId ?? "").length).toBeGreaterThan(0);
373
- });
374
-
375
- test("disable-user-ids", async ({ browser }) => {
376
- clearRequestLog();
377
- const browserContext = await browser.newContext();
378
- const { page, uncaughtErrors } = await createLoggingPage(browserContext);
379
- const [pageResult] = await Promise.all([page.goto(`${server.baseUrl}/disable-user-ids.html`)]);
380
- await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
381
- timeout: 1000,
382
- polling: 100,
383
- });
384
- expect(pageResult?.status()).toBe(200);
385
- //wait for some time since the server has an artificial latency of 30ms
386
- await new Promise(resolve => setTimeout(resolve, 1000));
387
- expect(uncaughtErrors.length).toEqual(0);
388
-
389
- expect(requestLog.length).toBe(0);
390
- await page.evaluate(generateEventsForConsentTests);
391
-
392
- const cookies = await browserContext.cookies();
393
-
394
- expect(uncaughtErrors.length).toEqual(0);
395
- expect(cookies.length).toBe(0);
396
- expect(requestLog.length).toBe(1);
397
- const p = requestLog[0];
398
- expect(p.type).toEqual("page");
399
- expect(p.body.userId).toBeUndefined();
400
- expect(p.body.groupId).toBeUndefined();
401
- expect(p.body.context?.traits?.email).toBeUndefined();
402
- expect(p.body.anonymousId).toBeUndefined();
403
- expect(p.body.properties?.path).toBe("/disable-user-ids.html");
404
- });
405
-
406
- test("disable-user-ids-then-consent", async ({ browser }) => {
407
- clearRequestLog();
408
- const browserContext = await browser.newContext();
409
- const { page, uncaughtErrors } = await createLoggingPage(browserContext);
410
- const [pageResult] = await Promise.all([page.goto(`${server.baseUrl}/disable-user-ids.html`)]);
411
- await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
412
- timeout: 1000,
413
- polling: 100,
414
- });
415
- expect(pageResult?.status()).toBe(200);
416
- //wait for some time since the server has an artificial latency of 30ms
417
- await new Promise(resolve => setTimeout(resolve, 1000));
418
- expect(uncaughtErrors.length).toEqual(0);
419
- expect(requestLog.length).toBe(0);
420
- await page.evaluate(generateEventsForConsentTests);
421
- let cookies = await browserContext.cookies();
422
- expect(uncaughtErrors.length).toEqual(0);
423
- expect(cookies.length).toBe(0);
424
- expect(requestLog.length).toBe(1);
425
-
426
- await page.evaluate(async () => {
427
- const analytics = window["jitsu"] as AnalyticsInterface;
428
- analytics.configure({
429
- privacy: {
430
- disableUserIds: false,
431
- consentCategories: {
432
- analytics: true,
433
- },
434
- },
435
- });
436
- });
437
- await page.evaluate(generateEventsForConsentTests);
438
- await new Promise(resolve => setTimeout(resolve, 1000));
439
-
440
- cookies = await browserContext.cookies();
441
- expect(uncaughtErrors.length).toEqual(0);
442
- expect(requestLog.length).toBe(4);
443
- expect(cookies.length).toBe(5);
444
- const p = requestLog[3];
445
- expect(p.type).toEqual("page");
446
- expect(p.body.userId).toEqual("myUserId");
447
- expect(p.body.groupId).toEqual("myGroupId");
448
- expect(p.body.context?.traits?.email).toEqual("myUserId@example.com");
449
- expect(p.body.context?.consent?.categoryPreferences).toEqual({ analytics: true });
450
- expect((p.body.anonymousId ?? "").length).toBeGreaterThan(0);
451
- });
452
-
453
- test("anonymous-id-bug", async ({ browser }) => {
454
- clearRequestLog();
455
- const anonymousId = "1724633695283.638279";
456
- const browserContext = await browser.newContext();
457
- await browserContext.addCookies([{ name: "__eventn_id", value: anonymousId, url: server.baseUrl }]);
458
- const { page, uncaughtErrors } = await createLoggingPage(browserContext);
459
- const [pageResult] = await Promise.all([page.goto(`${server.baseUrl}/anonymous-id-bug.html`)]);
460
- await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
461
- timeout: 1000,
462
- polling: 100,
463
- });
464
- expect(pageResult.status()).toBe(200);
465
- const cookies = (await browserContext.cookies()).reduce(
466
- (res, cookie) => ({
467
- ...res,
468
- [cookie.name]: cookie.value,
469
- }),
470
- {}
471
- );
472
- console.log("🍪 Jitsu Cookies", cookies);
473
- //wait for some time since the server has an artificial latency of 30ms
474
- await new Promise(resolve => setTimeout(resolve, 1000));
475
- expect(uncaughtErrors.length).toEqual(0);
476
- console.log(
477
- `📝 Request log size of ${requestLog.length}`,
478
- requestLog.map(x => describeEvent(x.type, x.body))
479
- );
480
- const p = requestLog[0];
481
- console.log(chalk.bold("📝 Checking page event"), JSON.stringify(p, null, 3));
482
- expect(p.body.anonymousId).toEqual(anonymousId);
483
- });
484
-
485
- test("cookie-names", async ({ browser }) => {
486
- clearRequestLog();
487
- const browserContext = await browser.newContext();
488
- const { page, uncaughtErrors } = await createLoggingPage(browserContext);
489
- const pageResult = await page.goto(`${server.baseUrl}/cookie-names.html`);
490
- await page.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
491
- timeout: 1000,
492
- polling: 100,
493
- });
494
- expect(pageResult.status()).toBe(200);
495
- const cookies = (await browserContext.cookies()).reduce(
496
- (res, cookie) => ({
497
- ...res,
498
- [cookie.name]: cookie.value,
499
- }),
500
- {}
501
- );
502
- console.log("🍪 Jitsu Cookies", cookies);
503
- expect(cookies).toHaveProperty("my_anon_ck");
504
- const anonymousId = cookies["my_anon_ck"];
505
-
506
- //wait for some time since the server has an artificial latency of 30ms
507
- await new Promise(resolve => setTimeout(resolve, 1000));
508
- expect(uncaughtErrors.length).toEqual(0);
509
- console.log(
510
- `📝 Request log size of ${requestLog.length}`,
511
- requestLog.map(x => describeEvent(x.type, x.body))
512
- );
513
- expect(requestLog[0].body.anonymousId).toEqual(anonymousId);
514
-
515
- const { page: secondPage } = await createLoggingPage(browserContext);
516
- const pageResult2 = await secondPage.goto(
517
- `${server.baseUrl}/cookie-names.html?utm_source=source&utm_medium=medium&utm_campaign=campaign`
518
- );
519
- await secondPage.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
520
- timeout: 1000,
521
- polling: 100,
522
- });
523
- expect(pageResult2.status()).toBe(200);
524
- const cookies2 = (await browserContext.cookies()).reduce(
525
- (res, cookie) => ({
526
- ...res,
527
- [cookie.name]: cookie.value,
528
- }),
529
- {}
530
- );
531
- console.log("🍪 Jitsu Cookies", cookies2);
532
- expect(cookies2).toHaveProperty("my_anon_ck");
533
- expect(cookies["my_anon_ck"]).toEqual(anonymousId);
534
-
535
- //wait for some time since the server has an artificial latency of 30ms
536
- await new Promise(resolve => setTimeout(resolve, 1000));
537
- expect(uncaughtErrors.length).toEqual(0);
538
- console.log(
539
- `📝 Request log size of ${requestLog.length}`,
540
- requestLog.map(x => describeEvent(x.type, x.body))
541
- );
542
- expect(requestLog[1].body.anonymousId).toEqual(anonymousId);
543
- });
544
-
545
- test("basic", async ({ browser }) => {
546
- clearRequestLog();
547
- const browserContext = await browser.newContext();
548
- await browserContext.addCookies([
549
- { name: "_fbc", value: "fbc-id", url: server.baseUrl },
550
- { name: "_fbp", value: "fbp-id", url: server.baseUrl },
551
- { name: "_ttp", value: "ttp-id", url: server.baseUrl },
552
- ]);
553
-
554
- const { page: firstPage, uncaughtErrors: firstPageErrors } = await createLoggingPage(browserContext);
555
- const [pageResult] = await Promise.all([
556
- firstPage.goto(`${server.baseUrl}/basic.html?utm_source=source&utm_medium=medium&utm_campaign=campaign`),
557
- ]);
558
-
559
- await firstPage.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
560
- timeout: 1000,
561
- polling: 100,
562
- });
563
- expect(pageResult.status()).toBe(200);
564
- const cookies = (await browserContext.cookies()).reduce(
565
- (res, cookie) => ({
566
- ...res,
567
- [cookie.name]: cookie.value,
568
- }),
569
- {}
570
- );
571
- console.log("🍪 Jitsu Cookies", cookies);
572
- //wait for some time since the server has an artificial latency of 30ms
573
- await new Promise(resolve => setTimeout(resolve, 1000));
574
- expect(firstPageErrors.length).toEqual(0);
575
- const anonymousId = cookies["__eventn_id"];
576
- expect(anonymousId).toBeDefined();
577
- expect(cookies["__eventn_uid"]).toBe("john-doe-id-1");
578
- expect(cookies["__eventn_id_usr"]).toBeDefined();
579
- expect(JSON.parse(decodeURIComponent(cookies["__eventn_id_usr"])).email).toEqual("john.doe@gmail.com");
580
- console.log(
581
- `📝 Request log size of ${requestLog.length}`,
582
- requestLog.map(x => describeEvent(x.type, x.body))
583
- );
584
- let identifies = requestLog.filter(x => x.type === "identify");
585
- let pages = requestLog.filter(x => x.type === "page");
586
- let tracks = requestLog.filter(x => x.type === "track");
587
- expect(identifies.length).toBe(1);
588
- expect(pages.length).toBe(1);
589
- expect(tracks.length).toBe(1);
590
-
591
- const track = tracks[0].body as AnalyticsClientEvent;
592
- const page = pages[0].body as AnalyticsClientEvent;
593
- const identify = identifies[0].body as AnalyticsClientEvent;
594
-
595
- console.log(chalk.bold("📝 Checking track event"), JSON.stringify(track, null, 3));
596
- expect(track.properties.trackParam).toEqual("trackValue");
597
- expect(track.type).toEqual("track");
598
- expect(track.context.clientIds).toHaveProperty("fbc", "fbc-id");
599
- expect(track.context.clientIds).toHaveProperty("fbp", "fbp-id");
600
- expect(track.context.clientIds).toHaveProperty("ttp", "ttp-id");
601
- expect(track.context.traits.email).toEqual("john.doe@gmail.com");
602
- expect(track.userId).toEqual("john-doe-id-1");
603
- expect(track.event).toEqual("pageLoaded");
604
-
605
- console.log(chalk.bold("📝 Checking identify event"), JSON.stringify(identify, null, 3));
606
- expect(identify.traits.email).toEqual("john.doe@gmail.com");
607
- expect(identify.userId).toEqual("john-doe-id-1");
608
- expect(identify.anonymousId).toEqual(anonymousId);
609
-
610
- console.log(chalk.bold("📝 Checking page event"), JSON.stringify(page, null, 3));
611
- expect(page.anonymousId).toEqual(anonymousId);
612
- expect(page.context.clientIds).toHaveProperty("fbc", "fbc-id");
613
- expect(page.context.clientIds).toHaveProperty("fbp", "fbp-id");
614
- expect(page.context.clientIds).toHaveProperty("ttp", "ttp-id");
615
- expect(page.context.traits.email).toEqual("john.doe@gmail.com");
616
- expect(page.userId).toEqual("john-doe-id-1");
617
-
618
- expect(page.context.campaign.source).toEqual("source");
619
-
620
- const { page: secondPage, uncaughtErrors: secondPageErrors } = await createLoggingPage(browserContext);
621
- await secondPage.goto(`${server.baseUrl}/basic.html?utm_source=source&utm_medium=medium&utm_campaign=campaign`);
622
- await secondPage.waitForFunction(() => window["jitsu"] !== undefined, undefined, {
623
- timeout: 1000,
624
- polling: 100,
625
- });
626
- clearRequestLog();
627
-
628
- await secondPage.evaluate(generateTestEvents);
629
- expect(secondPageErrors.length).toBe(0);
630
- let counter = 1;
631
- requestLog.forEach(({ body: payload }) => {
632
- const dir = path.join(__dirname, "artifacts", "requests");
633
- fs.mkdirSync(dir, { recursive: true });
634
- const file = path.join(
635
- dir,
636
- `${counter++} - ${payload.traits?.caseName || payload.properties?.caseName || payload.context?.caseName}.json`
637
- );
638
- fs.writeFileSync(file, JSON.stringify(sortKeysRecursively(payload), null, 2));
639
- });
640
- });