Skip to content

Commit ad09f4e

Browse files
committed
Unit test case for service package
1 parent 689abe9 commit ad09f4e

File tree

10 files changed

+1447
-58
lines changed

10 files changed

+1447
-58
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ jobs:
3232
run_install: false
3333
- name: Install dependencies
3434
run: pnpm install
35+
- name: Lint
36+
run: pnpm lint
3537
- name: 📦 Bundle
3638
run: pnpm -r --workspace-concurrency=1 build
3739
- name: 🧪 Run Tests

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66
"demo": "wdio run ./example/wdio.conf.ts",
77
"dev": "pnpm --parallel dev",
88
"preview": "pnpm --parallel preview",
9-
"test": "pnpm --parallel test",
9+
"test": "vitest run",
10+
"test:watch": "vitest",
11+
"test:coverage": "vitest run --coverage",
12+
"test:ui": "vitest --ui",
13+
"test:debug": "node --inspect-brk ./node_modules/.bin/vitest run",
14+
"lint": "pnpm --parallel lint",
1015
"watch": "pnpm build --watch"
1116
},
1217
"pnpm": {
@@ -26,6 +31,7 @@
2631
"eslint-plugin-import": "^2.32.0",
2732
"eslint-plugin-prettier": "^5.5.4",
2833
"eslint-plugin-unicorn": "^62.0.0",
34+
"happy-dom": "^20.0.11",
2935
"npm-run-all": "^4.1.5",
3036
"postcss": "^8.5.6",
3137
"postcss-lit": "^1.2.0",

packages/app/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"dev": "vite build --watch",
1414
"build": "tsc && vite build",
1515
"preview": "vite preview",
16-
"test": "eslint ."
16+
"lint": "eslint ."
1717
},
1818
"dependencies": {
1919
"@codemirror/lang-javascript": "^6.2.4",
@@ -32,15 +32,18 @@
3232
"author": "Christian Bromann <mail@bromann.dev>",
3333
"license": "MIT",
3434
"devDependencies": {
35+
"@open-wc/testing": "^4.0.0",
3536
"@tailwindcss/postcss": "^4.1.18",
3637
"@wdio/reporter": "9.18.0",
3738
"autoprefixer": "^10.4.21",
39+
"happy-dom": "^16.8.0",
3840
"postcss": "^8.5.6",
3941
"postcss-import": "^16.1.1",
4042
"rollup": "^4.47.0",
4143
"stylelint": "^16.24.0",
4244
"stylelint-config-recommended": "^17.0.0",
4345
"stylelint-config-tailwindcss": "^1.0.0",
44-
"tailwindcss": "~4.1.18"
46+
"tailwindcss": "~4.1.18",
47+
"vitest": "^4.0.16"
4548
}
4649
}

