function makeTrace(interactionEventsData) {
  let needsChildFrame = false;
  let lastTs = 0;
  for (const evtData of interactionEventsData) {
    if (evtData.inChildFrame) needsChildFrame = true;
    lastTs = Math.max(lastTs, evtData.ts);
  }

  // If there are non-mainFrame events, create a child frame in trace to add those events to.
  const childFrames = needsChildFrame ? [{frame: childFrameId}] : [];
  const trace = createTestTrace({traceEnd: lastTs + 10_000, childFrames});

  const navigationStartEvt = trace.traceEvents.find(e => e.name === 'navigationStart');
  assert(navigationStartEvt?.args?.frame);
  const mainFrameId = navigationStartEvt.args.frame;
  const {pid, tid} = navigationStartEvt;

  /** @type {Array<LH.TraceEvent>} */
  const interactionEvents = interactionEventsData.flatMap((data, index) => {
    const {
      maxDuration,
      ts,
      interactionType = 'keyboard',
      inChildFrame = false,
    } = data;

    const frame = inChildFrame ? childFrameId : mainFrameId;
    const interactionTimeStamp = (ts - navigationStartEvt.ts) / 1000;

    return [{
      name: 'Responsiveness.Renderer.UserInteraction',
      cat: 'devtools.timeline',
      ph: 'X',
      pid,
      tid,
      ts: ts,
      tts: ts,
      dur: 14,
      tdur: 14,
      args: {
        frame,
        data: {
          interactionType,
          maxDuration,
        },
      },
    }, {
      // TODO(bckenny): dynamically add all events for an interaction.
      name: 'EventTiming',
      cat: 'devtools.timeline',
      ph: 'b',
      pid,
      tid,
      ts: ts,
      id: `0x${(415583518 + index).toString(16)}`,
      scope: 'devtools.timeline',
      args: {
        data: {
          frame,
          timeStamp: interactionTimeStamp,
          processingStart: interactionTimeStamp + Math.floor(maxDuration / 3),
          processingEnd: interactionTimeStamp + Math.floor(2 * maxDuration / 3),
          duration: maxDuration,
          nodeId: 1,
          type: interactionType === 'keyboard' ? 'keydown' : 'pointerup',
          interactionId: 1,
        },
      },
    }];
  });

  trace.traceEvents.push(...interactionEvents);
  return trace;
}
@param {Array<{maxDuration: number, ts: number, interactionType?: 'keyboard'|'tapOrClick', inChildFrame?: boolean}>} interactionEventsData