mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-07 04:26:32 +08:00
DISABLE_THIRD_PARTY_CHECK=big clang format run against all files in front_end and test/ Bug: 1319340 Change-Id: I1fff63cb07544ccd0e3059fc901f9a48ff4af13b Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3598879 Reviewed-by: Alex Rudenko <alexrudenko@chromium.org> Commit-Queue: Jack Franklin <jacktfranklin@chromium.org> Reviewed-by: Wolfgang Beyer <wolfi@chromium.org>
247 lines
7.7 KiB
TypeScript
247 lines
7.7 KiB
TypeScript
// Copyright 2020 The Chromium Authors. All rights reserved.
|
|
// 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 {
|
|
$$,
|
|
click,
|
|
getBrowserAndPages,
|
|
goToResource,
|
|
step,
|
|
timeout,
|
|
waitFor,
|
|
waitForFunction,
|
|
} from '../../shared/helper.js';
|
|
import {describe, it} from '../../shared/mocha-extensions.js';
|
|
import {
|
|
addBreakpointForLine,
|
|
createSelectorsForWorkerFile,
|
|
getBreakpointDecorators,
|
|
getOpenSources,
|
|
openNestedWorkerFile,
|
|
RESUME_BUTTON,
|
|
retrieveTopCallFrameWithoutResuming,
|
|
} from '../helpers/sources-helpers.js';
|
|
|
|
async function validateSourceTabs() {
|
|
await step('Validate exactly one source file is open', async () => {
|
|
const openSources = await waitForFunction(async () => {
|
|
const sources = await getOpenSources();
|
|
return sources.length ? sources : undefined;
|
|
});
|
|
assert.deepEqual(openSources, ['multi-workers.js']);
|
|
});
|
|
}
|
|
|
|
describe('Multi-Workers', async function() {
|
|
// The tests in this suite are particularly slow, as they perform a lot of actions
|
|
if (this.timeout() !== 0) {
|
|
this.timeout(10000);
|
|
}
|
|
|
|
[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: number) {
|
|
return createSelectorsForWorkerFile(scriptFile, 'test/e2e/resources/sources', 'multi-workers.js', workerIndex);
|
|
}
|
|
|
|
async function validateNavigationTree() {
|
|
await step('Ensure 10 workers exist', async () => {
|
|
await waitFor(workerFileSelectors(10).rootSelector);
|
|
});
|
|
}
|
|
|
|
async function validateBreakpoints() {
|
|
assert.deepEqual(await getBreakpointDecorators(), [6, 12]);
|
|
assert.deepEqual(await getBreakpointDecorators(true), [6]);
|
|
}
|
|
|
|
describe(`loads scripts exactly once ${withOrWithout}`, () => {
|
|
beforeEach(async () => {
|
|
// Have the target load the page.
|
|
await goToResource(targetPage);
|
|
|
|
await step('Open sources panel', async () => {
|
|
await click('#tab-sources');
|
|
});
|
|
|
|
await validateNavigationTree();
|
|
|
|
await step('Open first worker file', async () => {
|
|
await openNestedWorkerFile(workerFileSelectors(1));
|
|
});
|
|
|
|
// Look at source tabs
|
|
await validateSourceTabs();
|
|
});
|
|
|
|
afterEach(async () => {
|
|
// Look at source tabs
|
|
await validateSourceTabs();
|
|
});
|
|
|
|
it('on reload', async () => {
|
|
// Reload page
|
|
await goToResource(targetPage);
|
|
|
|
// Check workers again
|
|
await validateNavigationTree();
|
|
});
|
|
|
|
it('upon break', async () => {
|
|
const {target} = getBrowserAndPages();
|
|
|
|
// Send message to a worker to trigger break
|
|
await target.evaluate('workers[3].postMessage({command:"break"});');
|
|
|
|
// Validate that we are paused by locating the resume button
|
|
await waitFor(RESUME_BUTTON);
|
|
});
|
|
});
|
|
|
|
it(`shows exactly one breakpoint ${withOrWithout}`, async () => {
|
|
const {frontend} = getBrowserAndPages();
|
|
// Have the target load the page.
|
|
await goToResource(targetPage);
|
|
|
|
await click('#tab-sources');
|
|
// Wait for all workers to load
|
|
await validateNavigationTree();
|
|
// Open file from second worker
|
|
await openNestedWorkerFile(workerFileSelectors(2));
|
|
// Set a breakpoint
|
|
await addBreakpointForLine(frontend, 6);
|
|
|
|
await waitFor('.breakpoint-entry');
|
|
const breakpoints = (await $$('.breakpoint-entry')).length;
|
|
assert.strictEqual(breakpoints, 1);
|
|
});
|
|
|
|
describe(`copies breakpoints between workers ${withOrWithout}`, () => {
|
|
beforeEach(async () => {
|
|
const {frontend} = getBrowserAndPages();
|
|
// Have the target load the page.
|
|
await goToResource(targetPage);
|
|
|
|
await click('#tab-sources');
|
|
// Wait for all workers to load
|
|
await validateNavigationTree();
|
|
|
|
await step('Open file from second worker', async () => {
|
|
await openNestedWorkerFile(workerFileSelectors(2));
|
|
});
|
|
|
|
await step('Set two breakpoints', async () => {
|
|
await addBreakpointForLine(frontend, 6);
|
|
});
|
|
|
|
await step('Disable first breakpoint', async () => {
|
|
const bpEntry = await waitFor('.breakpoint-entry');
|
|
const bpCheckbox = await waitFor('input', bpEntry);
|
|
await bpCheckbox.evaluate(n => (n as HTMLElement).click());
|
|
await waitFor('.cm-breakpoint-disabled');
|
|
});
|
|
|
|
await step('Add another breakpoint', async () => {
|
|
await addBreakpointForLine(frontend, 12);
|
|
});
|
|
|
|
await step('Check breakpoints', async () => {
|
|
await validateBreakpoints();
|
|
});
|
|
|
|
await step('Close tab', async () => {
|
|
await click('[aria-label="Close multi-workers.js"]');
|
|
});
|
|
});
|
|
|
|
it('when opening different file in editor', async () => {
|
|
// Open different worker
|
|
await step('Open different worker', async () => {
|
|
await openNestedWorkerFile(workerFileSelectors(3));
|
|
});
|
|
|
|
await step('Check breakpoints', async () => {
|
|
await validateBreakpoints();
|
|
});
|
|
});
|
|
|
|
it('after reloading', async () => {
|
|
const {target} = getBrowserAndPages();
|
|
|
|
await step('Reload page', async () => {
|
|
await target.reload();
|
|
});
|
|
|
|
// FIXME(crbug/1112692): Refactor test to remove the timeout.
|
|
await timeout(100);
|
|
|
|
await step('Open different worker', async () => {
|
|
await openNestedWorkerFile(workerFileSelectors(4));
|
|
});
|
|
|
|
await step('Check breakpoints', async () => {
|
|
await waitFor('.cm-breakpoint');
|
|
await validateBreakpoints();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe(`hits breakpoints added to workers ${withOrWithout}`, () => {
|
|
beforeEach(async () => {
|
|
const {frontend} = getBrowserAndPages();
|
|
|
|
// Have the target load the page.
|
|
await goToResource(targetPage);
|
|
|
|
await step('Open sources panel', async () => {
|
|
await click('#tab-sources');
|
|
});
|
|
|
|
await validateNavigationTree();
|
|
|
|
await step('Open second worker file', async () => {
|
|
await openNestedWorkerFile(workerFileSelectors(2));
|
|
});
|
|
|
|
await step('Set breakpoint', async () => {
|
|
await addBreakpointForLine(frontend, 6);
|
|
});
|
|
});
|
|
|
|
it('for pre-loaded workers', async () => {
|
|
const {target} = getBrowserAndPages();
|
|
// Send message to a worker to trigger break
|
|
await target.evaluate('workers[5].postMessage({});');
|
|
|
|
// Validate that we are paused by locating the resume button
|
|
await waitFor(RESUME_BUTTON);
|
|
|
|
// Validate that the code has paused on the breakpoint at the correct script location
|
|
assert.deepEqual(await retrieveTopCallFrameWithoutResuming(), 'multi-workers.js:6');
|
|
|
|
// Look at source tabs
|
|
await validateSourceTabs();
|
|
});
|
|
|
|
it('for newly created workers', async () => {
|
|
const {target} = getBrowserAndPages();
|
|
// Launch new worker to hit breakpoint
|
|
await target.evaluate(`new Worker('${scriptFile}').postMessage({});`);
|
|
|
|
// Validate that we are paused by locating the resume button
|
|
await waitFor(RESUME_BUTTON);
|
|
|
|
// Validate that the code has paused on the breakpoint at the correct script location
|
|
assert.deepEqual(await retrieveTopCallFrameWithoutResuming(), 'multi-workers.js:6');
|
|
|
|
await validateSourceTabs();
|
|
});
|
|
});
|
|
});
|
|
});
|