chore: make sw global in trace viewer (#9431)
This commit is contained in:
parent
8ae926efbf
commit
9dfc0a3394
|
|
@ -14,12 +14,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as http from 'http';
|
import http from 'http';
|
||||||
import querystring from 'querystring';
|
import path from 'path';
|
||||||
import { HttpServer } from '../../utils/httpServer';
|
import { HttpServer } from '../../utils/httpServer';
|
||||||
import type { RenderedFrameSnapshot, ResourceSnapshot } from './snapshotTypes';
|
import type { ResourceSnapshot } from './snapshotTypes';
|
||||||
import { SnapshotStorage } from './snapshotStorage';
|
import { SnapshotStorage } from './snapshotStorage';
|
||||||
import type { Point } from '../../common/types';
|
import type { Point } from '../../common/types';
|
||||||
|
import { URLSearchParams } from 'url';
|
||||||
|
|
||||||
export class SnapshotServer {
|
export class SnapshotServer {
|
||||||
private _snapshotStorage: SnapshotStorage;
|
private _snapshotStorage: SnapshotStorage;
|
||||||
|
|
@ -27,6 +28,10 @@ export class SnapshotServer {
|
||||||
constructor(server: HttpServer, snapshotStorage: SnapshotStorage) {
|
constructor(server: HttpServer, snapshotStorage: SnapshotStorage) {
|
||||||
this._snapshotStorage = snapshotStorage;
|
this._snapshotStorage = snapshotStorage;
|
||||||
|
|
||||||
|
server.routePrefix('/snapshot/sw.bundle.js', (request, response) => {
|
||||||
|
server.serveFile(response, path.join(__dirname, '..', '..', 'web', 'traceViewer', 'sw.bundle.js'));
|
||||||
|
return true;
|
||||||
|
});
|
||||||
server.routePrefix('/snapshot/', this._serveSnapshot.bind(this));
|
server.routePrefix('/snapshot/', this._serveSnapshot.bind(this));
|
||||||
server.routePrefix('/snapshotSize/', this._serveSnapshotSize.bind(this));
|
server.routePrefix('/snapshotSize/', this._serveSnapshotSize.bind(this));
|
||||||
server.routePrefix('/resources/', this._serveResource.bind(this));
|
server.routePrefix('/resources/', this._serveResource.bind(this));
|
||||||
|
|
@ -60,103 +65,25 @@ export class SnapshotServer {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _serveServiceWorker(request: http.IncomingMessage, response: http.ServerResponse): boolean {
|
|
||||||
function serviceWorkerMain(self: any /* ServiceWorkerGlobalScope */) {
|
|
||||||
const kBlobUrlPrefix = 'http://playwright.bloburl/#';
|
|
||||||
const snapshotIds = new Map<string, { frameId: string, index: number }>();
|
|
||||||
|
|
||||||
self.addEventListener('install', function(event: any) {
|
|
||||||
});
|
|
||||||
|
|
||||||
self.addEventListener('activate', function(event: any) {
|
|
||||||
event.waitUntil(self.clients.claim());
|
|
||||||
});
|
|
||||||
|
|
||||||
function respondNotAvailable(): Response {
|
|
||||||
return new Response('<body style="background: #ddd"></body>', { status: 200, headers: { 'Content-Type': 'text/html' } });
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeHash(url: string) {
|
|
||||||
try {
|
|
||||||
const u = new URL(url);
|
|
||||||
u.hash = '';
|
|
||||||
return u.toString();
|
|
||||||
} catch (e) {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function doFetch(event: any /* FetchEvent */): Promise<Response> {
|
|
||||||
const request = event.request;
|
|
||||||
const pathname = new URL(request.url).pathname;
|
|
||||||
if (pathname === '/snapshot/service-worker.js' || pathname === '/snapshot/')
|
|
||||||
return fetch(event.request);
|
|
||||||
|
|
||||||
const snapshotUrl = request.mode === 'navigate' ?
|
|
||||||
request.url : (await self.clients.get(event.clientId))!.url;
|
|
||||||
|
|
||||||
if (request.mode === 'navigate') {
|
|
||||||
const htmlResponse = await fetch(event.request);
|
|
||||||
const { html, frameId, index }: RenderedFrameSnapshot = await htmlResponse.json();
|
|
||||||
if (!html)
|
|
||||||
return respondNotAvailable();
|
|
||||||
snapshotIds.set(snapshotUrl, { frameId, index });
|
|
||||||
const response = new Response(html, { status: 200, headers: { 'Content-Type': 'text/html' } });
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { frameId, index } = snapshotIds.get(snapshotUrl)!;
|
|
||||||
const url = request.url.startsWith(kBlobUrlPrefix) ? request.url.substring(kBlobUrlPrefix.length) : removeHash(request.url);
|
|
||||||
const complexUrl = btoa(JSON.stringify({ frameId, index, url }));
|
|
||||||
const fetchUrl = `/resources/${complexUrl}`;
|
|
||||||
const fetchedResponse = await fetch(fetchUrl);
|
|
||||||
// We make a copy of the response, instead of just forwarding,
|
|
||||||
// so that response url is not inherited as "/resources/...", but instead
|
|
||||||
// as the original request url.
|
|
||||||
|
|
||||||
// Response url turns into resource base uri that is used to resolve
|
|
||||||
// relative links, e.g. url(/foo/bar) in style sheets.
|
|
||||||
const headers = new Headers(fetchedResponse.headers);
|
|
||||||
const response = new Response(fetchedResponse.body, {
|
|
||||||
status: fetchedResponse.status,
|
|
||||||
statusText: fetchedResponse.statusText,
|
|
||||||
headers,
|
|
||||||
});
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.addEventListener('fetch', function(event: any) {
|
|
||||||
event.respondWith(doFetch(event));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
response.statusCode = 200;
|
|
||||||
response.setHeader('Cache-Control', 'public, max-age=31536000');
|
|
||||||
response.setHeader('Content-Type', 'application/javascript');
|
|
||||||
response.end(`(${serviceWorkerMain.toString()})(self)`);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _serveSnapshot(request: http.IncomingMessage, response: http.ServerResponse): boolean {
|
private _serveSnapshot(request: http.IncomingMessage, response: http.ServerResponse): boolean {
|
||||||
if (request.url!.endsWith('/snapshot/'))
|
const { pathname, searchParams } = new URL('http://localhost' + request.url);
|
||||||
|
if (pathname.endsWith('/snapshot/'))
|
||||||
return this._serveSnapshotRoot(request, response);
|
return this._serveSnapshotRoot(request, response);
|
||||||
if (request.url!.endsWith('/snapshot/service-worker.js'))
|
const snapshot = this._snapshot(pathname.substring('/snapshot'.length), searchParams);
|
||||||
return this._serveServiceWorker(request, response);
|
|
||||||
const snapshot = this._snapshot(request.url!.substring('/snapshot/'.length));
|
|
||||||
this._respondWithJson(response, snapshot ? snapshot.render() : { html: '' });
|
this._respondWithJson(response, snapshot ? snapshot.render() : { html: '' });
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _serveSnapshotSize(request: http.IncomingMessage, response: http.ServerResponse): boolean {
|
private _serveSnapshotSize(request: http.IncomingMessage, response: http.ServerResponse): boolean {
|
||||||
const snapshot = this._snapshot(request.url!.substring('/snapshotSize/'.length));
|
const { pathname, searchParams } = new URL('http://localhost' + request.url);
|
||||||
|
const snapshot = this._snapshot(pathname.substring('/snapshotSize'.length), searchParams);
|
||||||
this._respondWithJson(response, snapshot ? snapshot.viewport() : {});
|
this._respondWithJson(response, snapshot ? snapshot.viewport() : {});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _snapshot(uri: string) {
|
private _snapshot(pathname: string, params: URLSearchParams) {
|
||||||
const [ pageOrFrameId, query ] = uri.split('?');
|
const name = params.get('name')!;
|
||||||
const parsed: any = querystring.parse(query);
|
return this._snapshotStorage.snapshotByName(pathname.slice(1), name);
|
||||||
return this._snapshotStorage.snapshotByName(pageOrFrameId, parsed.name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _respondWithJson(response: http.ServerResponse, object: any) {
|
private _respondWithJson(response: http.ServerResponse, object: any) {
|
||||||
|
|
@ -220,9 +147,8 @@ declare global {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function rootScript() {
|
function rootScript() {
|
||||||
if (!navigator.serviceWorker)
|
if (window.location.href.endsWith('serviceWorkerForTest'))
|
||||||
return;
|
navigator.serviceWorker.register('sw.bundle.js');
|
||||||
navigator.serviceWorker.register('./service-worker.js');
|
|
||||||
let showPromise = Promise.resolve();
|
let showPromise = Promise.resolve();
|
||||||
if (!navigator.serviceWorker.controller) {
|
if (!navigator.serviceWorker.controller) {
|
||||||
showPromise = new Promise(resolve => {
|
showPromise = new Promise(resolve => {
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ export class TraceViewer {
|
||||||
// - "/tracemodel" - json with trace model.
|
// - "/tracemodel" - json with trace model.
|
||||||
//
|
//
|
||||||
// Served by TraceViewer
|
// Served by TraceViewer
|
||||||
// - "/traceviewer/..." - our frontend.
|
// - "/" - our frontend.
|
||||||
// - "/file?filePath" - local files, used by sources tab.
|
// - "/file?filePath" - local files, used by sources tab.
|
||||||
// - "/sha1/<sha1>" - trace resource bodies, used by network previews.
|
// - "/sha1/<sha1>" - trace resource bodies, used by network previews.
|
||||||
//
|
//
|
||||||
|
|
@ -58,7 +58,6 @@ export class TraceViewer {
|
||||||
// - "/resources/" - network resources from the trace.
|
// - "/resources/" - network resources from the trace.
|
||||||
// - "/snapshot/" - root for snapshot frame.
|
// - "/snapshot/" - root for snapshot frame.
|
||||||
// - "/snapshot/pageId/..." - actual snapshot html.
|
// - "/snapshot/pageId/..." - actual snapshot html.
|
||||||
// - "/snapshot/service-worker.js" - service worker that intercepts snapshot resources
|
|
||||||
// and translates them into network requests.
|
// and translates them into network requests.
|
||||||
const entries = await this._vfs.entries();
|
const entries = await this._vfs.entries();
|
||||||
const debugNames = entries.filter(name => name.endsWith('.trace')).map(name => {
|
const debugNames = entries.filter(name => name.endsWith('.trace')).map(name => {
|
||||||
|
|
@ -95,13 +94,6 @@ export class TraceViewer {
|
||||||
};
|
};
|
||||||
this._server.routePrefix('/context/', traceModelHandler);
|
this._server.routePrefix('/context/', traceModelHandler);
|
||||||
|
|
||||||
const traceViewerHandler: ServerRouteHandler = (request, response) => {
|
|
||||||
const relativePath = request.url!.substring('/traceviewer/'.length);
|
|
||||||
const absolutePath = path.join(__dirname, '..', '..', '..', 'web', ...relativePath.split('/'));
|
|
||||||
return this._server.serveFile(response, absolutePath);
|
|
||||||
};
|
|
||||||
this._server.routePrefix('/traceviewer/', traceViewerHandler);
|
|
||||||
|
|
||||||
const fileHandler: ServerRouteHandler = (request, response) => {
|
const fileHandler: ServerRouteHandler = (request, response) => {
|
||||||
try {
|
try {
|
||||||
const url = new URL('http://localhost' + request.url!);
|
const url = new URL('http://localhost' + request.url!);
|
||||||
|
|
@ -123,6 +115,13 @@ export class TraceViewer {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
this._server.routePrefix('/sha1/', sha1Handler);
|
this._server.routePrefix('/sha1/', sha1Handler);
|
||||||
|
|
||||||
|
const traceViewerHandler: ServerRouteHandler = (request, response) => {
|
||||||
|
const relativePath = request.url!;
|
||||||
|
const absolutePath = path.join(__dirname, '..', '..', '..', 'web', 'traceViewer', ...relativePath.split('/'));
|
||||||
|
return this._server.serveFile(response, absolutePath);
|
||||||
|
};
|
||||||
|
this._server.routePrefix('/', traceViewerHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
async show(headless: boolean): Promise<BrowserContext> {
|
async show(headless: boolean): Promise<BrowserContext> {
|
||||||
|
|
@ -161,7 +160,7 @@ export class TraceViewer {
|
||||||
else
|
else
|
||||||
page.on('close', () => process.exit());
|
page.on('close', () => process.exit());
|
||||||
|
|
||||||
await page.mainFrame().goto(internalCallMetadata(), urlPrefix + '/traceviewer/traceViewer/index.html');
|
await page.mainFrame().goto(internalCallMetadata(), urlPrefix + '/index.html');
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import '../common.css';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
applyTheme();
|
applyTheme();
|
||||||
|
navigator.serviceWorker.register('sw.bundle.js');
|
||||||
const debugNames = await fetch('/contexts').then(response => response.json());
|
const debugNames = await fetch('/contexts').then(response => response.json());
|
||||||
ReactDOM.render(<Workbench debugNames={debugNames} />, document.querySelector('#root'));
|
ReactDOM.render(<Workbench debugNames={debugNames} />, document.querySelector('#root'));
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
88
packages/playwright-core/src/web/traceViewer/sw.ts
Normal file
88
packages/playwright-core/src/web/traceViewer/sw.ts
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { RenderedFrameSnapshot } from '../../server/snapshot/snapshotTypes';
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
declare const self: ServiceWorkerGlobalScope;
|
||||||
|
|
||||||
|
const kBlobUrlPrefix = 'http://playwright.bloburl/#';
|
||||||
|
const snapshotIds = new Map<string, { frameId: string, index: number }>();
|
||||||
|
|
||||||
|
self.addEventListener('install', function(event: any) {
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('activate', function(event: any) {
|
||||||
|
event.waitUntil(self.clients.claim());
|
||||||
|
});
|
||||||
|
|
||||||
|
function respondNotAvailable(): Response {
|
||||||
|
return new Response('<body style="background: #ddd"></body>', { status: 200, headers: { 'Content-Type': 'text/html' } });
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeHash(url: string) {
|
||||||
|
try {
|
||||||
|
const u = new URL(url);
|
||||||
|
u.hash = '';
|
||||||
|
return u.toString();
|
||||||
|
} catch (e) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function doFetch(event: any /* FetchEvent */): Promise<Response> {
|
||||||
|
const request = event.request;
|
||||||
|
const pathname = new URL(request.url).pathname;
|
||||||
|
const isSnapshotUrl = pathname !== '/snapshot/' && pathname.startsWith('/snapshot/');
|
||||||
|
if (request.url.startsWith(self.location.origin) && !isSnapshotUrl)
|
||||||
|
return fetch(event.request);
|
||||||
|
|
||||||
|
const snapshotUrl = request.mode === 'navigate' ?
|
||||||
|
request.url : (await self.clients.get(event.clientId))!.url;
|
||||||
|
|
||||||
|
if (request.mode === 'navigate') {
|
||||||
|
const htmlResponse = await fetch(request);
|
||||||
|
const { html, frameId, index }: RenderedFrameSnapshot = await htmlResponse.json();
|
||||||
|
if (!html)
|
||||||
|
return respondNotAvailable();
|
||||||
|
snapshotIds.set(snapshotUrl, { frameId, index });
|
||||||
|
const response = new Response(html, { status: 200, headers: { 'Content-Type': 'text/html' } });
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { frameId, index } = snapshotIds.get(snapshotUrl)!;
|
||||||
|
const url = request.url.startsWith(kBlobUrlPrefix) ? request.url.substring(kBlobUrlPrefix.length) : removeHash(request.url);
|
||||||
|
const complexUrl = btoa(JSON.stringify({ frameId, index, url }));
|
||||||
|
const fetchUrl = `/resources/${complexUrl}`;
|
||||||
|
const fetchedResponse = await fetch(fetchUrl);
|
||||||
|
// We make a copy of the response, instead of just forwarding,
|
||||||
|
// so that response url is not inherited as "/resources/...", but instead
|
||||||
|
// as the original request url.
|
||||||
|
|
||||||
|
// Response url turns into resource base uri that is used to resolve
|
||||||
|
// relative links, e.g. url(/foo/bar) in style sheets.
|
||||||
|
const headers = new Headers(fetchedResponse.headers);
|
||||||
|
const response = new Response(fetchedResponse.body, {
|
||||||
|
status: fetchedResponse.status,
|
||||||
|
statusText: fetchedResponse.statusText,
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.addEventListener('fetch', function(event: any) {
|
||||||
|
event.respondWith(doFetch(event));
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development';
|
||||||
|
module.exports = {
|
||||||
|
mode,
|
||||||
|
entry: {
|
||||||
|
sw: path.join(__dirname, 'sw.ts'),
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.ts', '.js']
|
||||||
|
},
|
||||||
|
devtool: mode === 'production' ? false : 'source-map',
|
||||||
|
output: {
|
||||||
|
globalObject: 'self',
|
||||||
|
filename: '[name].bundle.js',
|
||||||
|
path: path.resolve(__dirname, '../../../lib/web/traceViewer')
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.(j|t)sx?$/,
|
||||||
|
loader: 'babel-loader',
|
||||||
|
options: {
|
||||||
|
presets: [
|
||||||
|
"@babel/preset-typescript",
|
||||||
|
"@babel/preset-react"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -19,6 +19,7 @@ import { InMemorySnapshotter } from 'playwright-core/lib/server/snapshot/inMemor
|
||||||
import { HttpServer } from 'playwright-core/lib/utils/httpServer';
|
import { HttpServer } from 'playwright-core/lib/utils/httpServer';
|
||||||
import { SnapshotServer } from 'playwright-core/lib/server/snapshot/snapshotServer';
|
import { SnapshotServer } from 'playwright-core/lib/server/snapshot/snapshotServer';
|
||||||
import type { Frame } from 'playwright-core';
|
import type { Frame } from 'playwright-core';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
const it = contextTest.extend<{ snapshotPort: number, snapshotter: InMemorySnapshotter, showSnapshot: (snapshot: any) => Promise<Frame> }>({
|
const it = contextTest.extend<{ snapshotPort: number, snapshotter: InMemorySnapshotter, showSnapshot: (snapshot: any) => Promise<Frame> }>({
|
||||||
snapshotPort: async ({}, run, testInfo) => {
|
snapshotPort: async ({}, run, testInfo) => {
|
||||||
|
|
@ -30,6 +31,9 @@ const it = contextTest.extend<{ snapshotPort: number, snapshotter: InMemorySnaps
|
||||||
const snapshotter = new InMemorySnapshotter(toImpl(context));
|
const snapshotter = new InMemorySnapshotter(toImpl(context));
|
||||||
await snapshotter.initialize();
|
await snapshotter.initialize();
|
||||||
const httpServer = new HttpServer();
|
const httpServer = new HttpServer();
|
||||||
|
httpServer.routePath('/snapshot/sw.js', (request, response) => {
|
||||||
|
return httpServer.serveFile(response, path.join(__dirname, 'playwright-core/lib/web/traceViewer/sw.js'));
|
||||||
|
});
|
||||||
new SnapshotServer(httpServer, snapshotter);
|
new SnapshotServer(httpServer, snapshotter);
|
||||||
await httpServer.start(snapshotPort);
|
await httpServer.start(snapshotPort);
|
||||||
await run(snapshotter);
|
await run(snapshotter);
|
||||||
|
|
@ -42,7 +46,7 @@ const it = contextTest.extend<{ snapshotPort: number, snapshotter: InMemorySnaps
|
||||||
const previewContext = await contextFactory();
|
const previewContext = await contextFactory();
|
||||||
const previewPage = await previewContext.newPage();
|
const previewPage = await previewContext.newPage();
|
||||||
previewPage.on('console', console.log);
|
previewPage.on('console', console.log);
|
||||||
await previewPage.goto(`http://localhost:${snapshotPort}/snapshot/`);
|
await previewPage.goto(`http://localhost:${snapshotPort}/snapshot/?serviceWorkerForTest`);
|
||||||
const frameSnapshot = snapshot.snapshot();
|
const frameSnapshot = snapshot.snapshot();
|
||||||
await previewPage.evaluate(snapshotId => {
|
await previewPage.evaluate(snapshotId => {
|
||||||
(window as any).showSnapshot(snapshotId);
|
(window as any).showSnapshot(snapshotId);
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,7 @@ function copyFile(file, from, to) {
|
||||||
const webPackFiles = [
|
const webPackFiles = [
|
||||||
'packages/playwright-core/src/server/injected/webpack.config.js',
|
'packages/playwright-core/src/server/injected/webpack.config.js',
|
||||||
'packages/playwright-core/src/web/traceViewer/webpack.config.js',
|
'packages/playwright-core/src/web/traceViewer/webpack.config.js',
|
||||||
|
'packages/playwright-core/src/web/traceViewer/webpack-sw.config.js',
|
||||||
'packages/playwright-core/src/web/recorder/webpack.config.js',
|
'packages/playwright-core/src/web/recorder/webpack.config.js',
|
||||||
'packages/playwright-core/src/web/htmlReport/webpack.config.js',
|
'packages/playwright-core/src/web/htmlReport/webpack.config.js',
|
||||||
];
|
];
|
||||||
|
|
@ -182,7 +183,7 @@ copyFiles.push({
|
||||||
files: 'packages/playwright-core/src/**/*.js',
|
files: 'packages/playwright-core/src/**/*.js',
|
||||||
from: 'packages/playwright-core/src',
|
from: 'packages/playwright-core/src',
|
||||||
to: 'packages/playwright-core/lib',
|
to: 'packages/playwright-core/lib',
|
||||||
ignored: ['**/.eslintrc.js', '**/*webpack.config.js', '**/injected/**/*']
|
ignored: ['**/.eslintrc.js', '**/webpack*.config.js', '**/injected/**/*']
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sometimes we require JSON files that babel ignores.
|
// Sometimes we require JSON files that babel ignores.
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,7 @@ DEPS['src/cli/driver.ts'] = DEPS['src/inProcessFactory.ts'] = DEPS['src/browserS
|
||||||
// Tracing is a client/server plugin, nothing should depend on it.
|
// Tracing is a client/server plugin, nothing should depend on it.
|
||||||
DEPS['src/web/recorder/'] = ['src/common/', 'src/web/', 'src/web/components/', 'src/server/supplements/recorder/recorderTypes.ts'];
|
DEPS['src/web/recorder/'] = ['src/common/', 'src/web/', 'src/web/components/', 'src/server/supplements/recorder/recorderTypes.ts'];
|
||||||
DEPS['src/web/traceViewer/'] = ['src/common/', 'src/web/'];
|
DEPS['src/web/traceViewer/'] = ['src/common/', 'src/web/'];
|
||||||
|
DEPS['src/web/traceViewer/sw.ts'] = ['src/server/snapshot/snapshotTypes.ts'];
|
||||||
DEPS['src/web/traceViewer/ui/'] = ['src/common/', 'src/protocol/', 'src/web/traceViewer/', 'src/web/', 'src/server/trace/viewer/', 'src/server/trace/', 'src/server/trace/common/', 'src/server/snapshot/snapshotTypes.ts', 'src/protocol/channels.ts'];
|
DEPS['src/web/traceViewer/ui/'] = ['src/common/', 'src/protocol/', 'src/web/traceViewer/', 'src/web/', 'src/server/trace/viewer/', 'src/server/trace/', 'src/server/trace/common/', 'src/server/snapshot/snapshotTypes.ts', 'src/protocol/channels.ts'];
|
||||||
// The service is a cross-cutting feature, and so it depends on a bunch of things.
|
// The service is a cross-cutting feature, and so it depends on a bunch of things.
|
||||||
DEPS['src/remote/'] = ['src/client/', 'src/debug/', 'src/dispatchers/', 'src/server/', 'src/server/supplements/', 'src/server/electron/', 'src/server/trace/', 'src/utils/**'];
|
DEPS['src/remote/'] = ['src/client/', 'src/debug/', 'src/dispatchers/', 'src/server/', 'src/server/supplements/', 'src/server/electron/', 'src/server/trace/', 'src/utils/**'];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue