"use strict";
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const sources_helpers_js_1 = require("../helpers/sources-helpers.js");
async function validateSourceTabs(devToolsPage) {
    const openSources = await devToolsPage.waitForFunction(async () => {
        const sources = await (0, sources_helpers_js_1.getOpenSources)(devToolsPage);
        return sources.length ? sources : undefined;
    });
    chai_1.assert.deepEqual(openSources, ['multi-workers.js']);
}
describe('Multi-Workers', function () {
    [false, true].forEach(sourceMaps => {
        const withOrWithout = sourceMaps ? 'with source maps' : 'without source maps';
        const targetPage = sourceMaps ? 'sources/multi-workers-sourcemap.html' : 'sources/multi-workers.html';
        const scriptFile = sourceMaps ? 'multi-workers.min.js' : 'multi-workers.js';
        function workerFileSelectors(workerIndex, inspectedPage) {
            return (0, sources_helpers_js_1.createSelectorsForWorkerFile)(scriptFile, 'test/e2e/resources/sources', 'multi-workers.js', workerIndex, inspectedPage);
        }
        async function validateNavigationTree(devToolsPage, inspectedPage) {
            await devToolsPage.waitFor(workerFileSelectors(10, inspectedPage).rootSelector);
        }
        async function validateBreakpoints(devToolsPage) {
            await (0, sources_helpers_js_1.waitForLines)(12, devToolsPage);
            // Wait for breakpoints to be present
            await devToolsPage.waitFor('.cm-gutterElement ~ .cm-breakpoint ~ .cm-breakpoint');
            chai_1.assert.deepEqual(await (0, sources_helpers_js_1.getBreakpointDecorators)(false, 2, devToolsPage), [6, 12]);
            chai_1.assert.deepEqual(await (0, sources_helpers_js_1.getBreakpointDecorators)(true, 1, devToolsPage), [6]);
        }
        describe(`loads scripts exactly once ${withOrWithout}`, () => {
            it('but still distinguishes between the workers', async ({ devToolsPage, inspectedPage }) => {
                // Have the target load the page.
                await inspectedPage.goToResource(targetPage);
                await devToolsPage.click('#tab-sources');
                await validateNavigationTree(devToolsPage, inspectedPage);
                await devToolsPage.installEventListener(sources_helpers_js_1.DEBUGGER_PAUSED_EVENT);
                await inspectedPage.evaluate('workers[3].postMessage({command:"break"});');
                await devToolsPage.waitFor(sources_helpers_js_1.RESUME_BUTTON);
                await devToolsPage.waitFor(sources_helpers_js_1.PAUSE_INDICATOR_SELECTOR);
                await devToolsPage.waitForFunction(async () => await devToolsPage.getPendingEvents(sources_helpers_js_1.DEBUGGER_PAUSED_EVENT));
                await (0, sources_helpers_js_1.executionLineHighlighted)(devToolsPage);
                // Look at source tabs
                await validateSourceTabs(devToolsPage);
                const selectedFile = workerFileSelectors(1, inspectedPage).fileSelector + '[aria-selected="true"]';
                const expandedWorker = workerFileSelectors(1, inspectedPage).rootSelector + '[aria-expanded="true"]';
                await devToolsPage.waitFor(selectedFile);
                const workers = await devToolsPage.$$(expandedWorker);
                chai_1.assert.lengthOf(workers, 1);
                // Send message to a worker to a different worker to cause a different file to be
                // selected in the page tree
                await inspectedPage.evaluate('workers[5].postMessage({command:"break"});');
                // This typically happens too quickly to cause DevTools to switch to the other thread, so
                // click on the other paused thread.
                await devToolsPage.waitFor(sources_helpers_js_1.THREADS_SELECTOR + '[aria-expanded="true"]');
                await devToolsPage.click('.thread-item:has( .thread-item-paused-state:not(:empty))[aria-selected="false"]');
                // Now two workers are expanded
                await devToolsPage.waitFor(expandedWorker + ' ~ ' + expandedWorker);
                // And still only one source tab
                await validateSourceTabs(devToolsPage);
            });
        });
        describe(`loads scripts exactly once ${withOrWithout}`, () => {
            async function setupTest(devToolsPage, inspectedPage) {
                // Have the target load the page.
                await inspectedPage.goToResource(targetPage);
                await devToolsPage.click('#tab-sources');
                await validateNavigationTree(devToolsPage, inspectedPage);
                await (0, sources_helpers_js_1.openNestedWorkerFile)(workerFileSelectors(1, inspectedPage), devToolsPage);
                // Look at source tabs
                await validateSourceTabs(devToolsPage);
            }
            it('on reload', async ({ devToolsPage, inspectedPage }) => {
                await setupTest(devToolsPage, inspectedPage);
                // Reload page
                await inspectedPage.goToResource(targetPage);
                // Check workers again
                await validateNavigationTree(devToolsPage, inspectedPage);
                await validateSourceTabs(devToolsPage);
            });
            it('upon break', async ({ devToolsPage, inspectedPage }) => {
                await setupTest(devToolsPage, inspectedPage);
                // Send message to a worker to trigger break
                await inspectedPage.evaluate('workers[3].postMessage({command:"break"});');
                // Validate that we are paused by locating the resume button
                await devToolsPage.waitFor(sources_helpers_js_1.RESUME_BUTTON);
                await validateSourceTabs(devToolsPage);
            });
        });
        it(`shows exactly one breakpoint ${withOrWithout}`, async ({ devToolsPage, inspectedPage }) => {
            await (0, sources_helpers_js_1.waitForSourceFiles)("source-file-loaded" /* SourceFileEvents.SOURCE_FILE_LOADED */, files => files.some(f => f.endsWith('multi-workers.js')), async () => {
                // Have the target load the page.
                await inspectedPage.goToResource(targetPage);
                await devToolsPage.click('#tab-sources');
                // Wait for all workers to load
                await validateNavigationTree(devToolsPage, inspectedPage);
                // Open file from second worker
                await (0, sources_helpers_js_1.openNestedWorkerFile)(workerFileSelectors(2, inspectedPage), devToolsPage);
            }, devToolsPage);
            // Set a breakpoint
            await (0, sources_helpers_js_1.addBreakpointForLine)(6, devToolsPage);
            await devToolsPage.waitFor(sources_helpers_js_1.BREAKPOINT_ITEM_SELECTOR);
            const breakpoints = (await devToolsPage.$$(sources_helpers_js_1.BREAKPOINT_ITEM_SELECTOR)).length;
            chai_1.assert.strictEqual(breakpoints, 1);
        });
        describe(`copies breakpoints between workers ${withOrWithout}`, () => {
            async function setupBreakpoints({ devToolsPage, inspectedPage }) {
                await (0, sources_helpers_js_1.waitForSourceFiles)("source-file-loaded" /* SourceFileEvents.SOURCE_FILE_LOADED */, files => files.some(f => f.endsWith('multi-workers.js')), async () => {
                    // Have the target load the page.
                    await inspectedPage.goToResource(targetPage);
                    await devToolsPage.click('#tab-sources');
                    // Wait for all workers to load
                    await validateNavigationTree(devToolsPage, inspectedPage);
                    await (0, sources_helpers_js_1.openNestedWorkerFile)(workerFileSelectors(2, inspectedPage), devToolsPage);
                }, devToolsPage);
                await (0, sources_helpers_js_1.addBreakpointForLine)(6, devToolsPage);
                const bpEntry = await devToolsPage.waitFor(sources_helpers_js_1.BREAKPOINT_ITEM_SELECTOR);
                const bpCheckbox = await bpEntry?.$('input');
                chai_1.assert.isOk(bpCheckbox);
                await bpCheckbox.click();
                await devToolsPage.waitFor('.cm-breakpoint-disabled');
                await (0, sources_helpers_js_1.addBreakpointForLine)(12, devToolsPage);
                await validateBreakpoints(devToolsPage);
                await devToolsPage.click('[aria-label="Close multi-workers.js"]');
            }
            it('when opening different file in editor', async ({ devToolsPage, inspectedPage }) => {
                await setupBreakpoints({ devToolsPage, inspectedPage });
                // Open different worker
                await (0, sources_helpers_js_1.openNestedWorkerFile)(workerFileSelectors(3, inspectedPage), devToolsPage);
                await validateBreakpoints(devToolsPage);
            });
            it('after reloading', async ({ devToolsPage, inspectedPage }) => {
                await setupBreakpoints({ devToolsPage, inspectedPage });
                await inspectedPage.reload();
                // FIXME(crbug/1112692): Refactor test to remove the timeout.
                await devToolsPage.timeout(100);
                await (0, sources_helpers_js_1.openNestedWorkerFile)(workerFileSelectors(4, inspectedPage), devToolsPage);
                await devToolsPage.waitFor('.cm-breakpoint');
                await validateBreakpoints(devToolsPage);
            });
        });
        describe(`hits breakpoints added to workers ${withOrWithout}`, () => {
            setup({ enabledDevToolsExperiments: ['instrumentation-breakpoints'] });
            async function setupInstrumentationBreakpoints(devToolsPage, inspectedPage) {
                await (0, sources_helpers_js_1.waitForSourceFiles)("source-file-loaded" /* SourceFileEvents.SOURCE_FILE_LOADED */, files => files.some(f => f.endsWith('multi-workers.js')), async () => {
                    // Have the target load the page.
                    await inspectedPage.goToResource(targetPage);
                    await devToolsPage.click('#tab-sources');
                    await validateNavigationTree(devToolsPage, inspectedPage);
                    await (0, sources_helpers_js_1.openNestedWorkerFile)(workerFileSelectors(2, inspectedPage), devToolsPage);
                }, devToolsPage);
                await (0, sources_helpers_js_1.addBreakpointForLine)(6, devToolsPage);
            }
            it('for pre-loaded workers', async ({ devToolsPage, inspectedPage }) => {
                await setupInstrumentationBreakpoints(devToolsPage, inspectedPage);
                // Send message to a worker to trigger break
                await inspectedPage.evaluate('workers[5].postMessage({});');
                // Validate that we are paused by locating the resume button
                await devToolsPage.waitFor(sources_helpers_js_1.RESUME_BUTTON);
                // Validate that the code has paused on the breakpoint at the correct script location
                chai_1.assert.deepEqual(await (0, sources_helpers_js_1.retrieveTopCallFrameWithoutResuming)(devToolsPage), 'multi-workers.js:6');
                // Look at source tabs
                await validateSourceTabs(devToolsPage);
            });
            it('for newly created workers', async ({ devToolsPage, inspectedPage }) => {
                await setupInstrumentationBreakpoints(devToolsPage, inspectedPage);
                // Launch new worker to hit breakpoint
                await inspectedPage.evaluate(`new Worker('${scriptFile}').postMessage({});`);
                // Validate that we are paused by locating the resume button
                await devToolsPage.waitFor(sources_helpers_js_1.RESUME_BUTTON);
                // Validate that the code has paused on the breakpoint at the correct script location
                chai_1.assert.deepEqual(await (0, sources_helpers_js_1.retrieveTopCallFrameWithoutResuming)(devToolsPage), 'multi-workers.js:6');
                await validateSourceTabs(devToolsPage);
            });
        });
    });
});
//# sourceMappingURL=script-in-multiple-workers.test.js.map