// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { assert } from 'chai';
import * as Trace from '../../../models/trace/trace.js';
import { describeWithEnvironment } from '../../../testing/EnvironmentHelpers.js';
import { TraceLoader } from '../../../testing/TraceLoader.js';
import * as PerfUI from '../../../ui/legacy/components/perf_ui/perf_ui.js';
import * as Timeline from '../timeline.js';
function initTrackAppender(flameChartData, parsedTrace, entryData, entryTypeByLevel) {
    const entityMapper = new Trace.EntityMapper.EntityMapper(parsedTrace);
    const compatibilityTracksAppender = new Timeline.CompatibilityTracksAppender.CompatibilityTracksAppender(flameChartData, parsedTrace, entryData, entryTypeByLevel, entityMapper);
    return compatibilityTracksAppender.layoutShiftsTrackAppender();
}
describeWithEnvironment('LayoutShiftsTrackAppender', function () {
    async function renderTrackAppender(context, trace) {
        const entryTypeByLevel = [];
        const entryData = [];
        const flameChartData = PerfUI.FlameChart.FlameChartTimelineData.createEmpty();
        const parsedTrace = await TraceLoader.traceEngine(context, trace);
        const layoutShiftsTrackAppender = initTrackAppender(flameChartData, parsedTrace, entryData, entryTypeByLevel);
        layoutShiftsTrackAppender.appendTrackAtLevel(0);
        return {
            entryTypeByLevel,
            parsedTrace,
            flameChartData,
            layoutShiftsTrackAppender,
            entryData,
        };
    }
    it('marks all levels used by the track with the TrackAppender type', async function () {
        const { entryTypeByLevel } = await renderTrackAppender(this, 'cls-single-frame.json.gz');
        // Only one row of layout shifts.
        assert.lengthOf(entryTypeByLevel, 1);
        assert.deepEqual(entryTypeByLevel, [
            "TrackAppender" /* Timeline.TimelineFlameChartDataProvider.EntryType.TRACK_APPENDER */,
        ]);
    });
    it('does not append anything if there are no layout shifts', async function () {
        // No layout shifts.
        const { entryTypeByLevel } = await renderTrackAppender(this, 'animation.json.gz');
        assert.lengthOf(entryTypeByLevel, 0);
    });
    it('creates a flamechart group', async function () {
        const { flameChartData } = await renderTrackAppender(this, 'cls-single-frame.json.gz');
        assert.lengthOf(flameChartData.groups, 1);
        assert.strictEqual(flameChartData.groups[0].name, 'Layout shifts');
    });
    it('adds all layout shifts with the correct start times', async function () {
        const { flameChartData, parsedTrace, entryData } = await renderTrackAppender(this, 'cls-single-frame.json.gz');
        const events = parsedTrace.data.LayoutShifts.clusters.flatMap(c => c.events);
        for (const event of events) {
            const markerIndex = entryData.indexOf(event);
            assert.exists(markerIndex);
            assert.strictEqual(flameChartData.entryStartTimes[markerIndex], Trace.Helpers.Timing.microToMilli(event.ts));
        }
    });
    it('does not define any title for a layout shift or a cluster', async () => {
        const { layoutShiftsTrackAppender, parsedTrace } = await renderTrackAppender(this, 'cls-no-nav.json.gz');
        const cluster = parsedTrace.data.LayoutShifts.clusters.at(0);
        assert.isOk(cluster);
        const shift = cluster.events.at(0);
        assert.isOk(shift);
        assert.strictEqual(layoutShiftsTrackAppender.titleForEvent(cluster), '');
        assert.strictEqual(layoutShiftsTrackAppender.titleForEvent(shift), '');
    });
    it('shows "Layout shift" tooltip on hover', async function () {
        const { layoutShiftsTrackAppender, parsedTrace } = await renderTrackAppender(this, 'cls-no-nav.json.gz');
        const shifts = parsedTrace.data.LayoutShifts.clusters.flatMap(c => c.events);
        await layoutShiftsTrackAppender.preloadScreenshots(shifts);
        const info = {
            title: 'title',
            formattedTime: 'time',
            warningElements: [],
            additionalElements: [],
            url: null,
        };
        layoutShiftsTrackAppender.setPopoverInfo(shifts[3], info);
        assert.strictEqual(info.title, 'Layout shift');
        assert.strictEqual(info.formattedTime, '0.0197');
        assert.strictEqual(info.additionalElements?.at(0)?.nodeName, 'DIV');
    });
});
//# sourceMappingURL=LayoutShiftsTrackAppender.test.js.map