chore: migrate trace-viewer and recorder to vite (#13076)

This commit is contained in:
Pavel Feldman 2022-03-25 13:12:00 -08:00 committed by GitHub
parent 97e8ead57c
commit 6b81e76c2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
120 changed files with 1387 additions and 414 deletions

View File

@ -15,3 +15,4 @@ output/
test-results/
tests-components/
examples/
DEPS

916
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -71,6 +71,7 @@
"@types/yazl": "^2.4.2",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2",
"@vitejs/plugin-react": "^1.0.7",
"@zip.js/zip.js": "^2.4.2",
"ansi-to-html": "^0.7.2",
"babel-loader": "^8.2.3",
@ -98,6 +99,7 @@
"socksv5": "0.0.6",
"style-loader": "^3.3.1",
"typescript": "^4.5.5",
"vite": "^2.8.0",
"webpack": "^5.68.0",
"webpack-cli": "^4.9.2",
"xml2js": "^0.4.23",

View File

@ -5,6 +5,7 @@
# Include sources from lib, but not map files.
!lib/**/*.js
# Include web assets for recorder, trace viewer, etc.
!lib/**/*.css
!lib/**/*.html
!lib/**/*.png
!lib/**/*.ttf

View File

@ -3,6 +3,7 @@ module.exports = {
// CLI should only use client-side features.
'cli/': [
'..',
'cli/**',
'client/**',
'debug/injected/',
@ -13,10 +14,14 @@ module.exports = {
'utils/**',
],
'cli/driver.ts': [ '**' ],
'cli/driver.ts': [
'..',
'**',
],
// Client depends on chromium protocol for types.
'client/': [
'../types/**',
'common/',
'protocol/',
'server/chromium/protocol.d.ts',
@ -52,6 +57,7 @@ module.exports = {
// Generic dependencies for server-side code.
'server/': [
'../types/types.d.ts',
'common/',
'generated/',
'protocol/**',
@ -61,6 +67,8 @@ module.exports = {
'server/common/**',
'server/injected/**',
'server/supplements/**',
// For fetch ?!?
'server/trace/recorder/tracing.ts',
'utils/',
],
@ -110,18 +118,6 @@ module.exports = {
'utils/',
],
'server/fetch.ts': [
'common/',
'generated/',
'protocol/**',
'server/',
'server/common/**',
'server/injected/**',
'server/supplements/**',
'server/trace/recorder/tracing.ts',
'utils/',
],
'server/playwright.ts': [
'common/',
'generated/',
@ -171,6 +167,12 @@ module.exports = {
'utils/',
],
// For testing
'server/trace/test/': [
'@trace-viewer/**',
'**',
],
'server/trace/recorder/': [
'common/',
'generated/',
@ -216,43 +218,4 @@ module.exports = {
'protocol/',
'third_party/diff_match_patch',
],
// Tracing is a client/server plugin, nothing should depend on it.
'web/components/': [
'third_party/highlightjs/**',
'web/third_party/vscode/',
],
'web/recorder/': [
'common/',
'server/supplements/recorder/recorderTypes.ts',
'web/',
'web/components/',
'web/third_party/vscode/',
],
'web/traceViewer/': [
'common/',
'protocol/callMetadata.ts',
'server/trace/common/',
'web/',
'web/third_party/vscode/',
'web/traceViewer/ui/',
],
'web/traceViewer/ui/': [
'common/',
'protocol/',
'protocol/channels.ts',
'server/snapshot/snapshotTypes.ts',
'server/trace/',
'server/trace/common/',
'server/trace/viewer/',
'third_party/**',
'web/',
'web/components/',
'web/traceViewer/',
],
'web/traceViewer/inMemorySnapshotter.ts': [ '**' ],
}
};

View File

@ -33,8 +33,8 @@ export type Attribution = {
frame?: Frame;
};
import { CallMetadata } from '../protocol/callMetadata';
export { CallMetadata } from '../protocol/callMetadata';
import type { CallMetadata } from '../protocol/callMetadata';
export type { CallMetadata } from '../protocol/callMetadata';
export class SdkObject extends EventEmitter {
guid: string;

View File

@ -18,6 +18,7 @@ import type { Size } from '../../../common/types';
import type { CallMetadata } from '../../instrumentation';
import type { FrameSnapshot, ResourceSnapshot } from './snapshotTypes';
// Make sure you add _modernize_N_to_N1(event: any) to traceModel.ts.
export const VERSION = 3;
export type BrowserContextEventOptions = {

View File

@ -14,16 +14,16 @@
* limitations under the License.
*/
import { BrowserContext } from '../../server/browserContext';
import { eventsHelper } from '../../utils/eventsHelper';
import { Page } from '../../server/page';
import { FrameSnapshot } from '../../server/trace/common/snapshotTypes';
import { SnapshotRenderer } from './snapshotRenderer';
import { BaseSnapshotStorage } from './snapshotStorage';
import { Snapshotter, SnapshotterBlob, SnapshotterDelegate } from '../../server/trace/recorder/snapshotter';
import { ElementHandle } from '../../server/dom';
import { HarTracer, HarTracerDelegate } from '../../server/supplements/har/harTracer';
import * as har from '../../server/supplements/har/har';
import { BrowserContext } from '../../browserContext';
import { eventsHelper } from '../../../utils/eventsHelper';
import { Page } from '../../page';
import { FrameSnapshot } from '../common/snapshotTypes';
import { SnapshotRenderer } from '../../../../../trace-viewer/src/snapshotRenderer';
import { BaseSnapshotStorage } from '../../../../../trace-viewer/src/snapshotStorage';
import { Snapshotter, SnapshotterBlob, SnapshotterDelegate } from '../recorder/snapshotter';
import { ElementHandle } from '../../dom';
import { HarTracer, HarTracerDelegate } from '../../supplements/har/harTracer';
import * as har from '../../supplements/har/har';
export class InMemorySnapshotter extends BaseSnapshotStorage implements SnapshotterDelegate, HarTracerDelegate {
private _blobs = new Map<string, Buffer>();

View File

@ -15,8 +15,8 @@
* limitations under the License.
*/
import { Size, Point, TimeoutOptions } from '../common/types';
export { Size, Point, Rect, Quad, URLMatch, TimeoutOptions } from '../common/types';
import type { Size, Point, TimeoutOptions } from '../common/types';
export type { Size, Point, Rect, Quad, URLMatch, TimeoutOptions } from '../common/types';
export type StrictOptions = {
strict?: boolean,

View File

@ -1,2 +0,0 @@
// This file has been deprecated in favor of core.js
var hljs = require('./core');

View File

@ -1,8 +0,0 @@
var hljs = require('./core');
hljs.registerLanguage('javascript', require('./languages/javascript'));
hljs.registerLanguage('python', require('./languages/python'));
hljs.registerLanguage('csharp', require('./languages/csharp'));
hljs.registerLanguage('java', require('./languages/java'));
module.exports = hljs;

View File

@ -1,45 +0,0 @@
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development';
module.exports = {
mode,
entry: {
app: path.join(__dirname, 'index.tsx'),
},
resolve: {
extensions: ['.ts', '.js', '.tsx', '.jsx']
},
devtool: mode === 'production' ? false : 'source-map',
output: {
globalObject: 'self',
filename: '[name].bundle.js',
path: path.resolve(__dirname, '../../../lib/webpack/recorder')
},
module: {
rules: [
{
test: /\.(j|t)sx?$/,
loader: 'babel-loader',
options: {
presets: [
"@babel/preset-typescript",
"@babel/preset-react"
]
},
exclude: /node_modules/
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
]
},
plugins: [
new HtmlWebPackPlugin({
title: 'Playwright Inspector',
template: path.join(__dirname, 'index.html'),
})
]
};

View File

@ -1,32 +0,0 @@
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/webpack/traceViewer')
},
module: {
rules: [
{
test: /\.(j|t)sx?$/,
loader: 'babel-loader',
options: {
presets: [
"@babel/preset-typescript",
]
},
exclude: /node_modules/
},
]
},
};

View File

@ -1,60 +0,0 @@
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development';
module.exports = {
mode,
entry: {
app: path.join(__dirname, 'index.tsx'),
},
resolve: {
extensions: ['.ts', '.js', '.tsx', '.jsx']
},
devtool: mode === 'production' ? false : 'source-map',
output: {
globalObject: 'self',
filename: '[name].bundle.js',
path: path.resolve(__dirname, '../../../lib/webpack/traceViewer')
},
module: {
rules: [
{
test: /\.(j|t)sx?$/,
loader: 'babel-loader',
options: {
presets: [
"@babel/preset-typescript",
"@babel/preset-react"
]
},
exclude: /node_modules/
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
]
},
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, '../../../../../node_modules/@zip.js/zip.js/dist/zip-no-worker-inflate.min.js'),
to: 'zip.min.js'
},
],
}),
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, 'static'),
},
],
}),
new HtmlWebPackPlugin({
title: 'Playwright Trace Viewer',
template: path.join(__dirname, 'index.html'),
})
]
};

