Skip to content

Commit dca8879

Browse files
EmbraceAnwhale
authored andcommitted
Ci/vitest coverage
* test: init create vitest * ci: add vitest coverage, junit reporter and improve yarn cache strategy Ci/vitest coverage (#3253) * ci: pin node 18.18.2, add inputs display and yarn cache-dependency-path * ci: debug test discovery + set vitest root/include to ensure tests are found in CI * test: move Vitest__Test__ to __tests__ so CI includes it * fix(test): set spinner false when no editorOperationRecord
1 parent e0cb682 commit dca8879

File tree

7 files changed

+1103
-7
lines changed

7 files changed

+1103
-7
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Essential tests
2+
3+
concurrency:
4+
group: ${{ github.workflow }}-${{ github.ref }}
5+
cancel-in-progress: true
6+
7+
on:
8+
pull_request:
9+
branches: [test]
10+
paths:
11+
- 'app/renderer/src/main/src/release/**'
12+
- '.github/workflows/**'
13+
14+
jobs:
15+
vitest:
16+
name: Vitest - renderer main
17+
runs-on: ubuntu-latest
18+
strategy:
19+
matrix:
20+
node-version: [18.x]
21+
steps:
22+
- name: Display incoming configuration parameters
23+
run: echo ${{ inputs.platform }} ${{ inputs.legacy }} ${{ inputs.version }} ${{ inputs.engine }} ${{ inputs.engineVersion }} ${{ inputs.devTool }}
24+
25+
- name: Checkout
26+
uses: actions/checkout@v4
27+
28+
- uses: actions/setup-node@v4
29+
with:
30+
node-version: 18.18.2
31+
cache: "yarn"
32+
cache-dependency-path: |
33+
yarn.lock
34+
app/renderer/src/main/yarn.lock
35+
app/renderer/engine-link-startup/yarn.lock
36+
37+
- name: Cache Yarn cache
38+
uses: actions/cache@v4
39+
with:
40+
path: ~/.cache/yarn
41+
key: ${{ runner.os }}-yarn-cache-${{ hashFiles('app/renderer/src/main/yarn.lock') }}
42+
restore-keys: |
43+
${{ runner.os }}-yarn-cache-
44+
45+
- name: Cache node_modules
46+
uses: actions/cache@v4
47+
with:
48+
path: app/renderer/src/main/node_modules
49+
key: ${{ runner.os }}-node-modules-${{ hashFiles('app/renderer/src/main/yarn.lock') }}
50+
restore-keys: |
51+
${{ runner.os }}-node-modules-
52+
53+
- name: Install dependencies (renderer main)
54+
working-directory: app/renderer/src/main
55+
run: yarn install --frozen-lockfile --prefer-offline --network-concurrency 1
56+
57+
- name: Verify installed packages (quick)
58+
working-directory: app/renderer/src/main
59+
run: |
60+
echo "Yarn cache dir: $(yarn cache dir)"
61+
ls -la node_modules | head -n 20 || true
62+
63+
- name: Debug - list candidate test files
64+
working-directory: app/renderer/src/main
65+
run: |
66+
echo "pwd: $(pwd)"
67+
echo "node: $(node -v) yarn: $(yarn -v)"
68+
echo "Find test/spec files (up to depth 6):"
69+
find . -maxdepth 6 -type f \( -name "*.test.*" -o -name "*.spec.*" \) -print || true
70+
echo "Show specific folder (if exists):"
71+
ls -la src/components/playground/Vitest__Test__ || true
72+
73+
- name: Run Vitest (renderer main)
74+
working-directory: app/renderer/src/main
75+
env:
76+
CI: true
77+
run: yarn test:vitest -- --run --reporter verbose

app/renderer/src/main/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
"build-test-memfit": "env-cmd -e memfit,devTool -f ./.env-cmdrc cross-env GENERATE_SOURCEMAP=false react-app-rewired build",
144144
"build-breachtrace": "env-cmd -e breachtrace -f ./.env-cmdrc cross-env GENERATE_SOURCEMAP=false react-app-rewired build",
145145
"test": "react-app-rewired test",
146+
"test:vitest": "vitest",
146147
"eject": "react-app-rewired eject",
147148
"analyzer": "env-cmd -e analyzer -f cross-env react-app-rewired build",
148149
"postinstall": "patch-package",
@@ -180,7 +181,10 @@
180181
"sass": "^1.54.8",
181182
"sass-loader": "^12.6.0",
182183
"source-map-loader": "^4.0.2",
183-
"webpack-bundle-analyzer": "^4.10.1"
184+
"webpack-bundle-analyzer": "^4.10.1",
185+
"vitest": "^0.34.6",
186+
"vite": "^4.4.9",
187+
"vite-tsconfig-paths": "^3.5.0"
184188
},
185189
"resolutions": {
186190
"//": "See https://github.com/facebook/create-react-app/issues/11773",
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React from "react"
2+
import {render, waitFor, screen} from "@testing-library/react"
3+
import {afterEach, beforeEach, describe, expect, it, vi} from "vitest"
4+
5+
vi.mock("@/components/yakitUI/YakitSpin/YakitSpin", () => {
6+
const React = require("react")
7+
return {
8+
YakitSpin: (props: any) => {
9+
const {spinning, children} = props
10+
return React.createElement(
11+
"div",
12+
{"data-spinning": spinning ? "true" : "false", "data-testid": "yakitspin"},
13+
children
14+
)
15+
}
16+
}
17+
})
18+
19+
const mockGetRemoteValue = vi.fn()
20+
vi.mock("@/utils/kv", () => ({
21+
getRemoteValue: (...args: any[]) => mockGetRemoteValue(...args)
22+
}))
23+
24+
vi.mock("ahooks", () => {
25+
const React = require("react")
26+
return {
27+
useSafeState: (init: any) => React.useState(init)
28+
}
29+
})
30+
31+
let Vitest__Test__: any
32+
beforeAll(async () => {
33+
const mod = await import("@/components/playground/Vitest__Test__")
34+
Vitest__Test__ = mod.Vitest__Test__
35+
})
36+
37+
beforeEach(() => {
38+
mockGetRemoteValue.mockReset()
39+
})
40+
41+
afterEach(() => {
42+
vi.restoreAllMocks()
43+
})
44+
45+
describe("Vitest__Test__ component - loading behavior", () => {
46+
it("sets spinning=false immediately when no editorOperationRecord is provided", async () => {
47+
render(React.createElement(Vitest__Test__))
48+
const spin = screen.getByTestId("yakitspin")
49+
expect(spin).toBeInTheDocument()
50+
expect(spin).toHaveAttribute("data-spinning", "false")
51+
})
52+
53+
it("shows", async () => {
54+
mockGetRemoteValue.mockImplementation(() => Promise.resolve(JSON.stringify({fontSize: 14})))
55+
56+
render(React.createElement(Vitest__Test__, {editorOperationRecord: "my-key"}))
57+
58+
const spin = screen.getByTestId("yakitspin")
59+
expect(spin).toBeInTheDocument()
60+
expect(spin).toHaveAttribute("data-spinning", "true")
61+
62+
await waitFor(() => {
63+
expect(spin).toHaveAttribute("data-spinning", "false")
64+
})
65+
})
66+
})
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import {OperationRecordRes} from "@/components/yakitUI/YakitEditor/YakitEditorType"
2+
import {YakitSpin} from "@/components/yakitUI/YakitSpin/YakitSpin"
3+
import {getRemoteValue} from "@/utils/kv"
4+
import {useSafeState} from "ahooks"
5+
import {FC, useEffect} from "react"
6+
7+
interface VitestTestProps {
8+
editorOperationRecord?: string
9+
}
10+
11+
const Vitest__Test__: FC<VitestTestProps> = (props) => {
12+
const {editorOperationRecord} = props
13+
const [typeLoading, setTypeLoading] = useSafeState<boolean>(true)
14+
const [fontSize, setFontSize] = useSafeState<undefined | number>(12)
15+
const [showLineBreaks, setShowLineBreaks] = useSafeState<boolean>(true)
16+
const [noWordwrap, setNoWordwrap] = useSafeState(false)
17+
18+
useEffect(() => {
19+
if (!editorOperationRecord) {
20+
setTypeLoading(false)
21+
return
22+
}
23+
setTypeLoading(true)
24+
getRemoteValue(editorOperationRecord)
25+
.then((data) => {
26+
try {
27+
setTypeLoading(false)
28+
if (!data) return
29+
let obj: OperationRecordRes = JSON.parse(data)
30+
if (obj?.fontSize) {
31+
setFontSize(obj?.fontSize)
32+
}
33+
if (typeof obj?.showBreak === "boolean") {
34+
setShowLineBreaks(obj?.showBreak)
35+
}
36+
if (typeof obj?.noWordWrap === "boolean") {
37+
setNoWordwrap(obj?.noWordWrap)
38+
}
39+
} catch (error) {
40+
setTypeLoading(false)
41+
fail(error + "")
42+
}
43+
})
44+
.finally(() => {
45+
setTypeLoading(false)
46+
})
47+
// eslint-disable-next-line react-hooks/exhaustive-deps
48+
}, [editorOperationRecord])
49+
50+
return (
51+
<YakitSpin spinning={typeLoading}>
52+
<div>Vitest__Test__</div>
53+
</YakitSpin>
54+
)
55+
}
56+
57+
export {Vitest__Test__}

app/renderer/src/main/src/pages/debugMonaco/DebugMonacoEditorPage.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import {info} from "@/utils/notification"
55
import {SelectOne} from "@/utils/inputUtil"
66
import {YakitEditor} from "@/components/yakitUI/YakitEditor/YakitEditor"
77
import {YakURLTree} from "@/pages/yakURLTree/YakURLTree"
8-
import {TrafficDemo} from "@/components/playground/TrafficDemo"
98
import {PcapXDemo} from "@/components/playground/PcapXDemo"
9+
import {Vitest__Test__} from "@/components/playground/Vitest__Test__"
1010
import {DemoItemSelectOne} from "@/demoComponents/itemSelect/ItemSelect"
1111
import {RiskTableDemo} from "@/components/playground/RiskTableDemo"
1212
import {ChaosMakerRulesDemo} from "@/components/playground/ChaosMakerRulesDemo"
@@ -18,7 +18,7 @@ import {JavaDecompilerOperator} from "@/components/playground/javadecompiler/Jav
1818
import {KnowledgeBaseDemo} from "@/components/playground/knowlegeBase/KnowledgeBaseDemo"
1919
import {RagManagerDemo} from "@/components/playground/ragManager/RagManagerDemo"
2020
import {ThirdPartyBinaryManager} from "@/components/playground/thirdPartyBinary/ThirdPartyBinaryManager"
21-
import { EntityRepositoryPage } from "@/components/playground/entityRepository/EntityRepositoryPage"
21+
import {EntityRepositoryPage} from "@/components/playground/entityRepository/EntityRepositoryPage"
2222
export interface DebugMonacoEditorPageProp {}
2323

2424
const TAG = "DEBUG_PLAYGROUND_DEFAULT_MODE"
@@ -77,6 +77,7 @@ a=1&b=2 Content-Length: a
7777
{value: "rag-manager", label: "RAG 向量存储管理"},
7878
{value: "third-party-binary", label: "第三方应用管理"},
7979
{value: "entity-repository", label: "实体仓库"},
80+
{value: "vitest__test__", label: "Vitest 测试组件"}
8081
]}
8182
formItemStyle={{margin: 0}}
8283
value={mode}
@@ -112,7 +113,9 @@ a=1&b=2 Content-Length: a
112113
return <ThirdPartyBinaryManager />
113114
case "entity-repository":
114115
return <EntityRepositoryPage />
115-
}
116+
case "vitest__test__":
117+
return <Vitest__Test__ />
118+
}
116119
return <div>NO PLUGIN DEMO</div>
117120
})()}
118121
</AutoCard>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {defineConfig} from "vitest/config"
2+
import path from "path"
3+
4+
export default defineConfig({
5+
resolve: {
6+
alias: {
7+
"@": path.resolve(__dirname, "src")
8+
}
9+
},
10+
// Set test root to `src` and explicitly include test file patterns to ensure files are found in CI
11+
test: {
12+
environment: "jsdom",
13+
globals: true,
14+
root: path.resolve(__dirname),
15+
include: ["src/**/*.test.{ts,tsx,js,jsx}", "src/**/*.spec.{ts,tsx,js,jsx}"],
16+
setupFiles: ["src/setupTests.ts"],
17+
// Add JUnit reporter (writes `reports/junit.xml`) and keep default reporter
18+
// Cast the tuple to `any` to avoid type mismatch on this Vitest version
19+
reporters: [["junit", {outputFile: "reports/junit.xml"}] as unknown as any, "default"],
20+
// Use a supported coverage provider for Node (v8 or istanbul)
21+
coverage: {
22+
provider: "v8",
23+
reporter: ["lcov", "text"],
24+
reportsDirectory: "coverage"
25+
}
26+
}
27+
})

0 commit comments

Comments
 (0)