chore: migrate trace-viewer and recorder to vite (#13076)
@ -15,3 +15,4 @@ output/
|
||||
test-results/
|
||||
tests-components/
|
||||
examples/
|
||||
DEPS
|
916
package-lock.json
generated
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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': [ '**' ],
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
@ -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>();
|
@ -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,
|
||||
|
@ -1,2 +0,0 @@
|
||||
// This file has been deprecated in favor of core.js
|
||||
var hljs = require('./core');
|
@ -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;
|
@ -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'),
|
||||
})
|
||||
]
|
||||
};
|
@ -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/
|
||||
},
|
||||
]
|
||||
},
|
||||
};
|
@ -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'),
|
||||
})
|
||||
]
|
||||
};
|
20
packages/playwright-core/src/web/types.d.ts
vendored
@ -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;
|
||||
}
|
@ -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',
|
||||
],
|
||||
};
|
||||
|
@ -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
@ -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?
|
@ -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>
|
10
packages/recorder/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "recorder",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build && tsc",
|
||||
"preview": "vite preview"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 593 B After Width: | Height: | Size: 593 B |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
30
packages/recorder/public/manifest.webmanifest
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
5
packages/recorder/src/DEPS
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
'/': [
|
||||
'@web/**'
|
||||
]
|
||||
};
|
@ -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[],
|
@ -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 () => {
|
@ -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 {
|
@ -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
@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
26
packages/recorder/tsconfig.json
Normal 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" }]
|
||||
}
|
8
packages/recorder/tsconfig.node.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node"
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
41
packages/recorder/vite.config.ts
Normal 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
@ -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?
|
@ -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>
|
10
packages/trace-viewer/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "trace-viewer",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build && tsc",
|
||||
"preview": "vite preview"
|
||||
}
|
||||
}
|
BIN
packages/trace-viewer/public/icon-16x16.png
Normal file
After Width: | Height: | Size: 593 B |
BIN
packages/trace-viewer/public/icon-192x192.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
packages/trace-viewer/public/icon-256x256.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
packages/trace-viewer/public/icon-32x32.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
packages/trace-viewer/public/icon-384x384.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
packages/trace-viewer/public/icon-512x512.png
Normal file
After Width: | Height: | Size: 36 KiB |
12
packages/trace-viewer/src/DEPS
Normal file
@ -0,0 +1,12 @@
|
||||
module.exports = {
|
||||
'/': [
|
||||
'@web/**',
|
||||
'ui/',
|
||||
],
|
||||
|
||||
'ui/': [
|
||||
'@web/**',
|
||||
'geometry.ts',
|
||||
'entries.ts',
|
||||
]
|
||||
};
|
@ -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;
|
@ -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();
|
@ -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[];
|
@ -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';
|
||||
|
@ -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 {
|
@ -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;
|
||||
}
|
@ -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[],
|
@ -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>';
|
||||
}
|
@ -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<{
|
@ -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';
|
||||
|
@ -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');
|
@ -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,
|
@ -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';
|
@ -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<{
|
@ -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[];
|
@ -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,
|
@ -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';
|
@ -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<{
|
||||
}> = () => {
|
1
packages/trace-viewer/src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
26
packages/trace-viewer/tsconfig.json
Normal 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" }]
|
||||
}
|
8
packages/trace-viewer/tsconfig.node.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node"
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
48
packages/trace-viewer/vite.config.ts
Normal 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,
|
||||
},
|
||||
},
|
||||
}
|
||||
});
|
@ -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;
|