// Copyright 2022 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 sinon from 'sinon';
import * as SDK from '../../core/sdk/sdk.js';
import { stripLitHtmlCommentNodes } from '../../testing/DOMHelpers.js';
import { createTarget } from '../../testing/EnvironmentHelpers.js';
import { describeWithMockConnection } from '../../testing/MockConnection.js';
import * as UI from '../../ui/legacy/legacy.js';
import { html } from '../../ui/lit/lit.js';
import * as PanelsCommon from '../common/common.js';
describeWithMockConnection('LighthouseReportRenderer', () => {
    // eslint-disable-next-line @typescript-eslint/naming-convention
    let Lighthouse;
    let target;
    let sourceElement;
    let linkElement;
    const PATH = 'TEST_PATH';
    const NODE_ID = 42;
    const NODE = sinon.createStubInstance(SDK.DOMModel.DOMNode);
    NODE.id = NODE_ID;
    const SNIPPET = 'SNIPPET';
    const LH_NODE_HTML = (path, snippet) => `<div class="lh-node" data-path="${path}" data-snippet="${snippet}"></div>`;
    beforeEach(async () => {
        Lighthouse = await import('./lighthouse.js');
        const tabTarget = createTarget({ type: SDK.Target.Type.TAB });
        createTarget({ parentTarget: tabTarget, subtype: 'prerender' });
        target = createTarget({ parentTarget: tabTarget });
        linkElement = document.createElement('div');
        linkElement.textContent = 'link';
        sourceElement = document.createElement('div');
    });
    it('resolves node and calls linkifier', async () => {
        sourceElement.innerHTML = LH_NODE_HTML(PATH, SNIPPET);
        const domModel = target.model(SDK.DOMModel.DOMModel);
        assert.exists(domModel);
        sinon.stub(domModel, 'pushNodeByPathToFrontend').withArgs(PATH).returns(Promise.resolve(NODE_ID));
        sinon.stub(domModel, 'nodeForId').withArgs(NODE_ID).returns(NODE);
        sinon.stub(PanelsCommon.DOMLinkifier.Linkifier.instance(), 'linkify')
            .withArgs(NODE, { tooltip: SNIPPET, preventKeyboardFocus: undefined })
            .returns(html `<div>link</div>`);
        await Lighthouse.LighthouseReportRenderer.LighthouseReportRenderer.linkifyNodeDetails(sourceElement);
        assert.strictEqual(stripLitHtmlCommentNodes(sourceElement.firstChild.innerHTML), '<div>link</div>');
    });
    it('handles multiple nodes', async () => {
        const domModel = target.model(SDK.DOMModel.DOMModel);
        assert.exists(domModel);
        const pushNodeByPathToFrontend = sinon.stub(domModel, 'pushNodeByPathToFrontend');
        const nodeForId = sinon.stub(domModel, 'nodeForId');
        const linkify = sinon.stub(PanelsCommon.DOMLinkifier.Linkifier.instance(), 'linkify');
        const NUM_NODES = 3;
        for (let i = 1; i <= NUM_NODES; ++i) {
            sourceElement.innerHTML += LH_NODE_HTML(PATH + i, SNIPPET + i);
            const nodeId = i;
            const node = { id: nodeId };
            pushNodeByPathToFrontend.withArgs(PATH + i).returns(Promise.resolve(nodeId));
            nodeForId.withArgs(nodeId).returns(node);
            linkify.withArgs(node, { tooltip: SNIPPET + i, preventKeyboardFocus: undefined })
                .returns(html `<div>link${i}</div>`);
        }
        await Lighthouse.LighthouseReportRenderer.LighthouseReportRenderer.linkifyNodeDetails(sourceElement);
        assert.strictEqual(sourceElement.childNodes.length, NUM_NODES);
        assert.deepEqual([...sourceElement.childNodes].map(n => n.textContent), ['link1', 'link2', 'link3']);
    });
    it('resets tooltip', async () => {
        sourceElement.innerHTML = LH_NODE_HTML(PATH, SNIPPET);
        const domModel = target.model(SDK.DOMModel.DOMModel);
        assert.exists(domModel);
        sinon.stub(domModel, 'pushNodeByPathToFrontend').returns(Promise.resolve(NODE_ID));
        sinon.stub(domModel, 'nodeForId').returns(NODE);
        sinon.stub(PanelsCommon.DOMLinkifier.Linkifier.instance(), 'linkify').returns(html `<div>link</div>`);
        const installTooltip = sinon.spy(UI.Tooltip.Tooltip, 'install');
        await Lighthouse.LighthouseReportRenderer.LighthouseReportRenderer.linkifyNodeDetails(sourceElement);
        assert.isTrue(installTooltip.calledOnceWith(sourceElement.firstChild, ''));
    });
    it('only keeps link and screenshot', async () => {
        sourceElement.innerHTML = LH_NODE_HTML(PATH, SNIPPET);
        assert.exists(sourceElement.firstElementChild);
        sourceElement.firstElementChild.innerHTML = 'foo<div class="lh-element-screenshot"></div>bar';
        const domModel = target.model(SDK.DOMModel.DOMModel);
        assert.exists(domModel);
        sinon.stub(domModel, 'pushNodeByPathToFrontend').returns(Promise.resolve(NODE_ID));
        sinon.stub(domModel, 'nodeForId').returns(NODE);
        sinon.stub(PanelsCommon.DOMLinkifier.Linkifier.instance(), 'linkify').returns(html `<div>link</div>`);
        await Lighthouse.LighthouseReportRenderer.LighthouseReportRenderer.linkifyNodeDetails(sourceElement);
        assert.strictEqual(stripLitHtmlCommentNodes(sourceElement.firstElementChild.innerHTML), '<div class="lh-element-screenshot"></div><div>link</div>');
    });
    it('skips malformed nodes', async () => {
        const originalHtml = [
            LH_NODE_HTML('', SNIPPET),
            LH_NODE_HTML('UNKNOWN_PATH', SNIPPET),
            LH_NODE_HTML('PATH_WIHTOUT_NODE', SNIPPET),
        ].join('');
        const domModel = target.model(SDK.DOMModel.DOMModel);
        assert.exists(domModel);
        sinon.stub(domModel, 'pushNodeByPathToFrontend').withArgs('PATH_WIHTOUT_NODE').returns(Promise.resolve(NODE_ID));
        sourceElement.innerHTML = originalHtml;
        await Lighthouse.LighthouseReportRenderer.LighthouseReportRenderer.linkifyNodeDetails(sourceElement);
        assert.strictEqual(sourceElement.innerHTML, originalHtml);
    });
    it('renders lighthouse scores and strips out topbar', async () => {
        const lhr = {
            finalDisplayedUrl: 'http://example.com',
            configSettings: {},
            audits: {},
            categories: {
                performance: { auditRefs: [], id: 'performance', score: 0.8 },
                accessibility: { auditRefs: [], id: 'accessibility', score: 0.9 },
            },
            lighthouseVersion: '',
            userAgent: '',
            fetchTime: 0,
            environment: { benchmarkIndex: 0 },
            i18n: { rendererFormattedStrings: {} },
        };
        const el = Lighthouse.LighthouseReportRenderer.LighthouseReportRenderer.renderLighthouseScores(lhr);
        assert.isNotNull(el);
        assert.isNotNull(el?.querySelector('.lh-scores-header'));
        assert.isNull(el?.querySelector('.lh-topbar'));
    });
});
//# sourceMappingURL=LighthouseReportRenderer.test.js.map