Skip to content

Commit f396d43

Browse files
implement placeholder content
1 parent cc13efd commit f396d43

File tree

11 files changed

+173
-47
lines changed

11 files changed

+173
-47
lines changed

packages/app/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"type": "module",
66
"exports": "./src/index.ts",
77
"scripts": {
8-
"dev": "vite",
8+
"dev": "vite build --watch",
99
"build": "tsc && vite build",
1010
"preview": "vite preview",
1111
"test": "eslint ."
@@ -19,6 +19,7 @@
1919
"@wdio/protocols": "^8.23.0",
2020
"codemirror": "^6.0.1",
2121
"lit": "^2.7.6",
22+
"placeholder-loading": "^0.6.0",
2223
"pointer-tracker": "^2.5.3",
2324
"preact": "^10.18.1"
2425
},

packages/app/src/app.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { customElement, query, property } from 'lit/decorators.js'
44
import { type TraceLog } from '@wdio/devtools-service/types'
55

66
import { Element } from '@core/element'
7-
import { context } from './context.js'
7+
import { context, cacheTraceData } from './context.js'
88
import { DragController, Direction } from './utils/DragController.js'
99

1010
import './components/header.js'
@@ -13,21 +13,12 @@ import './components/workbench.js'
1313
import './components/onboarding/start.js'
1414

1515
const SIDEBAR_MIN_WIDTH = 200
16-
const CACHE_ID = 'wdio-trace-cache'
17-
18-
let cachedTraceFile: TraceLog | undefined
19-
try {
20-
const localStorageValue = localStorage.getItem(CACHE_ID)
21-
cachedTraceFile = localStorageValue ? JSON.parse(localStorageValue) : undefined
22-
} catch (e: unknown) {
23-
console.warn(`Failed to parse cached trace file: ${(e as Error).message}`)
24-
}
2516

