Skip to content

Commit 9041c59

Browse files
committed
wip
1 parent 5caf4d6 commit 9041c59

File tree

29 files changed

+1155
-101
lines changed

29 files changed

+1155
-101
lines changed

.vscode/launch.json

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,10 @@
66
"request": "launch",
77
"name": "Jest Current File",
88
"program": "${workspaceFolder}/node_modules/.bin/jest",
9-
"args": [
10-
"--testTimeout=100000",
11-
"--findRelatedTests",
12-
"${relativeFile}"
13-
],
9+
"args": ["--testTimeout=100000", "--findRelatedTests", "${relativeFile}"],
1410
"console": "integratedTerminal",
1511
"internalConsoleOptions": "neverOpen",
16-
"skipFiles": [
17-
"<node_internals>/**"
18-
]
12+
"skipFiles": ["<node_internals>/**"]
1913
},
2014
{
2115
"type": "node",
@@ -30,9 +24,17 @@
3024
],
3125
"console": "integratedTerminal",
3226
"internalConsoleOptions": "neverOpen",
33-
"skipFiles": [
34-
"<node_internals>/**"
35-
]
27+
"skipFiles": ["<node_internals>/**"]
28+
},
29+
{
30+
"name": "Run Jest Tests for Current Package",
31+
"type": "node",
32+
"request": "launch",
33+
"program": "${workspaceFolder}/node_modules/.bin/jest",
34+
"args": ["--testTimeout=100000"],
35+
"console": "integratedTerminal",
36+
"internalConsoleOptions": "neverOpen",
37+
"cwd": "${fileDirname}"
3638
},
3739
{
3840
"type": "node",
@@ -47,9 +49,7 @@
4749
"console": "integratedTerminal",
4850
"internalConsoleOptions": "neverOpen",
4951
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
50-
"skipFiles": [
51-
"<node_internals>/**"
52-
]
52+
"skipFiles": ["<node_internals>/**"]
5353
},
5454
{
5555
"type": "node",
@@ -64,9 +64,7 @@
6464
"console": "integratedTerminal",
6565
"internalConsoleOptions": "neverOpen",
6666
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
67-
"skipFiles": [
68-
"<node_internals>/**"
69-
]
67+
"skipFiles": ["<node_internals>/**"]
7068
},
7169
{
7270
"name": "ts-node Current File",

packages/signals/signals-integration-tests/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"scripts": {
99
".": "yarn run -T turbo run --filter=@internal/signals-integration-tests...",
1010
"build": "webpack",
11-
"test": "playwright test",
11+
"test": "playwright test src/tests/signals-vanilla",
12+
"test:perf": "playwright test src/tests/performance",
1213
"watch": "webpack -w",
1314
"lint": "yarn concurrently 'yarn:eslint .' 'yarn:tsc --noEmit'",
1415
"concurrently": "yarn run -T concurrently",

packages/signals/signals-integration-tests/playwright.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ const config: PlaywrightTestConfig = {
3636
use: {
3737
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
3838
trace: 'on',
39+
launchOptions: {
40+
args: ['--enable-precise-memory-info'],
41+
},
3942
},
4043

4144
/* Configure projects for major browsers */
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { BasePage } from '../../helpers/base-page-object'
2+
3+
export class IndexPage extends BasePage {
4+
constructor() {
5+
super(`/performance/index.html`)
6+
}
7+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<script src="../../../dist/signals-vanilla.bundle.js"></script>
6+
<!-- Dummy favicon -->
7+
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
8+
</head>
9+
10+
<body>
11+
<div id="test-container"></div>
12+
</body>
13+
14+
</html>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { test } from '@playwright/test'
2+
import { IndexPage } from './index-page'
3+
import { sleep } from '@segment/analytics-core'
4+
5+
declare global {
6+
interface Performance {
7+
memory: {
8+
usedJSHeapSize: number
9+
totalJSHeapSize: number
10+
}
11+
}
12+
}
13+
14+
const basicEdgeFn = `
15+
// this is a process signal function
16+
const processSignal = (signal) => {
17+
if (signal.type === 'interaction') {
18+
const eventName = signal.data.eventType + ' ' + '[' + signal.type + ']'
19+
analytics.track(eventName, signal.data)
20+
}
21+
}`
22+
23+
let indexPage: IndexPage
24+
25+
test.beforeEach(async ({ page }) => {
26+
indexPage = await new IndexPage().loadAndWait(page, basicEdgeFn)
27+
})
28+
29+
test('memory leak', async ({ page }) => {
30+
await indexPage.waitForSignalsApiFlush()
31+
const ALLOWED_GROWTH = 1.1
32+
const getMemoryUsage = (): Promise<number> =>
33+
page.evaluate(() => {
34+
return performance.memory.usedJSHeapSize
35+
})
36+
37+
const firstMemory = await getMemoryUsage()
38+
39+
// add nodes
40+
await page.evaluate(() => {
41+
const target = document.getElementById('test-container')!
42+
const NODE_COUNT = 2000
43+
for (let i = 0; i < NODE_COUNT; i++) {
44+
const newNode = document.createElement('input')
45+
newNode.type = 'text'
46+
newNode.value = Math.random().toString()
47+
target.appendChild(newNode)
48+
}
49+
})
50+
51+
await sleep(3000)
52+
53+
// remove all the nodes
54+
await page.evaluate(() => {
55+
const target = document.getElementById('test-container')!
56+
while (target.firstChild) {
57+
target.removeChild(target.firstChild)
58+
}
59+
})
60+
61+
// Analyze memory usage
62+
await sleep(3000)
63+
const lastMemory = await getMemoryUsage()
64+
65+
// Allow some fluctuation, but fail if there's a significant memory increase
66+
if (lastMemory > firstMemory * ALLOWED_GROWTH) {
67+
throw new Error(
68+
`Memory leak detected! Initial: ${firstMemory}, Final: ${lastMemory}. Threshold`
69+
)
70+
} else {
71+
console.log(
72+
'Memory leak test passed!',
73+
`initial: ${firstMemory}, final: ${lastMemory}, allowed growth: ${ALLOWED_GROWTH}`
74+
)
75+
}
76+
})

packages/signals/signals-integration-tests/src/tests/signals-vanilla/signals-ingestion.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { test, expect } from '@playwright/test'
22
import { IndexPage } from './index-page'
3+
import { waitForCondition } from '../../helpers/playwright-utils'
34

45
const indexPage = new IndexPage()
56

@@ -56,6 +57,10 @@ test('debug ingestion disabled and sample rate 1 -> will send the signal', async
5657
sampleRate: 1,
5758
}
5859
)
59-
await indexPage.fillNameInput('John Doe')
60-
expect(indexPage.signalsAPI.getEvents('interaction')).toHaveLength(1)
60+
await Promise.all([
61+
indexPage.fillNameInput('John Doe'),
62+
waitForCondition(
63+
() => indexPage.signalsAPI.getEvents('interaction').length > 0
64+
),
65+
])
6166
})

packages/signals/signals-runtime/src/web/web-signals-types.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ type SubmitData = {
2525
target: SerializedTarget
2626
}
2727

28-
type ChangeData = {
28+
export type ChangeData = {
2929
eventType: 'change'
30-
[key: string]: unknown
30+
target: SerializedTarget
31+
listener: 'contenteditable' | 'onchange' | 'mutation'
32+
change: JSONValue
3133
}
3234

3335
export type InteractionSignal = RawSignal<'interaction', InteractionData>

packages/signals/signals/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"build:bundle": "NODE_ENV=production yarn run webpack",
3333
"workerbox": "node scripts/build-workerbox.js",
3434
"assert-generated": "sh scripts/assert-workerbox-built.sh",
35-
"watch": "yarn concurrently 'yarn build:bundle --watch' 'yarn build:esm --watch'",
35+
"watch": "rm -rf dist && yarn concurrently 'yarn build:bundle --watch' 'yarn build:esm --watch'",
3636
"version": "sh scripts/version.sh",
3737
"watch:test": "yarn test --watch",
3838
"tsc": "yarn run -T tsc",

packages/signals/signals/src/core/buffer/__tests__/buffer.test.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ describe(getSignalBuffer, () => {
2828
})
2929

3030
it('should delete older signals when maxBufferSize is exceeded', async () => {
31-
const signals = range(15).map((_, idx) =>
31+
const signals = range(15).map(() =>
3232
createInteractionSignal({
33-
idx: idx,
33+
change: 'change',
3434
eventType: 'change',
35+
listener: 'listener',
3536
target: {},
3637
})
3738
)
@@ -46,9 +47,10 @@ describe(getSignalBuffer, () => {
4647
})
4748

4849
it('should delete older signals on initialize if current number exceeds maxBufferSize', async () => {
49-
const signals = range(15).map((_, idx) =>
50+
const signals = range(15).map((_) =>
5051
createInteractionSignal({
51-
idx: idx,
52+
change: { foo: 'bar' },
53+
listener: 'onchange',
5254
eventType: 'change',
5355
target: {},
5456
})
@@ -103,10 +105,11 @@ describe(getSignalBuffer, () => {
103105
})
104106

105107
it('should delete older signals when maxBufferSize is exceeded', async () => {
106-
const signals = range(15).map((_, idx) =>
108+
const signals = range(15).map(() =>
107109
createInteractionSignal({
108-
idx: idx,
109110
eventType: 'change',
111+
change: { foo: 'bar' },
112+
listener: 'onchange',
110113
target: {},
111114
})
112115
)

0 commit comments

Comments
 (0)