packages/backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"dev:ts": "tsc --watch",
2121
"dev:app": "nodemon --watch ./dist ./dist/index.js",
2222
"build": "tsc -p ./tsconfig.json",
23-
"test": "eslint ."
23+
"lint": "eslint ."
2424
},
2525
"dependencies": {
2626
"@fastify/static": "^9.0.0",

packages/script/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"dev": "vite",
1717
"build": "tsc && vite build",
1818
"preview": "vite preview",
19-
"test": "eslint ."
19+
"lint": "eslint ."
2020
},
2121
"dependencies": {
2222
"htm": "^3.1.1",

packages/script/tests/preload.test.ts

Lines changed: 0 additions & 47 deletions
This file was deleted.

packages/service/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"scripts": {
3232
"dev": "vite build --watch",
3333
"build": "tsc && vite build",
34-
"test": "eslint ."
34+
"lint": "eslint ."
3535
},
3636
"dependencies": {
3737
"@babel/types": "^7.28.4",
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { describe, it, expect, vi, beforeEach } from 'vitest'
2+
import DevToolsHookService from '../src/index.js'
3+
4+
const fakeFrame = {
5+
getFileName: () => '/test/specs/fake.spec.ts',
6+
getLineNumber: () => 1,
7+
getColumnNumber: () => 1
8+
}
9+
// Create mock instance that will be returned by SessionCapturer constructor
10+
vi.mock('stack-trace', () => ({
11+
parse: () => [fakeFrame]
12+
}))
13+
const mockSessionCapturerInstance = {
14+
afterCommand: vi.fn(),
15+
sendUpstream: vi.fn(),
16+
injectScript: vi.fn().mockResolvedValue(undefined),
17+
commandsLog: [],
18+
sources: new Map(),
19+
mutations: [],
20+
traceLogs: [],
21+
consoleLogs: [],
22+
isReportingUpstream: false
23+
}
24+
25+
vi.mock('../src/session.js', () => ({
26+
SessionCapturer: vi.fn(function (this: any) {
27+
return mockSessionCapturerInstance
28+
})
29+
}))
30+
31+
describe('DevtoolsService - Internal Command Filtering', () => {
32+
let service: DevToolsHookService
33+
const mockBrowser = {
34+
isBidi: true,
35+
sessionId: 'test-session',
36+
scriptAddPreloadScript: vi.fn().mockResolvedValue(undefined),
37+
takeScreenshot: vi.fn().mockResolvedValue('screenshot'),
38+
execute: vi.fn().mockResolvedValue({
39+
width: 1200,
40+
height: 800,
41+
offsetLeft: 0,
42+
offsetTop: 0
43+
})
44+
} as any
45+
46+
// Helper to execute a command (before + after)
47+
const executeCommand = (
48+
cmd: string,
49+
args: any[] = [],
50+
result: any = undefined
51+
) => {
52+
service.beforeCommand(cmd as any, args)
53+
service.afterCommand(cmd as any, args, result)
54+
}
55+
56+
beforeEach(() => {
57+
vi.clearAllMocks()
58+
mockSessionCapturerInstance.afterCommand.mockClear()
59+
mockSessionCapturerInstance.sendUpstream.mockClear()
60+
service = new DevToolsHookService()
61+
})
62+
63+
describe('beforeCommand', () => {
64+
it('should not add internal commands to command stack', () => {
65+
const internalCommands = [
66+
'getTitle',
67+
'waitUntil',
68+
'getUrl',
69+
'execute',
70+
'findElement'
71+
]
72+
internalCommands.forEach((cmd) => service.beforeCommand(cmd as any, []))
73+
expect(true).toBe(true)
74+
})
75+
76+
it('should add user commands to command stack', () => {
77+
;['click', 'url', 'getText'].forEach((cmd, i) => {
78+
const args = [['.button', 'https://example.com', '.result'][i]]
79+
service.beforeCommand(cmd as any, args)
80+
})
81+
expect(true).toBe(true)
82+
})
83+
})
84+
85+
describe('afterCommand - internal command filtering', () => {
86+
beforeEach(async () => {
87+
await service.before({} as any, [], mockBrowser)
88+
vi.clearAllMocks()
89+
mockSessionCapturerInstance.afterCommand.mockClear()
90+
})
91+
92+
it('should filter mixed internal and user commands correctly', () => {
93+
// Execute mix of user and internal commands
94+
executeCommand('url', ['https://example.com'])
95+
executeCommand('getTitle', [], 'Page Title') // internal
96+
executeCommand('click', ['.button'])
97+
executeCommand('waitUntil', [expect.any(Function)], true) // internal
98+
executeCommand('getText', ['.result'], 'Success')
99+
100+
// Only user commands (url, click, getText) should be captured
101+
expect(mockSessionCapturerInstance.afterCommand).toHaveBeenCalledTimes(3)
102+
103+
const capturedCommands =
104+
mockSessionCapturerInstance.afterCommand.mock.calls.map(
105+
(call) => call[1]
106+
)
107+
expect(capturedCommands).toEqual(['url', 'click', 'getText'])
108+
expect(capturedCommands).not.toContain('getTitle')
109+
expect(capturedCommands).not.toContain('waitUntil')
110+
})
111+
})
112+
})

0 commit comments

Comments
 (0)