2617
@customElement('wdio-devtools')
2718
export class WebdriverIODevtoolsApplication extends Element {
2819
@provide({ context })
2920
@property({ type: Object })
30-
data: TraceLog = cachedTraceFile!
21+
data: Partial<TraceLog> = {}
3122

3223
static styles = [...Element.styles, css`
3324
:host {
@@ -69,7 +60,7 @@ export class WebdriverIODevtoolsApplication extends Element {
6960

7061
#loadTrace ({ detail }: { detail: TraceLog }) {
7162
this.data = detail
72-
localStorage.setItem(CACHE_ID, JSON.stringify(detail))
63+
cacheTraceData(detail)
7364
this.requestUpdate()
7465
}
7566

packages/app/src/components/browser/snapshot.ts

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { customElement, query } from 'lit/decorators.js'
88
import { context, type TraceLog } from '../../context.js'
99

1010
import '~icons/mdi/world.js'
11+
import '../placeholder.js'
1112

1213
const MUTATION_SELECTOR = '__mutation-highlight__'
1314

@@ -38,7 +39,7 @@ export class DevtoolsBrowser extends Element {
3839
#activeUrl = ''
3940

4041
@consume({ context })
41-
data: TraceLog = {} as TraceLog
42+
data: Partial<TraceLog> = {}
4243

4344
static styles = [...Element.styles, css`
4445
:host {
@@ -84,16 +85,17 @@ export class DevtoolsBrowser extends Element {
8485
}
8586

8687
#setIframeSize () {
87-
if (!this.section || !this.iframe || !this.header) {
88+
const metadata = this.data.metadata
89+
if (!this.section || !this.iframe || !this.header || !metadata) {
8890
return
8991
}
9092

9193
this.section.style.width = 'auto'
9294
this.section.style.height = 'auto'
9395

9496
this.iframe.removeAttribute('style')
95-
const viewportWidth = this.data.metadata.viewport.width
96-
const viewportHeight = this.data.metadata.viewport.height
97+
const viewportWidth = metadata.viewport.width
98+
const viewportHeight = metadata.viewport.height
9799
const frameSize = this.getBoundingClientRect()
98100
const headerSize = this.header.getBoundingClientRect()
99101

@@ -115,9 +117,9 @@ export class DevtoolsBrowser extends Element {
115117
this.iframe.style.transform = `scale(${scale})`
116118
}
117119

118-
async #renderNewDocument (doc: SimplifiedVNode) {
120+
async #renderNewDocument (doc: SimplifiedVNode, baseUrl: string) {
119121
const root = transform(doc)
120-
const baseTag = h('base', { href: this.data.metadata.url })
122+
const baseTag = h('base', { href: baseUrl })
121123
const head: VNode<{}> | undefined = (root.props.children as VNode[])
122124
.filter(Boolean)
123125
.find((node) => node!.type === 'head')
@@ -188,7 +190,8 @@ export class DevtoolsBrowser extends Element {
188190

189191
#handleChildListMutation (mutation: TraceMutation) {
190192
if (mutation.addedNodes.length === 1 && !mutation.target) {
191-
this.#renderNewDocument(mutation.addedNodes[0] as SimplifiedVNode)
193+
const baseUrl = this.data.metadata?.url || 'unknown'
194+
this.#renderNewDocument(mutation.addedNodes[0] as SimplifiedVNode, baseUrl)
192195
return this.#renderVdom()
193196
}
194197

@@ -251,11 +254,16 @@ export class DevtoolsBrowser extends Element {
251254
}
252255

253256
async #renderBrowserState (mutationEntry?: TraceMutation) {
257+
const mutations = this.data.mutations
258+
if (!mutations) {
259+
return
260+
}
261+
254262
const mutationIndex = mutationEntry
255-
? this.data.mutations.indexOf(mutationEntry)
263+
? mutations.indexOf(mutationEntry)
256264
: 0
257265
this.#vdom = document.createDocumentFragment()
258-
const rootIndex = this.data.mutations
266+
const rootIndex = mutations
259267
.map((m, i) => [
260268
// is document loaded
261269
m.addedNodes.length === 1 && Boolean(m.url),
@@ -266,16 +274,16 @@ export class DevtoolsBrowser extends Element {
266274
.map(([, i]) => i)
267275
.pop() || 0
268276

269-
this.#activeUrl = this.data.mutations[rootIndex].url || this.data.metadata.url
277+
this.#activeUrl = mutations[rootIndex].url || this.data.metadata?.url || 'unknown'
270278
for (let i = rootIndex; i <= mutationIndex; i++) {
271-
await this.#handleMutation(this.data.mutations[i]).catch(
279+
await this.#handleMutation(mutations[i]).catch(
272280
(err) => console.warn(`Failed to render mutation: ${err.message}`))
273281
}
274282

275283
/**
276284
* scroll changed element into view
277285
*/
278-
const mutation = this.data.mutations[mutationIndex]
286+
const mutation = mutations[mutationIndex]
279287
if (mutation.target) {
280288
const el = this.#queryElement(mutation.target)
281289
if (el) {
@@ -298,7 +306,10 @@ export class DevtoolsBrowser extends Element {
298306
${this.#activeUrl}
299307
</div>
300308
</header>
301-
<iframe class="origin-top-left"></iframe>
309+
${this.data.mutations
310+
? html`<iframe class="origin-top-left"></iframe>`
311+
: html`<wdio-devtools-placeholder style="height: 500px"></wdio-devtools-placeholder>`
312+
}
302313
</section>
303314
`
304315
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { Element } from '@core/element'
2+
import { html, unsafeCSS } from 'lit'
3+
import { customElement } from 'lit/decorators.js'
4+
5+
import placeholderLoadingCSS from 'placeholder-loading/dist/css/placeholder-loading.css?inline'
6+
7+
@customElement('wdio-devtools-placeholder')
8+
export class DevtoolsPlaceholder extends Element {
9+
static styles = [unsafeCSS(placeholderLoadingCSS), unsafeCSS(`
10+
:host {
11+
display: block;
12+
width: 100%;
13+
height: 100%;
14+
}
15+
16+
.ph-item {
17+
border: 0;
18+
height: 100%;
19+
}
20+
21+
.ph-item div {
22+
opacity: .6;
23+
}
24+
`)]
25+
26+
render() {
27+
return html`
28+
<div class="ph-item">
29+
<div class="ph-col-12">
30+
<div class="ph-row">
31+
<div class="ph-col-6 big"></div>
32+
<div class="ph-col-4 empty big"></div>
33+
<div class="ph-col-4"></div>
34+
<div class="ph-col-8 empty"></div>
35+
<div class="ph-col-6"></div>
36+
<div class="ph-col-6 empty"></div>
37+
<div class="ph-col-12"></div>
38+
</div>
39+
</div>
40+
</div>
41+
`
42+
}
43+
}
44+
45+
declare global {
46+
interface HTMLElementTagNameMap {
47+
'wdio-devtools-placeholder': DevtoolsPlaceholder
48+
}
49+
}

packages/app/src/components/workbench/actions.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import '~icons/mdi/alert.js'
1212
import '~icons/mdi/document.js'
1313
import '~icons/mdi/arrow-right.js'
1414

15+
import '../placeholder.js'
1516
import './actionItems/command.js'
1617
import './actionItems/mutation.js'
1718

@@ -30,21 +31,22 @@ export class DevtoolsActions extends Element {
3031
`]
3132

3233
@consume({ context })
33-
data: TraceLog = {} as TraceLog
34+
data: Partial<TraceLog> = {}
3435

3536
connectedCallback(): void {
3637
super.connectedCallback()
37-
this.#entries = [...this.data.mutations, ...this.data.commands]
38+
this.#entries = [...this.data.mutations || [], ...this.data.commands || []]
3839
.sort((a, b) => a.timestamp - b.timestamp)
3940
}
4041

4142
render() {
42-
if (!this.#entries.length) {
43-
return html`<section class="flex items-center justify-center text-sm w-full h-full">No events logged!</section>`
43+
const mutations = this.data.mutations || []
44+
if (!this.#entries.length || !mutations.length) {
45+
return html`<wdio-devtools-placeholder></wdio-devtools-placeholder>`
4446
}
4547

4648
return this.#entries.map((entry) => {
47-
const elapsedTime = entry.timestamp - this.data.mutations[0].timestamp
49+
const elapsedTime = entry.timestamp - mutations[0].timestamp
4850

4951
if ('command' in entry) {
5052
return html`

packages/app/src/components/workbench/console.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/// <reference types="../../../script" />
2+
13
import { Element } from '@core/element'
24
import { html, css } from 'lit'
35
import { customElement } from 'lit/decorators.js'
@@ -6,6 +8,7 @@ import { consume } from '@lit/context'
68
import { context, type TraceLog } from '../../context.js'
79

810
import '~icons/mdi/chevron-right.js'
11+
import '../placeholder.js'
912

1013
const BG: Record<ConsoleLogs['type'], string> = {
1114
'warn': 'editorOverviewRulerWarningForeground',
@@ -28,11 +31,11 @@ export class DevtoolsConsoleLogs extends Element {
2831
`]
2932

3033
@consume({ context })
31-
data: TraceLog = {} as TraceLog
34+
data: Partial<TraceLog> = {}
3235

3336
render() {
34-
if (this.data.consoleLogs.length === 0) {
35-
return html`<section class="flex items-center justify-center text-sm w-full h-full">No events logged!</section>`
37+
if (!this.data.consoleLogs || this.data.consoleLogs.length === 0) {
38+
return html`<wdio-devtools-placeholder></wdio-devtools-placeholder>`
3639
}
3740

3841
return html`

packages/app/src/components/workbench/metadata.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ import { consume } from '@lit/context'
66
import { context, type TraceLog } from '../../context.js'
77

88
import './list.js'
9+
import '../placeholder.js'
910
import '~icons/mdi/chevron-right.js'
1011

1112
const SOURCE_COMPONENT = 'wdio-devtools-metadata'
1213
@customElement(SOURCE_COMPONENT)
1314
export class DevtoolsMetadata extends Element {
1415
@consume({ context })
15-
data: TraceLog = {} as TraceLog
16+
data: Partial<TraceLog> = {}
1617

1718
static styles = [...Element.styles, css`
1819
:host {
@@ -25,6 +26,10 @@ export class DevtoolsMetadata extends Element {
2526
`]
2627

2728
render() {
29+
if (!this.data.metadata) {
30+
return html`<wdio-devtools-placeholder style="height: 500px"></wdio-devtools-placeholder>`
31+
}
32+
2833
const { url } = this.data.metadata
2934
return html`
3035
<wdio-devtools-list

packages/app/src/components/workbench/source.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { oneDark } from '@codemirror/theme-one-dark'
1010

1111
import { context, type TraceLog } from '../../context.js'
1212

13+
import '../placeholder.js'
14+
1315
const SOURCE_COMPONENT = 'wdio-devtools-source'
1416
@customElement(SOURCE_COMPONENT)
1517
export class DevtoolsSource extends Element {
@@ -30,15 +32,19 @@ export class DevtoolsSource extends Element {
3032
`]
3133

3234
@consume({ context })
33-
data: TraceLog = {} as TraceLog
35+
data: Partial<TraceLog> = {}
3436

3537
connectedCallback(): void {
3638
super.connectedCallback()
3739
window.addEventListener('app-source-highlight', this.#highlightCallSource.bind(this))
38-
setTimeout(() => this.#renderEditor(Object.keys(this.data.sources)[0]))
40+
setTimeout(() => this.#renderEditor(Object.keys(this.data.sources || {})[0]))
3941
}
4042

4143
#renderEditor (filePath: string, highlightLine?: number) {
44+
if (!this.data.sources) {
45+
return
46+
}
47+
4248
const source = this.data.sources[filePath]
4349
if (!source) {
4450
return
@@ -75,7 +81,9 @@ export class DevtoolsSource extends Element {
7581
}
7682

7783
render() {
78-
return html`<section class="p-2">loading...</section>`
84+
return html`
85+
<wdio-devtools-placeholder></wdio-devtools-placeholder>
86+
`
7987
}
8088
}
8189

0 commit comments

Comments
 (0)