diff --git a/src/traceViewer/web/common.css b/src/traceViewer/web/common.css index c1390c9..eb08e26 100644 --- a/src/traceViewer/web/common.css +++ b/src/traceViewer/web/common.css @@ -35,6 +35,7 @@ --control-background: #3C3C3C; --settings: #E7E7E7; --sidebar-width: 250px; + --box-shadow: rgba(0, 0, 0, 0.133) 0px 1.6px 3.6px 0px, rgba(0, 0, 0, 0.11) 0px 0.3px 0.9px 0px; } html, body { diff --git a/src/traceViewer/web/components/tabbedPane.css b/src/traceViewer/web/components/tabbedPane.css index 6d69c7c..d9a9a31 100644 --- a/src/traceViewer/web/components/tabbedPane.css +++ b/src/traceViewer/web/components/tabbedPane.css @@ -31,7 +31,6 @@ tabbed-pane tab-strip { display: flex; flex-direction: row; align-items: center; - box-shadow: rgba(0, 0, 0, 0.133) 0px 1.6px 3.6px 0px, rgba(0, 0, 0, 0.11) 0px 0.3px 0.9px 0px; } tabbed-pane tab-strip > list-view { diff --git a/src/traceViewer/web/ui/actionListView.css b/src/traceViewer/web/ui/actionListView.css index 7a0163a..248cb69 100644 --- a/src/traceViewer/web/ui/actionListView.css +++ b/src/traceViewer/web/ui/actionListView.css @@ -29,7 +29,6 @@ action-list > list-view { } action-entry { - --action-color: transparent; position: relative; } @@ -41,7 +40,6 @@ action-list action-entry { border: 3px solid var(--background); margin-top: var(--layout-gap); user-select: none; - border-left-color: var(--action-color); padding: 0 5px 5px 5px; } @@ -70,7 +68,7 @@ action-list action-title { action-list action-entry action-header { display: block; align-items: center; - margin-bottom: 5px; + margin: 5px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -88,6 +86,7 @@ action-list action-thumbnail { justify-content: center; width: 200px; height: 100px; + box-shadow: var(--box-shadow); } action-list action-thumbnail img { diff --git a/src/traceViewer/web/ui/networkTab.css b/src/traceViewer/web/ui/networkTab.css new file mode 100644 index 0000000..a8ba405 --- /dev/null +++ b/src/traceViewer/web/ui/networkTab.css @@ -0,0 +1,27 @@ +/* + 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. +*/ + +.network-tab network-request { + box-shadow: var(--box-shadow); + overflow: hidden; + white-space: nowrap; + height: 36px; + display: flex; + align-items: center; + padding: 0 10px; + margin-bottom: 10px; + background: #fdfcfc; +} diff --git a/src/traceViewer/web/ui/networkTab.ts b/src/traceViewer/web/ui/networkTab.ts new file mode 100644 index 0000000..6a846f2 --- /dev/null +++ b/src/traceViewer/web/ui/networkTab.ts @@ -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 { ActionEntry } from "../../traceModel"; +import { NetworkResourceTraceEvent } from "../../traceTypes"; +import { dom } from '../components/dom'; +import { ListView } from "../components/listView"; +import { Tab } from './propertiesTabbedPane'; +import './networkTab.css'; + +export class NetworkTab implements Tab { + label = 'Network'; + private _listView: ListView; + + constructor() { + this._listView = new ListView(this); + this._listView.element.classList.add('network-tab'); + } + + render(resource: NetworkResourceTraceEvent, element: HTMLElement): HTMLElement { + if (element) + return element; + return dom`${resource.url}` + } + + async setAction(actionEntry: ActionEntry | undefined) { + this._listView.clear(); + if (actionEntry) + this._listView.appendAll(actionEntry.resources); + } + + content(): HTMLElement { + return this._listView.element; + } +} diff --git a/src/traceViewer/web/ui/propertiesTabbedPane.ts b/src/traceViewer/web/ui/propertiesTabbedPane.ts index 515351c..87868cf 100644 --- a/src/traceViewer/web/ui/propertiesTabbedPane.ts +++ b/src/traceViewer/web/ui/propertiesTabbedPane.ts @@ -16,11 +16,11 @@ import * as monaco from 'monaco-editor'; import { ActionEntry } from "../../traceModel"; -import { NetworkResourceTraceEvent } from "../../traceTypes"; import { dom, Element$ } from '../components/dom'; import { Size } from "../components/geometry"; -import { ListView } from "../components/listView"; import { TabbedPane, TabOptions } from "../components/tabbedPane"; +import { NetworkTab } from './networkTab'; +import { SourceTab } from './sourceTab'; export class PropertiesTabbedPane { element: HTMLElement; @@ -55,7 +55,7 @@ export class PropertiesTabbedPane { } } -interface Tab extends TabOptions { +export interface Tab extends TabOptions { setAction(action: ActionEntry | undefined): Promise; } @@ -90,90 +90,3 @@ class SnapshotTab implements Tab { return this._element; } } - -class SourceTab implements Tab { - label = 'Source'; - - readonly _element: Element$; - private _editor: monaco.editor.IStandaloneCodeEditor; - private _fileName: string | undefined; - private _decorations: string[] = []; - - constructor() { - this._element = dom``; - monaco.editor.setTheme('vs-light'); - this._editor = monaco.editor.create(this._element, { - value: '', - language: 'javascript', - readOnly: true - }); - window.addEventListener('resize', () => this.resize()); - } - - async setAction(actionEntry: ActionEntry | undefined) { - if (!actionEntry) { - this._editor.setValue(''); - return; - } - const { action } = actionEntry; - const frames = action.stack!.split('\n').slice(1); - const frame = frames.filter(frame => !frame.includes('playwright/lib/client/'))[0]; - if (!frame) { - this._editor.setValue(action.stack!); - return; - } - const match = frame.match(/at ([^:]+):(\d+):\d+/); - if (!match) { - this._editor.setValue(action.stack!); - return; - } - const fileName = match[1]; - if (this._fileName !== fileName) { - this._fileName = fileName; - const content = await (window as any).readFile(fileName); - this._editor.setValue(content); - } - - const lineNumber = parseInt(match[2],10); - this._decorations = this._editor.deltaDecorations(this._decorations, [ - { range: new monaco.Range(lineNumber, 1, lineNumber, 1), options: { - isWholeLine: true, - className: 'monaco-execution-line' - }}, - ]); - this._editor.revealLine(lineNumber, 1); - } - - content(): HTMLElement { - return this._element; - } - - resize() { - this._editor.layout(); - } -} - -class NetworkTab implements Tab { - label = 'Network'; - private _listView: ListView; - - constructor() { - this._listView = new ListView(this); - } - - render(resource: NetworkResourceTraceEvent, element: HTMLElement): HTMLElement { - if (element) - return element; - return dom`${resource.url}` - } - - async setAction(actionEntry: ActionEntry | undefined) { - this._listView.clear(); - if (actionEntry) - this._listView.appendAll(actionEntry.resources); - } - - content(): HTMLElement { - return this._listView.element; - } -} diff --git a/src/traceViewer/web/ui/sourceTab.ts b/src/traceViewer/web/ui/sourceTab.ts new file mode 100644 index 0000000..4f42583 --- /dev/null +++ b/src/traceViewer/web/ui/sourceTab.ts @@ -0,0 +1,82 @@ +/** + * 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 * as monaco from 'monaco-editor'; +import { ActionEntry } from "../../traceModel"; +import { dom, Element$ } from '../components/dom'; +import { Tab } from './propertiesTabbedPane'; + +export class SourceTab implements Tab { + label = 'Source'; + + readonly _element: Element$; + private _editor: monaco.editor.IStandaloneCodeEditor; + private _fileName: string | undefined; + private _decorations: string[] = []; + + constructor() { + this._element = dom``; + monaco.editor.setTheme('vs-light'); + this._editor = monaco.editor.create(this._element, { + value: '', + language: 'javascript', + readOnly: true + }); + window.addEventListener('resize', () => this.resize()); + } + + async setAction(actionEntry: ActionEntry | undefined) { + if (!actionEntry) { + this._editor.setValue(''); + return; + } + const { action } = actionEntry; + const frames = action.stack!.split('\n').slice(1); + const frame = frames.filter(frame => !frame.includes('playwright/lib/client/'))[0]; + if (!frame) { + this._editor.setValue(action.stack!); + return; + } + const match = frame.match(/at ([^:]+):(\d+):\d+/); + if (!match) { + this._editor.setValue(action.stack!); + return; + } + const fileName = match[1]; + if (this._fileName !== fileName) { + this._fileName = fileName; + const content = await (window as any).readFile(fileName); + this._editor.setValue(content); + } + + const lineNumber = parseInt(match[2],10); + this._decorations = this._editor.deltaDecorations(this._decorations, [ + { range: new monaco.Range(lineNumber, 1, lineNumber, 1), options: { + isWholeLine: true, + className: 'monaco-execution-line' + }}, + ]); + this._editor.revealLine(lineNumber, 1); + } + + content(): HTMLElement { + return this._element; + } + + resize() { + this._editor.layout(); + } +} diff --git a/src/traceViewer/web/ui/workbench.css b/src/traceViewer/web/ui/workbench.css index a3703eb..a33d9b6 100644 --- a/src/traceViewer/web/ui/workbench.css +++ b/src/traceViewer/web/ui/workbench.css @@ -31,6 +31,7 @@ .workbench tab-strip { margin-left: calc(-1*var(--sidebar-width)); padding-left: var(--sidebar-width); + box-shadow: var(--box-shadow); } .workbench .logo { @@ -49,4 +50,4 @@ tab-strip { .monaco-execution-line { background-color: #ff69b460; -} \ No newline at end of file +}