View File

@ -1,20 +0,0 @@
/*
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.
*/
declare module '*.png' {
const value: any;
export = value;
}

View File

@ -1,8 +1,9 @@
module.exports = {
'/': [
'../types/testReporter.d.ts',
'matchers/',
'reporters/',
'third_party/',
'matchers/',
],
'matchers': [
'expect.ts',
@ -12,6 +13,7 @@ module.exports = {
'util.ts',
],
'reporters': [
'util.ts'
'../types/testReporter.d.ts',
'util.ts',
],
};

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { Page } from '@playwright/test';
import type { Page } from '@playwright/test';
import { createGuid } from 'playwright-core/lib/utils/utils';
export async function mount(page: Page, jsxOrType: any, options: any): Promise<string> {

24
packages/recorder/.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@ -13,15 +13,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" sizes="32x32" href="/icon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/icon-16x16.png">
<link rel="manifest" href="/manifest.webmanifest">
<title>Playwright Inspector</title>
</head>
<body>
<div id=root></div>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>

View File

@ -0,0 +1,10 @@
{
"name": "recorder",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build && tsc",
"preview": "vite preview"
}
}

View File

Before

Width:  |  Height:  |  Size: 593 B

After

Width:  |  Height:  |  Size: 593 B

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,30 @@
{
"theme_color": "#000",
"background_color": "#fff",
"display": "browser",
"start_url": "index.html",
"name": "Playwright Inspector",
"short_name": "Playwright Inspector",
"icons": [
{
"src": "icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icon-256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}

View File

@ -0,0 +1,5 @@
module.exports = {
'/': [
'@web/**'
]
};

View File

@ -16,8 +16,8 @@
import './callLog.css';
import * as React from 'react';
import type { CallLog } from '../../server/supplements/recorder/recorderTypes';
import { msToString } from '../uiUtils';
import type { CallLog } from '@playwright-core/server/supplements/recorder/recorderTypes';
import { msToString } from '@web/uiUtils';
export interface CallLogProps {
log: CallLog[],

View File

@ -14,11 +14,11 @@
* limitations under the License.
*/
import '../third_party/vscode/codicon.css';
import '@web/common.css';
import { applyTheme } from '@web/theme';
import '@web/third_party/vscode/codicon.css';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { applyTheme } from '../theme';
import '../common.css';
import { Main } from './main';
(async () => {

View File

@ -14,10 +14,10 @@
limitations under the License.
*/
import './recorder.css';
import type { CallLog, Mode, Source } from '@playwright-core/server/supplements/recorder/recorderTypes';
import * as React from 'react';
import type { CallLog, Mode, Source } from '../../server/supplements/recorder/recorderTypes';
import { Recorder } from './recorder';
import './recorder.css';
declare global {
interface Window {

View File

@ -14,14 +14,14 @@
limitations under the License.
*/
import './recorder.css';
import type { CallLog, Mode, Source } from '@playwright-core/server/supplements/recorder/recorderTypes';
import { Source as SourceView } from '@web/components/source';
import { SplitView } from '@web/components/splitView';
import { Toolbar } from '@web/components/toolbar';
import { ToolbarButton } from '@web/components/toolbarButton';
import * as React from 'react';
import { Toolbar } from '../components/toolbar';
import { ToolbarButton } from '../components/toolbarButton';
import { Source as SourceView } from '../components/source';
import type { CallLog, Mode, Source } from '../../server/supplements/recorder/recorderTypes';
import { SplitView } from '../components/splitView';
import { CallLogView } from './callLog';
import './recorder.css';
declare global {
interface Window {

1
packages/recorder/src/vite-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": true,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": ".",
"useUnknownInCatchVariables": false,
"paths": {
"@web/*": ["../web/src/*"],
"@playwright-core/*": ["../playwright-core/src/*"],
}
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}

View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"composite": true,
"module": "esnext",
"moduleResolution": "node"
},
"include": ["vite.config.ts"]
}

View File

@ -0,0 +1,41 @@
/**
* 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 { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import * as path from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react()
],
resolve: {
alias: {
'@web': path.resolve(__dirname, '../web/src'),
'@playwright-core': path.resolve(__dirname, '../playwright-core/src'),
},
},
build: {
outDir: path.resolve(__dirname, '../playwright-core/lib/webpack/recorder'),
emptyOutDir: true,
rollupOptions: {
output: {
manualChunks: undefined,
},
},
}
});

24
packages/trace-viewer/.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@ -13,18 +13,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" sizes="32x32" href="icon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="icon-16x16.png">
<link rel="manifest" href="manifest.webmanifest">
<link rel="icon" type="image/png" sizes="32x32" href="/icon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/icon-16x16.png">
<link rel="manifest" href="/manifest.webmanifest">
<title>Playwright Trace Viewer</title>
</head>
<body>
<div id=root></div>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>

View File

@ -0,0 +1,10 @@
{
"name": "trace-viewer",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build && tsc",
"preview": "vite preview"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,12 @@
module.exports = {
'/': [
'@web/**',
'ui/',
],
'ui/': [
'@web/**',
'geometry.ts',
'entries.ts',
]
};

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
import type { ResourceSnapshot } from '../../server/trace/common/snapshotTypes';
import * as trace from '../../server/trace/common/traceEvents';
import type { ResourceSnapshot } from '@playwright-core/server/trace/common/snapshotTypes';
import type * as trace from '@playwright-core/server/trace/common/traceEvents';
export type ContextEntry = {
traceUrl: string;

View File

@ -14,12 +14,12 @@
* limitations under the License.
*/
import '../third_party/vscode/codicon.css';
import '@web/third_party/vscode/codicon.css';
import { Workbench } from './ui/workbench';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { applyTheme } from '../theme';
import '../common.css';
import { applyTheme } from '@web/theme';
import '@web/common.css';
(async () => {
applyTheme();

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { FrameSnapshot, NodeSnapshot, RenderedFrameSnapshot, ResourceSnapshot } from '../../server/trace/common/snapshotTypes';
import type { FrameSnapshot, NodeSnapshot, RenderedFrameSnapshot, ResourceSnapshot } from '@playwright-core/server/trace/common/snapshotTypes';
export class SnapshotRenderer {
private _snapshots: FrameSnapshot[];

View File

@ -15,7 +15,7 @@
*/
import { SnapshotStorage } from './snapshotStorage';
import type { Point } from '../../common/types';
import type { Point } from '@playwright-core/common/types';
import { URLSearchParams } from 'url';
import { SnapshotRenderer } from './snapshotRenderer';

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
import type { FrameSnapshot, ResourceSnapshot } from '@playwright-core/server/trace/common/snapshotTypes';
import { EventEmitter } from 'events';
import { FrameSnapshot, ResourceSnapshot } from '../../server/trace/common/snapshotTypes';
import { SnapshotRenderer } from './snapshotRenderer';
export interface SnapshotStorage {

View File

@ -14,17 +14,15 @@
* limitations under the License.
*/
import * as trace from '../../server/trace/common/traceEvents';
import type { CallMetadata } from '@playwright-core/protocol/callMetadata';
import type * as trace from '@playwright-core/server/trace/common/traceEvents';
import type zip from '@zip.js/zip.js';
// @ts-ignore
import zipImport from '@zip.js/zip.js/dist/zip-no-worker-inflate.min.js';
import { ContextEntry, createEmptyContext, PageEntry } from './entries';
import { BaseSnapshotStorage } from './snapshotStorage';
import type zip from '@zip.js/zip.js';
import { ContextEntry, createEmptyContext, PageEntry } from './entries';
import type { CallMetadata } from '../../protocol/callMetadata';
// @ts-ignore
self.importScripts('zip.min.js');
const zipjs = (self as any).zip as typeof zip;
const zipjs = zipImport as typeof zip;
export class TraceModel {
contextEntry: ContextEntry;
@ -159,7 +157,7 @@ export class TraceModel {
private _modernize(event: any): trace.TraceEvent {
if (this._version === undefined)
return event;
for (let version = this._version; version < trace.VERSION; ++version)
for (let version = this._version; version < 3; ++version)
event = (this as any)[`_modernize_${version}_to_${version + 1}`].call(this, event);
return event;
}

View File

@ -14,12 +14,12 @@
limitations under the License.
*/
import './actionList.css';
import './tabbedPane.css';
import type { ActionTraceEvent } from '@playwright-core/server/trace/common/traceEvents';
import { msToString } from '@web/uiUtils';
import * as React from 'react';
import './actionList.css';
import * as modelUtil from './modelUtil';
import { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
import { msToString } from '../../uiUtils';
import './tabbedPane.css';
export interface ActionListProps {
actions: ActionTraceEvent[],

View File

@ -14,12 +14,12 @@
* limitations under the License.
*/
import type { CallMetadata } from '@playwright-core/protocol/callMetadata';
import type { SerializedValue } from '@playwright-core/protocol/channels';
import type { ActionTraceEvent } from '@playwright-core/server/trace/common/traceEvents';
import { msToString } from '@web/uiUtils';
import * as React from 'react';
import './callTab.css';
import type { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
import { CallMetadata } from '../../../protocol/callMetadata';
import { parseSerializedValue } from '../../../protocol/serializers';
import { msToString } from '../../uiUtils';
export const CallTab: React.FunctionComponent<{
action: ActionTraceEvent | undefined,
@ -88,3 +88,44 @@ function toString(metadata: CallMetadata, name: string, value: any): { title: st
return { title: '<handle>', type: 'handle' };
return { title: JSON.stringify(value), type: 'object' };
}
function parseSerializedValue(value: SerializedValue, handles: any[] | undefined): any {
if (value.n !== undefined)
return value.n;
if (value.s !== undefined)
return value.s;
if (value.b !== undefined)
return value.b;
if (value.v !== undefined) {
if (value.v === 'undefined')
return undefined;
if (value.v === 'null')
return null;
if (value.v === 'NaN')
return NaN;
if (value.v === 'Infinity')
return Infinity;
if (value.v === '-Infinity')
return -Infinity;
if (value.v === '-0')
return -0;
}
if (value.d !== undefined)
return new Date(value.d);
if (value.r !== undefined)
return new RegExp(value.r.p, value.r.f);
if (value.a !== undefined)
return value.a.map((a: any) => parseSerializedValue(a, handles));
if (value.o !== undefined) {
const result: any = {};
for (const { k, v } of value.o)
result[k] = parseSerializedValue(v, handles);
return result;
}
if (value.h !== undefined) {
if (handles === undefined)
return '<object>';
return handles[value.h];
}
return '<object>';
}

View File

@ -14,10 +14,10 @@
* limitations under the License.
*/
import type * as channels from '@playwright-core/protocol/channels';
import type { ActionTraceEvent } from '@playwright-core/server/trace/common/traceEvents';
import * as React from 'react';
import './consoleTab.css';
import { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
import * as channels from '../../../protocol/channels';
import * as modelUtil from './modelUtil';
export const ConsoleTab: React.FunctionComponent<{

View File

@ -18,7 +18,7 @@ import './filmStrip.css';
import { Boundaries, Size } from '../geometry';
import * as React from 'react';
import { useMeasure } from './helpers';
import { upperBound } from '../../uiUtils';
import { upperBound } from '@web/uiUtils';
import { PageEntry } from '../entries';
import { MultiTraceModel } from './modelUtil';

View File

@ -14,10 +14,10 @@
* limitations under the License.
*/
import { ResourceSnapshot } from '../../../server/trace/common/snapshotTypes';
import { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
import { ContextEntry, PageEntry } from '../entries';
import * as trace from '../../../server/trace/common/traceEvents';
import type { ResourceSnapshot } from '@playwright-core/server/trace/common/snapshotTypes';
import type * as trace from '@playwright-core/server/trace/common/traceEvents';
import type { ActionTraceEvent } from '@playwright-core/server/trace/common/traceEvents';
import type { ContextEntry, PageEntry } from '../entries';
const contextSymbol = Symbol('context');
const nextSymbol = Symbol('next');

View File

@ -14,10 +14,10 @@
* limitations under the License.
*/
import './networkResourceDetails.css';
import type { ResourceSnapshot } from '@playwright-core/server/trace/common/snapshotTypes';
import { Expandable } from '@web/components/expandable';
import * as React from 'react';
import type { ResourceSnapshot } from '../../../server/trace/common/snapshotTypes';
import { Expandable } from '../../components/expandable';
import './networkResourceDetails.css';
export const NetworkResourceDetails: React.FunctionComponent<{
resource: ResourceSnapshot,

View File

@ -15,7 +15,7 @@
*/
import * as React from 'react';
import { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
import type { ActionTraceEvent } from '@playwright-core/server/trace/common/traceEvents';
import * as modelUtil from './modelUtil';
import { NetworkResourceDetails } from './networkResourceDetails';
import './networkTab.css';

View File

@ -18,7 +18,7 @@ import './snapshotTab.css';
import './tabbedPane.css';
import * as React from 'react';
import { useMeasure } from './helpers';
import { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
import type { ActionTraceEvent } from '@playwright-core/server/trace/common/traceEvents';
import { context } from './modelUtil';
export const SnapshotTab: React.FunctionComponent<{

View File

@ -14,15 +14,15 @@
* limitations under the License.
*/
import type { StackFrame } from '@playwright-core/protocol/channels';
import type { ActionTraceEvent } from '@playwright-core/server/trace/common/traceEvents';
import { Source as SourceView } from '@web/components/source';
import { SplitView } from '@web/components/splitView';
import '@web/third_party/highlightjs/highlightjs/tomorrow.css';
import * as React from 'react';
import { useAsyncMemo } from './helpers';
import './sourceTab.css';
import '../../../third_party/highlightjs/highlightjs/tomorrow.css';
import { Source as SourceView } from '../../components/source';
import { StackTraceView } from './stackTrace';
import { SplitView } from '../../components/splitView';
import { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
import { StackFrame } from '../../../protocol/channels';
type StackInfo = string | {
frames: StackFrame[];

View File

@ -16,7 +16,7 @@
import * as React from 'react';
import './stackTrace.css';
import { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
import type { ActionTraceEvent } from '@playwright-core/server/trace/common/traceEvents';
export const StackTraceView: React.FunctionComponent<{
action: ActionTraceEvent | undefined,

View File

@ -15,9 +15,9 @@
limitations under the License.
*/
import type { ActionTraceEvent } from '@playwright-core/server/trace/common/traceEvents';
import { msToString } from '@web/uiUtils';
import * as React from 'react';
import { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
import { msToString } from '../../uiUtils';
import { Boundaries } from '../geometry';
import { FilmStrip } from './filmStrip';
import { useMeasure } from './helpers';

View File

@ -14,22 +14,22 @@
limitations under the License.
*/
import { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
import type { ActionTraceEvent } from '@playwright-core/server/trace/common/traceEvents';
import { SplitView } from '@web/components/splitView';
import { msToString } from '@web/uiUtils';
import * as React from 'react';
import { ContextEntry } from '../entries';
import { ActionList } from './actionList';
import { CallTab } from './callTab';
import { ConsoleTab } from './consoleTab';
import * as modelUtil from './modelUtil';
import { MultiTraceModel } from './modelUtil';
import { NetworkTab } from './networkTab';
import { SnapshotTab } from './snapshotTab';
import { SourceTab } from './sourceTab';
import { TabbedPane } from './tabbedPane';
import { Timeline } from './timeline';
import './workbench.css';
import * as React from 'react';
import { NetworkTab } from './networkTab';
import { SourceTab } from './sourceTab';
import { SnapshotTab } from './snapshotTab';
import { CallTab } from './callTab';
import { SplitView } from '../../components/splitView';
import { ConsoleTab } from './consoleTab';
import * as modelUtil from './modelUtil';
import { msToString } from '../../uiUtils';
import { MultiTraceModel } from './modelUtil';
export const Workbench: React.FunctionComponent<{
}> = () => {

View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": true,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": ".",
"paths": {
"@web/*": ["../web/src/*"],
"@playwright-core/*": ["../playwright-core/src/*"],
},
"useUnknownInCatchVariables": false,
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}

View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"composite": true,
"module": "esnext",
"moduleResolution": "node"
},
"include": ["vite.config.ts"]
}

View File

@ -0,0 +1,48 @@
/**
* 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 { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import * as path from 'path';
// https://vitejs.dev/config/
export default defineConfig({
base: '/trace/',
plugins: [
react()
],
resolve: {
alias: {
'@web': path.resolve(__dirname, '../web/src'),
'@playwright-core': path.resolve(__dirname, '../playwright-core/src'),
},
},
build: {
outDir: path.resolve(__dirname, '../playwright-core/lib/webpack/traceViewer'),
emptyOutDir: true,
rollupOptions: {
input: {
main: path.resolve(__dirname, 'index.html'),
sw: path.resolve(__dirname, 'src/sw.ts'),
},
output: {
entryFileNames: info => info.name === 'sw' ? '[name].bundle.js' : '[name].[hash].js',
assetFileNames: () => '[name].[hash][extname]',
manualChunks: undefined,
},
},
}
});

View File

@ -16,8 +16,8 @@
import './source.css';
import * as React from 'react';
import * as highlightjs from '../../third_party/highlightjs/highlightjs';
import '../../third_party/highlightjs/highlightjs/tomorrow.css';
import highlightjs from '../third_party/highlightjs/highlightjs';
import '../third_party/highlightjs/highlightjs/tomorrow.css';
export type SourceHighlight = {
line: number;

Some files were not shown because too many files have changed in this diff Show More