Haha, @thdxr had the exact same question when I shared a preview with him before hand. I'll copy in my same answer:
We have a setup that saves events in DynamoDB and the tests assert based on that. Slightly more complicated, but not that difficult to setup:
1. Conditionally in CDK, depending on the environment (where we run tests, i.e. not prod yet), create:
a. A dynamodb table where pk is the workspace id (or whatever tenant id you have) sk is the event's timestamp (or in our case just the id since we use ulid). We also have an expiry timestamp to not store these test events forever.
b. A lambda (non sst / live reload) that receives an event and writes out the event to the dynamodb table. This relies on our events having a standard event envelope structure and being able to determine the workspace id + the event id without knowing every possible payload.
c. Add a catch-all rule to each eventbridge eventbus that routes all events on the bus to the event writer lambda
2. Then in our tests we just do a query for all events in the pk (and get a sorted array as they were received). This is done in an eventually block, i.e. keeps retrying until the expect passes or it times out. Since it picks up ALL events in a workspace, we have quite a few helpers to make sure we're expecting on the things that matter for that specific test, like:
a. expectEvents: strict match
b. expectSomeEvents: array containing match
c. expectSomeEventsExcept: strict match excluding some event types
d. expectNoEvents: wait for N seconds and expect 0 elements
e. expectAnyEvents: any event just passes this
All in all, this works quite well. The sad thing is that eventbridge is slow, i.e. best case it's like 400-500ms worst case we've seen delays up to a 2-5 seconds.