()
| 221 | } |
| 222 | |
| 223 | async function scenarioIdentify() { |
| 224 | scenario('identified visit → profile index + profile_id on events'); |
| 225 | const ip = `10.${(runId >> 16) & 255}.4.${runId & 255 || 1}`; |
| 226 | const profileId = `e2e-user-${runId}`; |
| 227 | |
| 228 | const { deviceId, sessionId } = await screenView(ip, '/account'); |
| 229 | await track( |
| 230 | { |
| 231 | type: 'track', |
| 232 | payload: { name: 'signed_in', profileId, properties: { __ip: ip } }, |
| 233 | }, |
| 234 | ip |
| 235 | ); |
| 236 | |
| 237 | const ptr = await pollUntil(async () => |
| 238 | (await redis.get(profileKey(profileId))) === deviceId ? true : null |
| 239 | ); |
| 240 | check('redis: profile→device pointer written', !!ptr); |
| 241 | |
| 242 | const profiled = await pollUntil(async () => { |
| 243 | const rows = await chQuery<{ c: string }>( |
| 244 | `SELECT count() AS c FROM events WHERE project_id = '${PROJECT_ID}' AND session_id = '${sessionId}' AND profile_id = '${profileId}'` |
| 245 | ); |
| 246 | return Number(rows[0]?.c ?? 0) > 0 ? true : null; |
| 247 | }); |
| 248 | check('clickhouse: event carries the identified profile_id', !!profiled); |
| 249 | } |
| 250 | |
| 251 | async function main() { |
| 252 | console.log( |
no test coverage detected