()
| 113 | } |
| 114 | |
| 115 | async function scenarioBoundary() { |
| 116 | scenario('boundary split → first session closes, second opens'); |
| 117 | const ip = `10.${(runId >> 16) & 255}.2.${runId & 255 || 1}`; |
| 118 | |
| 119 | const a = await screenView(ip, '/x'); |
| 120 | console.log(` …waiting ${IDLE_WAIT_MS}ms so the next event crosses the boundary`); |
| 121 | await sleep(IDLE_WAIT_MS); |
| 122 | const b = await screenView(ip, '/y'); |
| 123 | |
| 124 | check( |
| 125 | 'second event opened a NEW session id', |
| 126 | a.sessionId !== b.sessionId && !!b.sessionId, |
| 127 | `${a.sessionId} vs ${b.sessionId}` |
| 128 | ); |
| 129 | |
| 130 | const startsA = await pollUntil(async () => |
| 131 | (await countByName([a.sessionId], 'session_start')) > 0 ? true : null |
| 132 | ); |
| 133 | check('clickhouse: session_start for first session', !!startsA); |
| 134 | const startsB = await pollUntil(async () => |
| 135 | (await countByName([b.sessionId], 'session_start')) > 0 ? true : null |
| 136 | ); |
| 137 | check('clickhouse: session_start for second session', !!startsB); |
| 138 | const endsA = await pollUntil(async () => |
| 139 | (await countByName([a.sessionId], 'session_end')) > 0 ? true : null |
| 140 | ); |
| 141 | check('clickhouse: first session got a session_end', !!endsA); |
| 142 | } |
| 143 | |
| 144 | async function scenarioNonScreenViewFirst() { |
| 145 | scenario('session opened by a non-screen_view event'); |
no test coverage detected