async getArtifact(context) {
    const session = context.driver.defaultSession;

    const trace = context.dependencies.Trace;
    const SourceMaps = context.dependencies.SourceMaps;
    const settings = context.settings;
    const traceEngineResult =
      await TraceEngineResult.request({trace, settings, SourceMaps}, context);

    const processedTrace = await ProcessedTrace.request(trace, context);
    const {mainThreadEvents} = processedTrace;
    const navigationId = processedTrace.timeOriginEvt.args.data?.navigationId;

    const traceEngineData = await TraceElements.getTraceEngineElements(
      traceEngineResult, navigationId);
    const lcpNodeData = await TraceElements.getLcpElement(trace, context);
    const shiftsData = await TraceElements.getTopLayoutShifts(
      trace, traceEngineResult.parsedTrace, context);
    const animatedElementData = await this.getAnimatedElements(mainThreadEvents);
    const responsivenessElementData = await TraceElements.getResponsivenessElement(trace, context);

    /** @type {Map<string, TraceElementData[]>} */
    const backendNodeDataMap = new Map([
      ['trace-engine', traceEngineData],
      ['largest-contentful-paint', lcpNodeData ? [lcpNodeData] : []],
      ['layout-shift', shiftsData],
      ['animation', animatedElementData],
      ['responsiveness', responsivenessElementData ? [responsivenessElementData] : []],
    ]);

    /** @type {Map<number, LH.Crdp.Runtime.CallFunctionOnResponse | null>} */
    const callFunctionOnCache = new Map();
    /** @type {LH.Artifacts.TraceElement[]} */
    const traceElements = [];
    for (const [traceEventType, backendNodeData] of backendNodeDataMap) {
      for (let i = 0; i < backendNodeData.length; i++) {
        const backendNodeId = backendNodeData[i].nodeId;
        let response = callFunctionOnCache.get(backendNodeId);
        if (response === undefined) {
          response = await this.getNodeDetails(session, backendNodeId);
          callFunctionOnCache.set(backendNodeId, response);
        }

        if (response?.result?.value) {
          traceElements.push({
            ...response.result.value,
            traceEventType,
            animations: backendNodeData[i].animations,
            nodeId: backendNodeId,
            type: backendNodeData[i].type,
          });
        }
      }
    }

    return traceElements;
  }
@param {LH.Gatherer.Context<'Trace'|'SourceMaps'>} context
@return {Promise<LH.Artifacts.TraceElement[]>}