Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
ref: ${{ github.event.workflow_run.head_sha || github.sha }}

- name: Setup pnpm
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/skill-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ jobs:
VITEPRESS_BASE: /datav-kit/
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: pnpm/action-setup@v6
with:
version: 11.6.0
Expand Down
1 change: 1 addition & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default defineConfig({
title: 'DataV Kit',
description: 'Framework-agnostic Web Components for data dashboard decoration.',
base,
head: [['link', { rel: 'icon', href: 'data:,' }]],
buildEnd: copySkillExamples,
cleanUrls: true,
vite: {
Expand Down
1 change: 1 addition & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { defineConfig } from '@playwright/test'

export default defineConfig({
testDir: './tests/examples',
forbidOnly: !!process.env.CI,
timeout: 90_000,
expect: { timeout: 15_000 },
workers: 1,
Expand Down
1 change: 1 addition & 0 deletions skills/datav-kit/assets/examples/business.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="data:," />
<meta
name="description"
content="明亮经营分析大屏:收入趋势、目标差距与渠道贡献。"
Expand Down
1 change: 1 addition & 0 deletions skills/datav-kit/assets/examples/city.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="data:," />
<meta
name="description"
content="上海滨江城市指挥大屏,OpenStreetMap 地理数据与区域事件联动。"
Expand Down
1 change: 1 addition & 0 deletions skills/datav-kit/assets/examples/energy.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="data:," />
<meta
name="description"
content="源网荷储能源调度大屏,平衡能流、负荷曲线与储能状态。"
Expand Down
1 change: 1 addition & 0 deletions skills/datav-kit/assets/examples/industrial.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="data:," />
<meta
name="description"
content="工业监控大屏:原创 Three.js 厂区、设备选取、视角控制和二维降级。"
Expand Down
5 changes: 4 additions & 1 deletion skills/datav-kit/assets/minimal-example.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="data:," />
<title>DataV Kit · Minimal Screen</title>
<script type="importmap">
{
Expand Down Expand Up @@ -89,9 +90,11 @@ <h1>生产运行总览</h1>
register()
await document.querySelector('dvk-fit-screen').updateComplete
document.querySelector('#screen').dataset.ready = 'true'
} catch {
} catch (error) {
document.querySelector('#error').textContent =
'依赖加载失败,请联网后重新打开。'
document.querySelector('#screen').dataset.ready = 'error'
console.error(error)
}
</script>
</body>
Expand Down
22 changes: 14 additions & 8 deletions tests/examples/screens.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const directory = path.resolve('skills/datav-kit/assets/examples')
const examples = (await readdir(directory)).filter(name => name.endsWith('.html'))
const base = process.env.VITEPRESS_BASE || '/'
const previewBase = `http://127.0.0.1:4173${base}examples/`
const chartLibrary = 'https://cdn.jsdelivr.net/npm/echarts@6.1.0/dist/echarts.esm.min.js'

async function openExample(page: Page, url: string) {
const errors: string[] = []
Expand All @@ -35,7 +34,8 @@ async function expectRegistered(page: Page) {
.map(element => element.localName))
expect(missing).toEqual([])
const invalid = await page.evaluate(async () => {
const { elementMetadata } = await import('https://cdn.jsdelivr.net/npm/@datav-kit/elements@0.0.5/+esm')
const imports = JSON.parse(document.querySelector('script[type="importmap"]')!.textContent!).imports
const { elementMetadata } = await import(imports['@datav-kit/elements'])
const result: string[] = []
for (const element of document.querySelectorAll('*')) {
if (!element.localName.startsWith('dvk-'))
Expand All @@ -56,8 +56,9 @@ async function expectRegistered(page: Page) {
}

async function expectCharts(page: Page) {
const chartResults = await page.evaluate(async (url) => {
const echarts = await import(/* @vite-ignore */ url)
const chartResults = await page.evaluate(async () => {
const imports = JSON.parse(document.querySelector('script[type="importmap"]')!.textContent!).imports
const echarts = await import(imports.echarts)
return [...document.querySelectorAll<HTMLElement>('[data-chart]')].map((element) => {
const chart = echarts.getInstanceByDom(element)
const options = chart.getOption()
Expand All @@ -68,7 +69,7 @@ async function expectCharts(page: Page) {
.some(attribute => roles.includes((mark.getAttribute(attribute) || '').toLowerCase())))
return { id: element.id, width: chart.getWidth(), height: chart.getHeight(), series: options.series.length, coloredMarks: marks.length }
})
}, chartLibrary)
})
for (const result of chartResults) {
expect(result.width, result.id).toBeGreaterThan(100)
expect(result.height, result.id).toBeGreaterThan(80)
Expand Down Expand Up @@ -173,10 +174,11 @@ for (const name of examples) {
await page.screenshot({ path: path.join(directory, 'previews', name.replace('.html', '.png')) })
}
}
const animation = await page.evaluate(async (url) => {
const echarts = await import(/* @vite-ignore */ url)
const animation = await page.evaluate(async () => {
const imports = JSON.parse(document.querySelector('script[type="importmap"]')!.textContent!).imports
const echarts = await import(imports.echarts)
return [...document.querySelectorAll('[data-chart]')].map(element => echarts.getInstanceByDom(element).getOption().animation)
}, chartLibrary)
})
expect(animation.every(value => value === false)).toBe(true)
if (name === 'industrial.html') {
await expect(page.locator('#screen')).toHaveAttribute('data-paused', 'true')
Expand Down Expand Up @@ -285,6 +287,10 @@ test('minimal starter registers and scales', async ({ page }) => {
await expect(page.locator('#screen')).toHaveAttribute('data-ready', 'true')
await expectRegistered(page)
await expectCanvasFits(page)
await page.route('https://cdn.jsdelivr.net/**', route => route.abort())
await page.reload()
await expect(page.locator('#screen')).toHaveAttribute('data-ready', 'error')
await expect(page.getByRole('status')).toContainText('依赖加载失败')
})

test('gallery serves screenshots and downloads the maintained HTML', async ({ page }) => {
Expand Down
9 changes: 4 additions & 5 deletions tests/examples/serve.mjs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { readFile } from 'node:fs/promises'
import http from 'node:http'
import path from 'node:path'
import process from 'node:process'

const root = path.resolve('docs/.vitepress/dist')
const base = (process.env.VITEPRESS_BASE || '/').replace(/\/$/, '')
const types = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript', '.css': 'text/css', '.png': 'image/png', '.svg': 'image/svg+xml' }
http.createServer(async (request, response) => {
const url = new URL(request.url, 'http://localhost')
const pathname = decodeURIComponent(url.pathname).replace(/^\/datav-kit(?=\/)/, '')
if (pathname === '/favicon.ico') {
response.writeHead(204).end()
return
}
const decoded = decodeURIComponent(url.pathname)
const pathname = base && decoded.startsWith(`${base}/`) ? decoded.slice(base.length) : decoded
const filename = pathname.endsWith('/') ? `${pathname}index.html` : path.extname(pathname) ? pathname : `${pathname}.html`
const file = path.resolve(root, `.${filename}`)
if (!file.startsWith(`${root}${path.sep}`)) {
Expand Down
Loading