// Copyright 2024 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 { describeWithEnvironment } from '../../../testing/EnvironmentHelpers.js';
import { getInsightOrError, processTrace } from '../../../testing/InsightHelpers.js';
describeWithEnvironment('RenderBlocking', function () {
    it('finds render-blocking requests', async function () {
        const { data, insights } = await processTrace(this, 'load-simple.json.gz');
        assert.deepEqual([...insights.keys()], ['NAVIGATION_0']);
        const insight = getInsightOrError('RenderBlocking', insights, data.Meta.navigationsByNavigationId.values().next().value);
        assert.lengthOf(insight.renderBlockingRequests, 2);
        assert.deepEqual(insight.renderBlockingRequests.map(r => r.args.data.url), [
            'https://fonts.googleapis.com/css2?family=Orelega+One&display=swap',
            'http://localhost:8080/styles.css',
        ]);
    });
    it('returns a warning if navigation does not have a first paint event', async function () {
        const { data, insights } = await processTrace(this, 'user-timings.json.gz');
        assert.deepEqual([...insights.keys()], ['NAVIGATION_0']);
        const insight = getInsightOrError('RenderBlocking', insights, data.Meta.navigationsByNavigationId.values().next().value);
        assert.lengthOf(insight.renderBlockingRequests, 0);
        assert.strictEqual(insight.warnings?.length, 1);
        assert.strictEqual(insight.warnings?.[0], 'NO_FP');
    });
    it('considers only the navigation specified by the context', async function () {
        const { data, insights } = await processTrace(this, 'multiple-navigations-render-blocking.json.gz');
        assert.deepEqual([...insights.keys()], ['NAVIGATION_0', 'NAVIGATION_1']);
        const navigations = Array.from(data.Meta.navigationsByNavigationId.values());
        const insight = getInsightOrError('RenderBlocking', insights, navigations[0]);
        assert(insight.renderBlockingRequests.length > 0, 'no render-blocking requests found');
        assert(insight.renderBlockingRequests.every(r => r.args.data.syntheticData.sendStartTime > navigations[0].ts), 'a result is not contained by the nav bounds');
        assert(insight.renderBlockingRequests.every(r => r.args.data.syntheticData.finishTime < navigations[1].ts), 'a result is not contained by the nav bounds');
    });
    it('considers navigations separately', async function () {
        const { data, insights } = await processTrace(this, 'multiple-navigations-render-blocking.json.gz');
        assert.deepEqual([...insights.keys()], ['NAVIGATION_0', 'NAVIGATION_1']);
        const navigations = Array.from(data.Meta.navigationsByNavigationId.values());
        const insightOne = getInsightOrError('RenderBlocking', insights, navigations[0]);
        const insightTwo = getInsightOrError('RenderBlocking', insights, navigations[1]);
        assert.deepEqual(insightOne.renderBlockingRequests.map(r => r.args.data.requestId), ['99116.2']);
        assert.deepEqual(insightTwo.renderBlockingRequests.map(r => r.args.data.requestId), ['99116.5']);
    });
    it('considers only the frame specified by the context', async function () {
        const { data, insights } = await processTrace(this, 'render-blocking-in-iframe.json.gz');
        assert.deepEqual([...insights.keys()], ['NAVIGATION_0']);
        const navigations = Array.from(data.Meta.navigationsByNavigationId.values());
        const insight = getInsightOrError('RenderBlocking', insights, navigations[0]);
        assert(insight.renderBlockingRequests.length > 0, 'no render-blocking requests found');
        assert(insight.renderBlockingRequests.every(r => r.args.data.frame === data.Meta.mainFrameId), 'a result is not from the main frame');
    });
    it('ignores blocking request after first paint', async function () {
        const { data, insights } = await processTrace(this, 'parser-blocking-after-paint.json.gz');
        assert.deepEqual([...insights.keys()], ['NAVIGATION_0']);
        const insight = getInsightOrError('RenderBlocking', insights, data.Meta.navigationsByNavigationId.values().next().value);
        assert.lengthOf(insight.renderBlockingRequests, 0);
    });
    it('correctly handles body parser blocking requests', async function () {
        const { data, insights } = await processTrace(this, 'render-blocking-body.json.gz');
        assert.deepEqual([...insights.keys()], ['NAVIGATION_0']);
        const insight = getInsightOrError('RenderBlocking', insights, data.Meta.navigationsByNavigationId.values().next().value);
        assert.deepEqual(insight.renderBlockingRequests.map(r => r.args.data.url), [
            'http://localhost:8080/render-blocking/style.css',
            'http://localhost:8080/render-blocking/script.js?beforeImage',
        ]);
    });
    // TODO(crbug.com/372674229): when swapping to 'provided' instead of 'simulated', all these test traces give
    // uninteresting results. must get new traces.
    it('estimates savings with Lantern (image LCP)', async function () {
        const { data, insights } = await processTrace(this, 'lantern/render-blocking/trace.json.gz');
        assert.deepEqual([...insights.keys()], ['NAVIGATION_0']);
        const insight = getInsightOrError('RenderBlocking', insights, data.Meta.navigationsByNavigationId.values().next().value);
        assert.deepEqual(insight.metricSavings, {
            FCP: 0,
            LCP: 0,
        });
        assert.exists(insight.requestIdToWastedMs);
        const urlToWastedMs = [...insight.requestIdToWastedMs].map(([requestId, wastedMs]) => {
            const url = insight.renderBlockingRequests.find(r => r.args.data.requestId === requestId)?.args.data.url;
            return [url, wastedMs];
        });
        assert.deepEqual(urlToWastedMs, []);
    });
    it('estimates savings with Lantern (text LCP)', async function () {
        const { data, insights } = await processTrace(this, 'lantern/typescript-angular/trace.json.gz');
        assert.deepEqual([...insights.keys()], ['NAVIGATION_0']);
        const insight = getInsightOrError('RenderBlocking', insights, data.Meta.navigationsByNavigationId.values().next().value);
        assert.deepEqual(insight.metricSavings, {
            FCP: 0,
            LCP: 0,
        });
        assert.exists(insight.requestIdToWastedMs);
        const urlToWastedMs = [...insight.requestIdToWastedMs].map(([requestId, wastedMs]) => {
            const url = insight.renderBlockingRequests.find(r => r.args.data.requestId === requestId)?.args.data.url;
            return [url, wastedMs];
        });
        assert.deepEqual(urlToWastedMs, []);
    });
});
//# sourceMappingURL=RenderBlocking.test.js.map